From 61c4fc4b919c197351b71d7865729d05ec96ad7b Mon Sep 17 00:00:00 2001 From: ManDude <7569514+ManDude@users.noreply.github.com> Date: Fri, 22 Sep 2023 15:50:16 +0100 Subject: [PATCH] [jak2] fully implement collide mesh renderer (#3010) Fixes #2983 --- decompiler/config/jak2/all-types.gc | 2 +- .../level_extractor/extract_collide_frags.cpp | 30 ++- game/graphics/gfx.cpp | 35 ++- game/graphics/gfx.h | 19 +- .../opengl_renderer/CollideMeshRenderer.cpp | 114 +++++++-- .../opengl_renderer/CollideMeshRenderer.h | 9 +- .../opengl_renderer/OpenGLRenderer.cpp | 5 +- .../opengl_renderer/VisDataHandler.cpp | 14 ++ .../opengl_renderer/loader/Loader.cpp | 23 +- game/graphics/opengl_renderer/loader/Loader.h | 2 + .../opengl_renderer/shaders/collision.vert | 44 ++-- game/graphics/pipelines/opengl.cpp | 5 + game/kernel/common/kmachine.cpp | 4 +- game/kernel/jak2/kmachine.cpp | 17 ++ goal_src/jak1/engine/math/vector-h.gc | 8 +- goal_src/jak1/kernel-defs.gc | 3 +- goal_src/jak1/pc/debug/default-menu-pc.gc | 16 +- goal_src/jak1/pc/pckernel-common.gc | 21 -- goal_src/jak1/pc/pckernel-h.gc | 5 + goal_src/jak1/pc/pckernel-impl.gc | 11 + goal_src/jak2/engine/collide/collide-shape.gc | 2 +- goal_src/jak2/engine/collide/pat-h.gc | 2 +- .../jak2/engine/gfx/background/background.gc | 238 +++++++++++------- goal_src/jak2/engine/level/level.gc | 15 +- goal_src/jak2/engine/math/vector-h.gc | 8 +- goal_src/jak2/kernel-defs.gc | 4 +- goal_src/jak2/pc/debug/default-menu-pc.gc | 14 ++ goal_src/jak2/pc/pckernel-impl.gc | 20 ++ goalc/compiler/Compiler.cpp | 3 +- .../jak2/engine/collide/collide-shape_REF.gc | 2 +- .../jak2/engine/collide/pat-h_REF.gc | 6 +- 31 files changed, 501 insertions(+), 200 deletions(-) diff --git a/decompiler/config/jak2/all-types.gc b/decompiler/config/jak2/all-types.gc index 4a2e33b455f..a3835a714f7 100644 --- a/decompiler/config/jak2/all-types.gc +++ b/decompiler/config/jak2/all-types.gc @@ -14939,7 +14939,7 @@ (deadly 1) (endlessfall 2) (burn 3) - (deadlup 4) + (deadlyup 4) (burnup 5) (melt 6) (slide 7) diff --git a/decompiler/level_extractor/extract_collide_frags.cpp b/decompiler/level_extractor/extract_collide_frags.cpp index 8e854243b92..a195364c702 100644 --- a/decompiler/level_extractor/extract_collide_frags.cpp +++ b/decompiler/level_extractor/extract_collide_frags.cpp @@ -325,24 +325,34 @@ void handle_collide_fragment(const TypedRef& collide_fragment, 4 * (max_pat + 1)); for (const auto& p : polys) { + math::Vector4f verts_in[3]; for (int vi = 0; vi < 3; vi++) { int v = p.vert_index[vi]; - auto& vert_out = out->emplace_back(); - vert_out.flags = 0; - math::Vector4f pt(u32(verts.at(v * 3)) * 16 + bbox_min.data[0], - u32(verts.at(v * 3 + 1)) * 16 + bbox_min.data[1], - u32(verts.at(v * 3 + 2)) * 16 + bbox_min.data[2], 1.f); + verts_in[vi] = {u32(verts.at(v * 3)) * 16 + bbox_min.data[0], + u32(verts.at(v * 3 + 1)) * 16 + bbox_min.data[1], + u32(verts.at(v * 3 + 2)) * 16 + bbox_min.data[2], 1.f}; if (matrix) { - pt = transform_tie(*matrix, pt); + verts_in[vi] = transform_tie(*matrix, verts_in[vi]); } - vert_out.x = pt.x(); - vert_out.y = pt.y(); - vert_out.z = pt.z(); + } + + math::Vector3f v10 = verts_in[1].xyz() - verts_in[0].xyz(); + math::Vector3f v20 = verts_in[2].xyz() - verts_in[0].xyz(); + auto normal = (v10.cross(v20).normalized() * INT16_MAX).cast(); + for (int i = 0; i < 3; i++) { + auto& vert_out = out->emplace_back(); + vert_out.x = verts_in[i].x(); + vert_out.y = verts_in[i].y(); + vert_out.z = verts_in[i].z(); + vert_out.nx = normal.x(); + vert_out.ny = normal.y(); + vert_out.nz = normal.z(); + vert_out.flags = 0; // todo vert_out.pad = 0; vert_out.pad2 = 0; vert_out.pat = pats.at(p.pat); } - }; + } } void extract_collide_frags(const level_tools::CollideHash& chash, diff --git a/game/graphics/gfx.cpp b/game/graphics/gfx.cpp index 7f53d89fd0f..78259aa42f1 100644 --- a/game/graphics/gfx.cpp +++ b/game/graphics/gfx.cpp @@ -130,7 +130,7 @@ u32 sync_path() { return 0; } -bool CollisionRendererGetMask(GfxGlobalSettings::CollisionRendererMode mode, int mask_id) { +bool CollisionRendererGetMask(GfxGlobalSettings::CollisionRendererMode mode, s64 mask_id) { int arr_idx = mask_id / 32; int arr_ofs = mask_id % 32; @@ -142,15 +142,20 @@ bool CollisionRendererGetMask(GfxGlobalSettings::CollisionRendererMode mode, int case GfxGlobalSettings::CollisionRendererMode::Material: return (g_global_settings.collision_material_mask[arr_idx] >> arr_ofs) & 1; case GfxGlobalSettings::CollisionRendererMode::Skip: - ASSERT(arr_idx == 0); - return (g_global_settings.collision_skip_mask >> arr_ofs) & 1; + if (mask_id == -1) { + return g_global_settings.collision_skip_nomask_allowed; + } else { + return g_global_settings.collision_skip_mask & mask_id; + } + case GfxGlobalSettings::CollisionRendererMode::SkipHide: + return g_global_settings.collision_skip_hide_mask & mask_id; default: lg::error("{} invalid params {} {}", __PRETTY_FUNCTION__, fmt::underlying(mode), mask_id); return false; } } -void CollisionRendererSetMask(GfxGlobalSettings::CollisionRendererMode mode, int mask_id) { +void CollisionRendererSetMask(GfxGlobalSettings::CollisionRendererMode mode, s64 mask_id) { int arr_idx = mask_id / 32; int arr_ofs = mask_id % 32; @@ -165,8 +170,14 @@ void CollisionRendererSetMask(GfxGlobalSettings::CollisionRendererMode mode, int g_global_settings.collision_material_mask[arr_idx] |= 1 << arr_ofs; break; case GfxGlobalSettings::CollisionRendererMode::Skip: - ASSERT(arr_idx == 0); - g_global_settings.collision_skip_mask |= 1 << arr_ofs; + if (mask_id == -1) { + g_global_settings.collision_skip_nomask_allowed = true; + } else { + g_global_settings.collision_skip_mask |= mask_id; + } + break; + case GfxGlobalSettings::CollisionRendererMode::SkipHide: + g_global_settings.collision_skip_hide_mask |= mask_id; break; default: lg::error("{} invalid params {} {}", __PRETTY_FUNCTION__, fmt::underlying(mode), mask_id); @@ -174,7 +185,7 @@ void CollisionRendererSetMask(GfxGlobalSettings::CollisionRendererMode mode, int } } -void CollisionRendererClearMask(GfxGlobalSettings::CollisionRendererMode mode, int mask_id) { +void CollisionRendererClearMask(GfxGlobalSettings::CollisionRendererMode mode, s64 mask_id) { int arr_idx = mask_id / 32; int arr_ofs = mask_id % 32; @@ -189,8 +200,14 @@ void CollisionRendererClearMask(GfxGlobalSettings::CollisionRendererMode mode, i g_global_settings.collision_material_mask[arr_idx] &= ~(1 << arr_ofs); break; case GfxGlobalSettings::CollisionRendererMode::Skip: - ASSERT(arr_idx == 0); - g_global_settings.collision_skip_mask &= ~(1 << arr_ofs); + if (mask_id == -1) { + g_global_settings.collision_skip_nomask_allowed = false; + } else { + g_global_settings.collision_skip_mask &= ~mask_id; + } + break; + case GfxGlobalSettings::CollisionRendererMode::SkipHide: + g_global_settings.collision_skip_hide_mask &= ~mask_id; break; default: lg::error("{} invalid params {} {}", __PRETTY_FUNCTION__, fmt::underlying(mode), mask_id); diff --git a/game/graphics/gfx.h b/game/graphics/gfx.h index efa106734b4..9ddce735b86 100644 --- a/game/graphics/gfx.h +++ b/game/graphics/gfx.h @@ -42,15 +42,16 @@ struct GfxRendererModule { std::function texture_upload_now; std::function texture_relocate; std::function&)> set_levels; + std::function&)> set_active_levels; std::function set_pmode_alp; GfxPipeline pipeline; const char* name; }; // runtime settings -static constexpr int PAT_MOD_COUNT = 3; -static constexpr int PAT_EVT_COUNT = 7; -static constexpr int PAT_MAT_COUNT = 23; +static constexpr int PAT_MOD_COUNT = 4; +static constexpr int PAT_EVT_COUNT = 15; +static constexpr int PAT_MAT_COUNT = 29; struct GfxGlobalSettings { bool debug = true; // graphics debugging @@ -93,11 +94,13 @@ struct GfxGlobalSettings { bool collision_wireframe = true; // matching enum in kernel-defs.gc !! - enum CollisionRendererMode { None, Mode, Event, Material, Skip } collision_mode = Mode; + enum CollisionRendererMode { None, Mode, Event, Material, Skip, SkipHide } collision_mode = Mode; std::array collision_mode_mask = {UINT32_MAX}; std::array collision_event_mask = {UINT32_MAX}; std::array collision_material_mask = {UINT32_MAX}; - u32 collision_skip_mask = UINT32_MAX; + u32 collision_skip_mask = 0; + u32 collision_skip_hide_mask = 0; + bool collision_skip_nomask_allowed = true; }; namespace Gfx { @@ -118,9 +121,9 @@ u32 sync_path(); // matching enum in kernel-defs.gc !! enum class RendererTreeType { NONE = 0, TFRAG3 = 1, TIE3 = 2, INVALID }; -bool CollisionRendererGetMask(GfxGlobalSettings::CollisionRendererMode mode, int mask_id); -void CollisionRendererSetMask(GfxGlobalSettings::CollisionRendererMode mode, int mask_id); -void CollisionRendererClearMask(GfxGlobalSettings::CollisionRendererMode mode, int mask_id); +bool CollisionRendererGetMask(GfxGlobalSettings::CollisionRendererMode mode, s64 mask_id); +void CollisionRendererSetMask(GfxGlobalSettings::CollisionRendererMode mode, s64 mask_id); +void CollisionRendererClearMask(GfxGlobalSettings::CollisionRendererMode mode, s64 mask_id); void CollisionRendererSetMode(GfxGlobalSettings::CollisionRendererMode mode); } // namespace Gfx diff --git a/game/graphics/opengl_renderer/CollideMeshRenderer.cpp b/game/graphics/opengl_renderer/CollideMeshRenderer.cpp index 84dd82cc598..0b5df425fc3 100644 --- a/game/graphics/opengl_renderer/CollideMeshRenderer.cpp +++ b/game/graphics/opengl_renderer/CollideMeshRenderer.cpp @@ -1,9 +1,11 @@ #include "CollideMeshRenderer.h" +#include + #include "game/graphics/gfx.h" #include "game/graphics/opengl_renderer/background/background_common.h" -float material_colors_jak1[23 * 3] = { +const static std::vector material_colors_jak1 = { 1.0f, 0.7f, 1.0f, // 0, stone 0.1f, 2.0f, 2.0f, // 1, ice 0.75f, 0.25f, 0.1f, // 2, quicksand @@ -29,7 +31,7 @@ float material_colors_jak1[23 * 3] = { 1.0f, 1.0f, 1.0f, // 22, neutral }; -float event_colors_jak1[7 * 3] = { +const static std::vector event_colors_jak1 = { 1.0f, 1.0f, 1.0f, // 0, none 0.2f, 1.0f, 1.0f, // 1, deadly 0.1f, 1.0f, 0.1f, // 2, endlessfall @@ -39,12 +41,69 @@ float event_colors_jak1[7 * 3] = { 1.0f, 0.1f, 0.1f, // 6, melt }; -float mode_colors_jak1[3 * 3] = { +const static std::vector mode_colors_jak1 = { 1.25f, 0.1f, 0.1f, // 0, ground 0.1f, 0.1f, 1.0f, // 1, wall 1.0f, 0.1f, 1.0f, // 2, obstacle }; +const static std::vector material_colors_jak2 = { + 1.0f, 0.1f, 1.0f, // 0, unknown + 0.1f, 2.0f, 2.0f, // 1, ice + 0.75f, 0.25f, 0.1f, // 2, quicksand + 0.1f, 0.25f, 0.75f, // 3, waterbottom + 0.5f, 0.15f, 0.1f, // 4, tar + 2.0f, 1.5f, 0.5f, // 5, sand + 1.5f, 0.75f, 0.1f, // 6, wood + 0.1f, 1.35f, 0.1f, // 7, grass + 1.7f, 1.3f, 0.1f, // 8, pcmetal + 1.8f, 1.8f, 1.8f, // 9, snow + 1.5f, 0.2f, 1.0f, // 10, deepsnow + 1.2f, 0.5f, 0.3f, // 11, hotcoals + 1.4f, 0.1f, 0.1f, // 12, lava + 0.8f, 0.3f, 0.1f, // 13, crwood + 1.0f, 0.4f, 1.0f, // 14, gravel + 1.5f, 0.5f, 0.15f, // 15, dirt + 0.7f, 0.7f, 1.0f, // 16, metal + 0.1f, 0.1f, 1.2f, // 17, straw + 0.75f, 1.75f, 0.75f, // 18, tube + 0.4f, 0.1f, 0.8f, // 19, swamp + 0.1f, 0.4f, 0.8f, // 20, stopproj + 1.9f, 0.1f, 1.9f, // 21, rotate + 1.0f, 1.0f, 1.0f, // 22, neutral + 1.0f, 0.7f, 1.0f, // 23, stone + 0.8f, 1.2f, 1.2f, // 24, crmetal + 0.7f, 0.0f, 0.0f, // 25, carpet + 0.1f, 0.9f, 0.1f, // 26, grmetal + 1.4f, 0.7f, 0.1f, // 27, shmetal + 0.5f, 0.5f, 0.0f, // 28, hdwood +}; + +const static std::vector event_colors_jak2 = { + 1.0f, 1.0f, 1.0f, // 0, none + 0.5f, 1.0f, 1.0f, // 1, deadly + 0.1f, 1.0f, 0.1f, // 2, endlessfall + 1.0f, 1.0f, 0.1f, // 3, burn + 0.1f, 0.1f, 1.0f, // 4, deadlyup + 1.0f, 0.1f, 0.5f, // 5, burnup + 1.0f, 0.1f, 0.1f, // 6, melt + 0.1f, 0.7f, 0.7f, // 7, slide + 1.0f, 0.2f, 1.0f, // 8, lip + 0.5f, 0.2f, 1.0f, // 9, lipramp + 0.1f, 0.5f, 1.0f, // 10, shock + 0.5f, 0.6f, 1.0f, // 11, shockup + 0.5f, 0.6f, 0.5f, // 12, hide + 0.5f, 1.0f, 0.5f, // 13, rail + 0.7f, 0.7f, 0.7f, // 14, slippery +}; + +const static std::vector mode_colors_jak2 = { + 1.25f, 0.1f, 0.1f, // 0, ground + 0.1f, 0.1f, 1.0f, // 1, wall + 1.0f, 0.1f, 1.0f, // 2, obstacle + 1.0f, 1.0f, 0.1f, // 3, halfpipe +}; + CollideMeshRenderer::CollideMeshRenderer(GameVersion version) { glGenVertexArrays(1, &m_vao); glGenBuffers(1, &m_ubo); @@ -62,37 +121,54 @@ CollideMeshRenderer::~CollideMeshRenderer() { } void CollideMeshRenderer::init_pat_colors(GameVersion version) { - for (int i = 0; i < 0x8; ++i) { + for (int i = 0; i < 4; ++i) { m_colors.pat_mode_colors[i].x() = -1.f; m_colors.pat_mode_colors[i].y() = -1.f; m_colors.pat_mode_colors[i].z() = -1.f; } - for (int i = 0; i < 0x40; ++i) { + for (int i = 0; i < 32; ++i) { m_colors.pat_material_colors[i].x() = -1.f; m_colors.pat_material_colors[i].y() = -1.f; m_colors.pat_material_colors[i].z() = -1.f; } - for (int i = 0; i < 0x40; ++i) { + for (int i = 0; i < 32; ++i) { m_colors.pat_event_colors[i].x() = -1.f; m_colors.pat_event_colors[i].y() = -1.f; m_colors.pat_event_colors[i].z() = -1.f; } + const std::vector* material_colors = nullptr; + const std::vector* event_colors = nullptr; + const std::vector* mode_colors = nullptr; + switch (version) { case GameVersion::Jak1: - for (int i = 0; i < 23 * 3; ++i) { - m_colors.pat_material_colors[i / 3].data()[i % 3] = material_colors_jak1[i]; - } - for (int i = 0; i < 7 * 3; ++i) { - m_colors.pat_event_colors[i / 3].data()[i % 3] = event_colors_jak1[i]; - } - for (int i = 0; i < 3 * 3; ++i) { - m_colors.pat_mode_colors[i / 3].data()[i % 3] = mode_colors_jak1[i]; - } + material_colors = &material_colors_jak1; + event_colors = &event_colors_jak1; + mode_colors = &mode_colors_jak1; break; case GameVersion::Jak2: + material_colors = &material_colors_jak2; + event_colors = &event_colors_jak2; + mode_colors = &mode_colors_jak2; break; } + + if (material_colors) { + for (size_t i = 0; i < material_colors->size(); ++i) { + m_colors.pat_material_colors[i / 3].data()[i % 3] = material_colors->at(i); + } + } + if (event_colors) { + for (size_t i = 0; i < event_colors->size(); ++i) { + m_colors.pat_event_colors[i / 3].data()[i % 3] = event_colors->at(i); + } + } + if (mode_colors) { + for (size_t i = 0; i < mode_colors->size(); ++i) { + m_colors.pat_mode_colors[i / 3].data()[i % 3] = mode_colors->at(i); + } + } } void CollideMeshRenderer::render(SharedRenderState* render_state, ScopedProfilerNode& prof) { @@ -161,6 +237,8 @@ void CollideMeshRenderer::render(SharedRenderState* render_state, ScopedProfiler (void*)offsetof(tfrag3::CollisionMesh::Vertex, pat) // offset (0) ); glUniform1i(glGetUniformLocation(shader, "wireframe"), 0); + glUniform1i(glGetUniformLocation(shader, "wireframe_enabled"), + Gfx::g_global_settings.collision_wireframe); glUniform1uiv(glGetUniformLocation(shader, "collision_mode_mask"), Gfx::g_global_settings.collision_mode_mask.size(), Gfx::g_global_settings.collision_mode_mask.data()); @@ -172,6 +250,10 @@ void CollideMeshRenderer::render(SharedRenderState* render_state, ScopedProfiler Gfx::g_global_settings.collision_material_mask.data()); glUniform1ui(glGetUniformLocation(shader, "collision_skip_mask"), Gfx::g_global_settings.collision_skip_mask); + glUniform1ui(glGetUniformLocation(shader, "collision_skip_hide_mask"), + Gfx::g_global_settings.collision_skip_hide_mask); + glUniform1ui(glGetUniformLocation(shader, "collision_skip_nomask_allowed"), + Gfx::g_global_settings.collision_skip_nomask_allowed); glUniform1i(glGetUniformLocation(shader, "mode"), Gfx::g_global_settings.collision_mode); glDrawArrays(GL_TRIANGLES, 0, lev->level->collision.vertices.size()); @@ -188,5 +270,7 @@ void CollideMeshRenderer::render(SharedRenderState* render_state, ScopedProfiler prof.add_draw_call(); prof.add_tri(lev->level->collision.vertices.size() / 3); + + last_render_time = current_time; } } diff --git a/game/graphics/opengl_renderer/CollideMeshRenderer.h b/game/graphics/opengl_renderer/CollideMeshRenderer.h index b7c18ce9384..de01b3325d3 100644 --- a/game/graphics/opengl_renderer/CollideMeshRenderer.h +++ b/game/graphics/opengl_renderer/CollideMeshRenderer.h @@ -4,9 +4,9 @@ #include "game/graphics/opengl_renderer/BucketRenderer.h" struct PatColors { - math::Vector4f pat_mode_colors[0x8]; - math::Vector4f pat_material_colors[0x40]; - math::Vector4f pat_event_colors[0x40]; + math::Vector4f pat_mode_colors[4]; + math::Vector4f pat_material_colors[32]; + math::Vector4f pat_event_colors[32]; }; class CollideMeshRenderer { @@ -15,6 +15,9 @@ class CollideMeshRenderer { void render(SharedRenderState* render_state, ScopedProfilerNode& prof); ~CollideMeshRenderer(); + int current_time = 0; + int last_render_time = 0; + private: void init_pat_colors(GameVersion version); diff --git a/game/graphics/opengl_renderer/OpenGLRenderer.cpp b/game/graphics/opengl_renderer/OpenGLRenderer.cpp index 3a7cbcf97af..e58bca16e8a 100644 --- a/game/graphics/opengl_renderer/OpenGLRenderer.cpp +++ b/game/graphics/opengl_renderer/OpenGLRenderer.cpp @@ -1010,6 +1010,8 @@ void OpenGLRenderer::dispatch_buckets_jak2(DmaFollower dma, m_render_state.bucket_for_vis_copy = (int)jak2::BucketId::BUCKET_2; m_render_state.num_vis_to_copy = jak2::LEVEL_MAX; + ++m_collide_renderer.current_time; + for (size_t bucket_id = 0; bucket_id < m_bucket_renderers.size(); bucket_id++) { auto& renderer = m_bucket_renderers[bucket_id]; auto bucket_prof = prof.make_scoped_child(renderer->name_and_id()); @@ -1030,7 +1032,8 @@ void OpenGLRenderer::dispatch_buckets_jak2(DmaFollower dma, // hack to draw the collision mesh in the middle the drawing if (bucket_id + 1 == (int)jak2::BucketId::TEX_L0_ALPHA && - Gfx::g_global_settings.collision_enable) { + Gfx::g_global_settings.collision_enable && + m_collide_renderer.last_render_time != m_collide_renderer.current_time) { auto p = prof.make_scoped_child("collision-draw"); m_collide_renderer.render(&m_render_state, p); } diff --git a/game/graphics/opengl_renderer/VisDataHandler.cpp b/game/graphics/opengl_renderer/VisDataHandler.cpp index 87743f3b376..b7cf2eb9671 100644 --- a/game/graphics/opengl_renderer/VisDataHandler.cpp +++ b/game/graphics/opengl_renderer/VisDataHandler.cpp @@ -1,5 +1,7 @@ #include "VisDataHandler.h" +#include "background/background_common.h" + #include "third-party/imgui/imgui.h" VisDataHandler::VisDataHandler(const std::string& name, int my_id) : BucketRenderer(name, my_id) {} @@ -75,6 +77,18 @@ void VisDataHandler::render(DmaFollower& dma, ASSERT(next.size_bytes == 0); } + if (dma.current_tag_offset() != render_state->next_bucket) { + // we have some fallback data to use. + TfragPcPortData pc_port_data; + auto pc_port_data_dma = dma.read_and_advance(); + ASSERT(pc_port_data_dma.size_bytes == sizeof(TfragPcPortData)); + memcpy(&pc_port_data, pc_port_data_dma.data, sizeof(TfragPcPortData)); + update_render_state_from_pc_settings(render_state, pc_port_data); + + auto next = dma.read_and_advance(); + ASSERT(next.size_bytes == 0); + } + while (dma.current_tag_offset() != render_state->next_bucket) { dma.read_and_advance(); ASSERT(false); diff --git a/game/graphics/opengl_renderer/loader/Loader.cpp b/game/graphics/opengl_renderer/loader/Loader.cpp index d4563901962..63fa71eb4b5 100644 --- a/game/graphics/opengl_renderer/loader/Loader.cpp +++ b/game/graphics/opengl_renderer/loader/Loader.cpp @@ -83,6 +83,15 @@ void Loader::set_want_levels(const std::vector& levels) { } } +/*! + * The game calls this to tell the loader that we absolutely want these levels active. + * This will NOT trigger a load! + */ +void Loader::set_active_levels(const std::vector& levels) { + std::unique_lock lk(m_loader_mutex); + m_active_levels = levels; +} + /*! * Get all levels that are in memory and used very recently. */ @@ -90,9 +99,9 @@ std::vector Loader::get_in_use_levels() { std::vector result; std::unique_lock lk(m_loader_mutex); - for (auto& lev : m_loaded_tfrag3_levels) { - if (lev.second->frames_since_last_used < 5) { - result.push_back(lev.second.get()); + for (auto& [name, lev] : m_loaded_tfrag3_levels) { + if (lev->frames_since_last_used < 5) { + result.push_back(lev.get()); } } return result; @@ -376,8 +385,12 @@ void Loader::update(TexturePool& texture_pool) { Timer loader_timer; // only main thread can touch this. - for (auto& lev : m_loaded_tfrag3_levels) { - lev.second->frames_since_last_used++; + for (auto& [name, lev] : m_loaded_tfrag3_levels) { + if (std::find(m_active_levels.begin(), m_active_levels.end(), name) == m_active_levels.end()) { + lev->frames_since_last_used++; + } else { + lev->frames_since_last_used = 0; + } } bool did_gpu_stuff = false; diff --git a/game/graphics/opengl_renderer/loader/Loader.h b/game/graphics/opengl_renderer/loader/Loader.h index ba7f2022f0d..2cfa3e1a4d5 100644 --- a/game/graphics/opengl_renderer/loader/Loader.h +++ b/game/graphics/opengl_renderer/loader/Loader.h @@ -23,6 +23,7 @@ class Loader { std::optional get_merc_model(const char* model_name); const tfrag3::Level& load_common(TexturePool& tex_pool, const std::string& name); void set_want_levels(const std::vector& levels); + void set_active_levels(const std::vector& levels); std::vector get_in_use_levels(); void draw_debug_window(); @@ -52,6 +53,7 @@ class Loader { std::unordered_map> m_all_merc_models; std::vector m_desired_levels; + std::vector m_active_levels; std::vector> m_loader_stages; fs::path m_base_path; diff --git a/game/graphics/opengl_renderer/shaders/collision.vert b/game/graphics/opengl_renderer/shaders/collision.vert index eaa28abdcec..a1a3251a2aa 100644 --- a/game/graphics/opengl_renderer/shaders/collision.vert +++ b/game/graphics/opengl_renderer/shaders/collision.vert @@ -12,18 +12,21 @@ uniform float fog_constant; uniform float fog_min; uniform float fog_max; uniform int wireframe; +uniform int wireframe_enabled; uniform int mode; uniform int version; out vec4 fragment_color; -const int PAT_MOD_COUNT = 3; -const int PAT_EVT_COUNT = 7; -const int PAT_MAT_COUNT = 23; +const int PAT_MOD_COUNT = 4; +const int PAT_EVT_COUNT = 15; +const int PAT_MAT_COUNT = 29; uniform uint collision_mode_mask[(PAT_MOD_COUNT + 31) / 32]; uniform uint collision_event_mask[(PAT_EVT_COUNT + 31) / 32]; uniform uint collision_material_mask[(PAT_MAT_COUNT + 31) / 32]; uniform uint collision_skip_mask; +uniform uint collision_skip_hide_mask; +uniform uint collision_skip_nomask_allowed; const int MODE_NONE = 0; const int MODE_MODE = 1; @@ -33,14 +36,15 @@ const int MODE_MATERIAL = 3; uint pat_get_mode(uint p) { return version == 2 ? (p >> 7) & 0x7u : (p >> 3) & 0x7u; } uint pat_get_material(uint p) { return version == 2 ? (p >> 10) & 0x3fu : (p >> 6) & 0x3fu; } uint pat_get_event(uint p) { return version == 2 ? (p >> 18) & 0x3fu : (p >> 14) & 0x3fu; } +uint pat_get_skip(uint p) { return version == 2 ? p & 0x1f03007fu : p & 0x3007u; } bool logtest(uint a, uint b) { return (a & b) != 0; } bool logtesta(uint a, uint b) { return (a & b) == b; } layout(std140) uniform PatColors { - vec4 pat_mode_colors[0x8]; - vec4 pat_material_colors[0x40]; - vec4 pat_event_colors[0x40]; + vec4 pat_mode_colors[4]; + vec4 pat_material_colors[32]; + vec4 pat_event_colors[32]; }; void main() { @@ -86,30 +90,36 @@ void main() { float cam_dot = abs(dot(to_cam_n, normal_in)); // base colors - fragment_color = vec4(0.5, 0.5, 0.5, 1); - fragment_color.xyz *= (pow(cam_dot, 2) * 0.5 + 0.5); + fragment_color = vec4(vec3(0.75), 1); + if (wireframe_enabled == 0) { + fragment_color.rgb *= (pow(cam_dot, 2) * 0.35 + 0.65); + } else { + fragment_color.rgb *= (pow(cam_dot, 2.5) * 0.25 + 0.75); + } // pat checks uint pMode = pat_get_mode(pat); uint pMat = pat_get_material(pat); uint pEvent = pat_get_event(pat); + uint pSkip = pat_get_skip(pat); if (logtest(collision_mode_mask[pMode/32], 1 << (pMode & 0x1fu)) && - logtest(collision_material_mask[pMat/32], 1 << (pMat & 0x1fu)) && - logtest(collision_event_mask[pEvent/32], 1 << (pEvent & 0x1fu)) && - logtesta(collision_skip_mask, pat)) { + logtest(collision_material_mask[pMat/32], 1 << (pMat & 0x1fu)) && + logtest(collision_event_mask[pEvent/32], 1 << (pEvent & 0x1fu)) && + !logtest(collision_skip_hide_mask, pSkip) && + ((pSkip == 0 && collision_skip_nomask_allowed == 1) || (pSkip != 0 && (collision_skip_mask == 0 || logtest(pSkip, collision_skip_mask))))) { // fancy colors if (mode == MODE_MODE) { - fragment_color.rgb *= pat_mode_colors[pMode].rgb; + fragment_color.rgb *= pat_mode_colors[pMode].rgb; } else if (mode == MODE_EVENT) { - fragment_color.rgb *= pat_event_colors[pEvent].rgb; + fragment_color.rgb *= pat_event_colors[pEvent].rgb; } else if (mode == MODE_MATERIAL) { - fragment_color.rgb *= pat_material_colors[pMat].rgb; + fragment_color.rgb *= pat_material_colors[pMat].rgb; } else { - fragment_color = vec4((normal_in + 1)*.5, 1); - fragment_color.rgb *= (pow(cam_dot, 2) * 0.5 + 0.5); + fragment_color = vec4((normal_in + 1)*.5, 1); + fragment_color.rgb *= (pow(cam_dot, 2) * 0.5 + 0.5); } if (fragment_color.r < 0 || fragment_color.g < 0 || fragment_color.b < 0) { - fragment_color.rgb = vec3(1, 0, 1); + fragment_color.rgb = vec3(1, 0, 1); } } else { // filtered out. goodbye! diff --git a/game/graphics/pipelines/opengl.cpp b/game/graphics/pipelines/opengl.cpp index 471a75e0ed7..cdf27701ae3 100644 --- a/game/graphics/pipelines/opengl.cpp +++ b/game/graphics/pipelines/opengl.cpp @@ -715,6 +715,10 @@ void gl_set_levels(const std::vector& levels) { g_gfx_data->loader->set_want_levels(levels); } +void gl_set_active_levels(const std::vector& levels) { + g_gfx_data->loader->set_active_levels(levels); +} + void gl_set_pmode_alp(float val) { g_gfx_data->pmode_alp = val; } @@ -729,6 +733,7 @@ const GfxRendererModule gRendererOpenGL = { gl_texture_upload_now, // texture_upload_now gl_texture_relocate, // texture_relocate gl_set_levels, // set_levels + gl_set_active_levels, // set_active_levels gl_set_pmode_alp, // set_pmode_alp GfxPipeline::OpenGL, // pipeline "OpenGL 4.3" // name diff --git a/game/kernel/common/kmachine.cpp b/game/kernel/common/kmachine.cpp index b567a74d6ad..65f4d4532fc 100644 --- a/game/kernel/common/kmachine.cpp +++ b/game/kernel/common/kmachine.cpp @@ -769,7 +769,7 @@ void pc_renderer_tree_set_lod(Gfx::RendererTreeType tree, int lod) { } } -void pc_set_collision_mask(GfxGlobalSettings::CollisionRendererMode mode, int mask, u32 symptr) { +void pc_set_collision_mask(GfxGlobalSettings::CollisionRendererMode mode, s64 mask, u32 symptr) { if (symbol_to_bool(symptr)) { Gfx::CollisionRendererSetMask(mode, mask); } else { @@ -777,7 +777,7 @@ void pc_set_collision_mask(GfxGlobalSettings::CollisionRendererMode mode, int ma } } -u32 pc_get_collision_mask(GfxGlobalSettings::CollisionRendererMode mode, int mask) { +u32 pc_get_collision_mask(GfxGlobalSettings::CollisionRendererMode mode, s64 mask) { return Gfx::CollisionRendererGetMask(mode, mask) ? s7.offset + true_symbol_offset(g_game_version) : s7.offset; } diff --git a/game/kernel/jak2/kmachine.cpp b/game/kernel/jak2/kmachine.cpp index 780923d8505..7bba5f91d9b 100644 --- a/game/kernel/jak2/kmachine.cpp +++ b/game/kernel/jak2/kmachine.cpp @@ -662,6 +662,22 @@ void pc_set_levels(u32 lev_list) { Gfx::GetCurrentRenderer()->set_levels(levels); } +void pc_set_active_levels(u32 lev_list) { + if (!Gfx::GetCurrentRenderer()) { + return; + } + std::vector levels; + for (int i = 0; i < LEVEL_MAX; i++) { + u32 lev = *Ptr(lev_list + i * 4); + std::string ls = Ptr(lev).c()->data(); + if (ls != "none" && ls != "#f" && ls != "") { + levels.push_back(ls); + } + } + + Gfx::GetCurrentRenderer()->set_active_levels(levels); +} + void init_autosplit_struct() { g_auto_splitter_block_jak2.pointer_to_symbol = (u64)g_ee_main_mem + (u64)intern_from_c("*autosplit-info-jak2*")->value(); @@ -761,6 +777,7 @@ void InitMachine_PCPort() { make_string_from_c); make_function_symbol_from_c("__pc-set-levels", (void*)pc_set_levels); + make_function_symbol_from_c("__pc-set-active-levels", (void*)pc_set_active_levels); make_function_symbol_from_c("__pc-get-tex-remap", (void*)lookup_jak2_texture_dest_offset); make_function_symbol_from_c("pc-init-autosplitter-struct", (void*)init_autosplit_struct); make_function_symbol_from_c("pc-encode-utf8-string", (void*)encode_utf8_string); diff --git a/goal_src/jak1/engine/math/vector-h.gc b/goal_src/jak1/engine/math/vector-h.gc index 4c67cdd5a00..7e7a7f8c803 100644 --- a/goal_src/jak1/engine/math/vector-h.gc +++ b/goal_src/jak1/engine/math/vector-h.gc @@ -400,14 +400,16 @@ :flag-assert #x900000010 ) -(defmacro static-vectorm (x y z w) - `(new 'static 'vector :x (meters ,x) :y (meters ,y) :z (meters ,z) :w (meters ,w)) +(defmacro static-vectorm (x y z) + "creates a static vector using meters. w is set to 1.0" + `(new 'static 'vector :x (meters ,x) :y (meters ,y) :z (meters ,z) :w 1.0) ) (defmacro static-spherem (x y z r) - "actually makes a vector. use bspherem for sphere." + "creates a static vector using meters where the w component is used as sphere radius. for a 'real' sphere use static-bspherem." `(new 'static 'vector :x (meters ,x) :y (meters ,y) :z (meters ,z) :w (meters ,r)) ) (defmacro static-bspherem (x y z r) + "creates a static sphere using meters." `(new 'static 'sphere :x (meters ,x) :y (meters ,y) :z (meters ,z) :w (meters ,r)) ) diff --git a/goal_src/jak1/kernel-defs.gc b/goal_src/jak1/kernel-defs.gc index 9691e600365..3ccab0f391f 100644 --- a/goal_src/jak1/kernel-defs.gc +++ b/goal_src/jak1/kernel-defs.gc @@ -317,7 +317,8 @@ (mode 1) (event 2) (material 3) - (skip 4)) + (skip 4) + (skiphide 5)) (defenum pc-gfx-hack (no-tex 0)) diff --git a/goal_src/jak1/pc/debug/default-menu-pc.gc b/goal_src/jak1/pc/debug/default-menu-pc.gc index c6ab192efc8..d2fb2d3dc72 100644 --- a/goal_src/jak1/pc/debug/default-menu-pc.gc +++ b/goal_src/jak1/pc/debug/default-menu-pc.gc @@ -370,6 +370,13 @@ (pc-get-collision-mask (pc-collision-mode skip) arg) ) +(defun dm-collision-filter-skiphide-pick-func ((arg int) (msg debug-menu-msg)) + (when (= msg (debug-menu-msg press)) + (pc-set-collision-mask (pc-collision-mode skiphide) arg (not (pc-get-collision-mask (pc-collision-mode skiphide) arg))) + ) + (pc-get-collision-mask (pc-collision-mode skiphide) arg) + ) + (defun debug-menu-make-collision-renderer-menu ((ctx debug-menu-context)) (let ((menu (new 'debug 'debug-menu ctx "Collision renderer menu"))) ;; master toggle @@ -400,11 +407,18 @@ ) filter-menu))) (debug-menu-append-item menu (new-dm-submenu "Filter skip" - (let ((filter-menu (new 'debug 'debug-menu ctx "Collision renderer filter skip menu"))) + (let ((filter-menu (new 'debug 'debug-menu ctx "Collision renderer hide skip menu"))) + (debug-menu-append-item filter-menu (new-dm-flag "(no skip)" -1 dm-collision-filter-skip-pick-func)) (doenum (name val pc-pat-skip-hack) (debug-menu-append-item filter-menu (new-dm-flag name val dm-collision-filter-skip-pick-func)) ) filter-menu))) + (debug-menu-append-item menu (new-dm-submenu "Hide skip" + (let ((filter-menu (new 'debug 'debug-menu ctx "Collision renderer hide skip menu"))) + (doenum (name val pc-pat-skip-hack) + (debug-menu-append-item filter-menu (new-dm-flag name val dm-collision-filter-skiphide-pick-func)) + ) + filter-menu))) (new-dm-submenu "Collision renderer" menu) ) diff --git a/goal_src/jak1/pc/pckernel-common.gc b/goal_src/jak1/pc/pckernel-common.gc index ce9576a74ca..3798eabb44e 100644 --- a/goal_src/jak1/pc/pckernel-common.gc +++ b/goal_src/jak1/pc/pckernel-common.gc @@ -29,27 +29,6 @@ "return the current pckernel version" PC_KERNEL_VERSION) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;; global variables -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - -;; collision renderer things. debug only. -(define *collision-renderer* #f) -(define *collision-wireframe* #f) -(define *collision-mode* (pc-collision-mode mode)) - -;; todo -(defenum pc-pat-skip-hack - :bitfield #t - (noentity 0) - (nocamera 1) - (noedge 2) - (nolineofsight 12) - (unknowncamera 13) - (unknown 15) - ) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; updates diff --git a/goal_src/jak1/pc/pckernel-h.gc b/goal_src/jak1/pc/pckernel-h.gc index 5c366b0fb73..e9e2c3b7023 100644 --- a/goal_src/jak1/pc/pckernel-h.gc +++ b/goal_src/jak1/pc/pckernel-h.gc @@ -277,6 +277,11 @@ (define *display-text-box* #f) (define *display-sha* *debug-segment*) +;; collision renderer things. debug only. +(define *collision-renderer* #f) +(define *collision-wireframe* #f) +(define *collision-mode* (pc-collision-mode mode)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; resets diff --git a/goal_src/jak1/pc/pckernel-impl.gc b/goal_src/jak1/pc/pckernel-impl.gc index 004aa809044..78030846157 100644 --- a/goal_src/jak1/pc/pckernel-impl.gc +++ b/goal_src/jak1/pc/pckernel-impl.gc @@ -211,3 +211,14 @@ (defun get-video-params () *video-parms*) + +;; for debugging +(defenum pc-pat-skip-hack + :bitfield #t + (noentity 0) + (nocamera 1) + (noedge 2) + (nolineofsight 12) + (unknowncamera 13) + ) + diff --git a/goal_src/jak2/engine/collide/collide-shape.gc b/goal_src/jak2/engine/collide/collide-shape.gc index 48ad416d778..d117518852f 100644 --- a/goal_src/jak2/engine/collide/collide-shape.gc +++ b/goal_src/jak2/engine/collide/collide-shape.gc @@ -874,7 +874,7 @@ it returns a triangle and normal direction to push in. (static-attack-info ((id (the-as uint 2)) (mode 'burn) (shove-up (meters 3)))) ) ) - (((pat-event deadlup)) + (((pat-event deadlyup)) (set! set-flags (logior set-flags (cshape-reaction-flags csrf14))) (target-attack-up (the-as target (-> obj process)) 'attack-or-shove 'deadlyup) ) diff --git a/goal_src/jak2/engine/collide/pat-h.gc b/goal_src/jak2/engine/collide/pat-h.gc index ade458e4806..9b16d9e1c53 100644 --- a/goal_src/jak2/engine/collide/pat-h.gc +++ b/goal_src/jak2/engine/collide/pat-h.gc @@ -52,7 +52,7 @@ (deadly 1) (endlessfall 2) (burn 3) - (deadlup 4) + (deadlyup 4) (burnup 5) (melt 6) (slide 7) diff --git a/goal_src/jak2/engine/gfx/background/background.gc b/goal_src/jak2/engine/gfx/background/background.gc index b0069db3f28..4e6e50dd5e0 100644 --- a/goal_src/jak2/engine/gfx/background/background.gc +++ b/goal_src/jak2/engine/gfx/background/background.gc @@ -229,6 +229,141 @@ (none) ) + +(defun add-pc-tfrag3-data ((dma-buf dma-buffer) (lev level)) + "Add PC-port specific tfrag data" + (let ((packet (the-as dma-packet (-> dma-buf base)))) + (set! (-> packet dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc 24)) + (set! (-> packet vif0) (new 'static 'vif-tag)) + (set! (-> packet vif1) (new 'static 'vif-tag :cmd (vif-cmd pc-port))) + (set! (-> dma-buf base) (the pointer (&+ packet 16))) + ) + + ;; first 4 quadwords are planes, then itimes + (let ((data-ptr (the-as (pointer uint128) (-> dma-buf base)))) + ;; the "use-camera-other" flag is set to "move" entire levels, + ;; like the rotating city below in the throne room. + (cond + ((-> lev info use-camera-other) + (set! (-> data-ptr 0) (-> *math-camera* plane-other 0 quad)) + (set! (-> data-ptr 1) (-> *math-camera* plane-other 1 quad)) + (set! (-> data-ptr 2) (-> *math-camera* plane-other 2 quad)) + (set! (-> data-ptr 3) (-> *math-camera* plane-other 3 quad)) + (set! (-> data-ptr 4) (-> lev mood-context itimes 0 quad)) + (set! (-> data-ptr 5) (-> lev mood-context itimes 1 quad)) + (set! (-> data-ptr 6) (-> lev mood-context itimes 2 quad)) + (set! (-> data-ptr 7) (-> lev mood-context itimes 3 quad)) + (set! (-> data-ptr 8) (-> *math-camera* camera-temp-other vector 0 quad)) + (set! (-> data-ptr 9) (-> *math-camera* camera-temp-other vector 1 quad)) + (set! (-> data-ptr 10) (-> *math-camera* camera-temp-other vector 2 quad)) + (set! (-> data-ptr 11) (-> *math-camera* camera-temp-other vector 3 quad)) + (set! (-> data-ptr 12) (-> *math-camera* hvdf-off quad)) + (let ((vec (-> (the (inline-array vector) data-ptr) 13))) + (set! (-> vec x) (-> *math-camera* pfog0)) + (set! (-> vec y) (-> *math-camera* fog-min)) + (set! (-> vec z) (-> *math-camera* fog-max)) + ) + (set! (-> data-ptr 14) (-> *math-camera* trans-other quad)) + + (set! (-> data-ptr 15) (-> *math-camera* camera-rot-other vector 0 quad)) + (set! (-> data-ptr 16) (-> *math-camera* camera-rot-other vector 1 quad)) + (set! (-> data-ptr 17) (-> *math-camera* camera-rot-other vector 2 quad)) + (set! (-> data-ptr 18) (-> *math-camera* camera-rot-other vector 3 quad)) + + (set! (-> data-ptr 19) (-> *math-camera* perspective vector 0 quad)) + (set! (-> data-ptr 20) (-> *math-camera* perspective vector 1 quad)) + (set! (-> data-ptr 21) (-> *math-camera* perspective vector 2 quad)) + (set! (-> data-ptr 22) (-> *math-camera* perspective vector 3 quad)) + + ) + (else + (set! (-> data-ptr 0) (-> *math-camera* plane 0 quad)) + (set! (-> data-ptr 1) (-> *math-camera* plane 1 quad)) + (set! (-> data-ptr 2) (-> *math-camera* plane 2 quad)) + (set! (-> data-ptr 3) (-> *math-camera* plane 3 quad)) + (set! (-> data-ptr 4) (-> lev mood-context itimes 0 quad)) + (set! (-> data-ptr 5) (-> lev mood-context itimes 1 quad)) + (set! (-> data-ptr 6) (-> lev mood-context itimes 2 quad)) + (set! (-> data-ptr 7) (-> lev mood-context itimes 3 quad)) + (set! (-> data-ptr 8) (-> *math-camera* camera-temp vector 0 quad)) + (set! (-> data-ptr 9) (-> *math-camera* camera-temp vector 1 quad)) + (set! (-> data-ptr 10) (-> *math-camera* camera-temp vector 2 quad)) + (set! (-> data-ptr 11) (-> *math-camera* camera-temp vector 3 quad)) + (set! (-> data-ptr 12) (-> *math-camera* hvdf-off quad)) + (let ((vec (-> (the (inline-array vector) data-ptr) 13))) + (set! (-> vec x) (-> *math-camera* pfog0)) + (set! (-> vec y) (-> *math-camera* fog-min)) + (set! (-> vec z) (-> *math-camera* fog-max)) + ) + (set! (-> data-ptr 14) (-> *math-camera* trans quad)) + + (set! (-> data-ptr 15) (-> *math-camera* camera-rot vector 0 quad)) + (set! (-> data-ptr 16) (-> *math-camera* camera-rot vector 1 quad)) + (set! (-> data-ptr 17) (-> *math-camera* camera-rot vector 2 quad)) + (set! (-> data-ptr 18) (-> *math-camera* camera-rot vector 3 quad)) + + (set! (-> data-ptr 19) (-> *math-camera* perspective vector 0 quad)) + (set! (-> data-ptr 20) (-> *math-camera* perspective vector 1 quad)) + (set! (-> data-ptr 21) (-> *math-camera* perspective vector 2 quad)) + (set! (-> data-ptr 22) (-> *math-camera* perspective vector 3 quad)) + ) + ) + + (charp<-string (the (pointer uint8) (&-> data-ptr 23)) (symbol->string (-> lev nickname))) + ) + (&+! (-> dma-buf base) (* 16 24)) + ) + +(defun add-pc-camera-data ((dma-buf dma-buffer)) + "Add PC-port specific camera data. used as fallback for collide mesh renderer. + Same as add-pc-trag3-data but level-specific data is left undefined." + (let ((packet (the-as dma-packet (-> dma-buf base)))) + (set! (-> packet dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc 24)) + (set! (-> packet vif0) (new 'static 'vif-tag)) + (set! (-> packet vif1) (new 'static 'vif-tag :cmd (vif-cmd pc-port))) + (set! (-> dma-buf base) (the pointer (&+ packet 16))) + ) + + ;; first 4 quadwords are planes, then itimes + (let ((data-ptr (the-as (pointer uint128) (-> dma-buf base)))) + ;; the "use-camera-other" flag is set to "move" entire levels, + ;; like the rotating city below in the throne room. + (set! (-> data-ptr 0) (-> *math-camera* plane 0 quad)) + (set! (-> data-ptr 1) (-> *math-camera* plane 1 quad)) + (set! (-> data-ptr 2) (-> *math-camera* plane 2 quad)) + (set! (-> data-ptr 3) (-> *math-camera* plane 3 quad)) + ;; (set! (-> data-ptr 4) (-> lev mood-context itimes 0 quad)) + ;; (set! (-> data-ptr 5) (-> lev mood-context itimes 1 quad)) + ;; (set! (-> data-ptr 6) (-> lev mood-context itimes 2 quad)) + ;; (set! (-> data-ptr 7) (-> lev mood-context itimes 3 quad)) + (set! (-> data-ptr 8) (-> *math-camera* camera-temp vector 0 quad)) + (set! (-> data-ptr 9) (-> *math-camera* camera-temp vector 1 quad)) + (set! (-> data-ptr 10) (-> *math-camera* camera-temp vector 2 quad)) + (set! (-> data-ptr 11) (-> *math-camera* camera-temp vector 3 quad)) + (set! (-> data-ptr 12) (-> *math-camera* hvdf-off quad)) + (let ((vec (-> (the (inline-array vector) data-ptr) 13))) + (set! (-> vec x) (-> *math-camera* pfog0)) + (set! (-> vec y) (-> *math-camera* fog-min)) + (set! (-> vec z) (-> *math-camera* fog-max)) + ) + (set! (-> data-ptr 14) (-> *math-camera* trans quad)) + + (set! (-> data-ptr 15) (-> *math-camera* camera-rot vector 0 quad)) + (set! (-> data-ptr 16) (-> *math-camera* camera-rot vector 1 quad)) + (set! (-> data-ptr 17) (-> *math-camera* camera-rot vector 2 quad)) + (set! (-> data-ptr 18) (-> *math-camera* camera-rot vector 3 quad)) + + (set! (-> data-ptr 19) (-> *math-camera* perspective vector 0 quad)) + (set! (-> data-ptr 20) (-> *math-camera* perspective vector 1 quad)) + (set! (-> data-ptr 21) (-> *math-camera* perspective vector 2 quad)) + (set! (-> data-ptr 22) (-> *math-camera* perspective vector 3 quad)) + + (charp<-string (the (pointer uint8) (&-> data-ptr 23)) (symbol->string #f)) + ) + (&+! (-> dma-buf base) (* 16 24)) + ) + + (defun add-pc-port-background-data ((dma-buf dma-buffer)) "PC Port added" ;; loop over levels @@ -275,6 +410,24 @@ ) ) ) + (let* ((shrub-dma-buff (-> *display* frames (-> *display* on-screen) global-buf)) + (dma-start (-> shrub-dma-buff base))) + (add-pc-camera-data shrub-dma-buff) + (let ((a3-22 (-> shrub-dma-buff base))) + (let ((v1-57 (the-as object (-> shrub-dma-buff base)))) + (set! (-> (the-as dma-packet v1-57) dma) (new 'static 'dma-tag :id (dma-tag-id next))) + (set! (-> (the-as dma-packet v1-57) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet v1-57) vif1) (new 'static 'vif-tag)) + (set! (-> shrub-dma-buff base) (&+ (the-as pointer v1-57) 16)) + ) + (dma-bucket-insert-tag + (-> *display* frames (-> *display* on-screen) bucket-group) + (bucket-id bucket-2) + dma-start + (the-as (pointer dma-tag) a3-22) + ) + ) + ) (the-as pointer 0) ) @@ -602,88 +755,3 @@ 0 (none) ) - - -(defun add-pc-tfrag3-data ((dma-buf dma-buffer) (lev level)) - "Add PC-port specific tfrag data" - (let ((packet (the-as dma-packet (-> dma-buf base)))) - (set! (-> packet dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc 24)) - (set! (-> packet vif0) (new 'static 'vif-tag)) - (set! (-> packet vif1) (new 'static 'vif-tag :cmd (vif-cmd pc-port))) - (set! (-> dma-buf base) (the pointer (&+ packet 16))) - ) - - ;; first 4 quadwords are planes, then itimes - (let ((data-ptr (the-as (pointer uint128) (-> dma-buf base)))) - ;; the "use-camera-other" flag is set to "move" entire levels, - ;; like the rotating city below in the throne room. - (cond - ((-> lev info use-camera-other) - (set! (-> data-ptr 0) (-> *math-camera* plane-other 0 quad)) - (set! (-> data-ptr 1) (-> *math-camera* plane-other 1 quad)) - (set! (-> data-ptr 2) (-> *math-camera* plane-other 2 quad)) - (set! (-> data-ptr 3) (-> *math-camera* plane-other 3 quad)) - (set! (-> data-ptr 4) (-> lev mood-context itimes 0 quad)) - (set! (-> data-ptr 5) (-> lev mood-context itimes 1 quad)) - (set! (-> data-ptr 6) (-> lev mood-context itimes 2 quad)) - (set! (-> data-ptr 7) (-> lev mood-context itimes 3 quad)) - (set! (-> data-ptr 8) (-> *math-camera* camera-temp-other vector 0 quad)) - (set! (-> data-ptr 9) (-> *math-camera* camera-temp-other vector 1 quad)) - (set! (-> data-ptr 10) (-> *math-camera* camera-temp-other vector 2 quad)) - (set! (-> data-ptr 11) (-> *math-camera* camera-temp-other vector 3 quad)) - (set! (-> data-ptr 12) (-> *math-camera* hvdf-off quad)) - (let ((vec (-> (the (inline-array vector) data-ptr) 13))) - (set! (-> vec x) (-> *math-camera* pfog0)) - (set! (-> vec y) (-> *math-camera* fog-min)) - (set! (-> vec z) (-> *math-camera* fog-max)) - ) - (set! (-> data-ptr 14) (-> *math-camera* trans-other quad)) - - (set! (-> data-ptr 15) (-> *math-camera* camera-rot-other vector 0 quad)) - (set! (-> data-ptr 16) (-> *math-camera* camera-rot-other vector 1 quad)) - (set! (-> data-ptr 17) (-> *math-camera* camera-rot-other vector 2 quad)) - (set! (-> data-ptr 18) (-> *math-camera* camera-rot-other vector 3 quad)) - - (set! (-> data-ptr 19) (-> *math-camera* perspective vector 0 quad)) - (set! (-> data-ptr 20) (-> *math-camera* perspective vector 1 quad)) - (set! (-> data-ptr 21) (-> *math-camera* perspective vector 2 quad)) - (set! (-> data-ptr 22) (-> *math-camera* perspective vector 3 quad)) - - ) - (else - (set! (-> data-ptr 0) (-> *math-camera* plane 0 quad)) - (set! (-> data-ptr 1) (-> *math-camera* plane 1 quad)) - (set! (-> data-ptr 2) (-> *math-camera* plane 2 quad)) - (set! (-> data-ptr 3) (-> *math-camera* plane 3 quad)) - (set! (-> data-ptr 4) (-> lev mood-context itimes 0 quad)) - (set! (-> data-ptr 5) (-> lev mood-context itimes 1 quad)) - (set! (-> data-ptr 6) (-> lev mood-context itimes 2 quad)) - (set! (-> data-ptr 7) (-> lev mood-context itimes 3 quad)) - (set! (-> data-ptr 8) (-> *math-camera* camera-temp vector 0 quad)) - (set! (-> data-ptr 9) (-> *math-camera* camera-temp vector 1 quad)) - (set! (-> data-ptr 10) (-> *math-camera* camera-temp vector 2 quad)) - (set! (-> data-ptr 11) (-> *math-camera* camera-temp vector 3 quad)) - (set! (-> data-ptr 12) (-> *math-camera* hvdf-off quad)) - (let ((vec (-> (the (inline-array vector) data-ptr) 13))) - (set! (-> vec x) (-> *math-camera* pfog0)) - (set! (-> vec y) (-> *math-camera* fog-min)) - (set! (-> vec z) (-> *math-camera* fog-max)) - ) - (set! (-> data-ptr 14) (-> *math-camera* trans quad)) - - (set! (-> data-ptr 15) (-> *math-camera* camera-rot vector 0 quad)) - (set! (-> data-ptr 16) (-> *math-camera* camera-rot vector 1 quad)) - (set! (-> data-ptr 17) (-> *math-camera* camera-rot vector 2 quad)) - (set! (-> data-ptr 18) (-> *math-camera* camera-rot vector 3 quad)) - - (set! (-> data-ptr 19) (-> *math-camera* perspective vector 0 quad)) - (set! (-> data-ptr 20) (-> *math-camera* perspective vector 1 quad)) - (set! (-> data-ptr 21) (-> *math-camera* perspective vector 2 quad)) - (set! (-> data-ptr 22) (-> *math-camera* perspective vector 3 quad)) - ) - ) - - (charp<-string (the (pointer uint8) (&-> data-ptr 23)) (symbol->string (-> lev nickname))) - ) - (&+! (-> dma-buf base) (* 16 24)) - ) diff --git a/goal_src/jak2/engine/level/level.gc b/goal_src/jak2/engine/level/level.gc index f103ac2786e..7ee04daa687 100644 --- a/goal_src/jak2/engine/level/level.gc +++ b/goal_src/jak2/engine/level/level.gc @@ -2959,18 +2959,23 @@ into 7 sections, which might explain the weird sizes in the center. ) ;; og:preserve-this added - (let ((lev-names (new 'stack-no-clear 'array 'string LEVEL_MAX))) + (let ((lev-names (new 'stack-no-clear 'array 'string LEVEL_MAX)) + (active-lev-names (new 'stack-no-clear 'array 'string LEVEL_MAX))) (dotimes (i LEVEL_MAX) + (set! (-> active-lev-names i) "none") + (set! (-> lev-names i) "none") (cond - ((= (-> obj level i status) 'inactive) - (set! (-> lev-names i) "none") - ) - (else + ((or (= (-> obj level i status) 'active) + (= (-> obj level i status) 'alive) + (= (-> obj level i status) 'loaded)) (set! (-> lev-names i) (symbol->string (-> obj level i nickname))) + (if (-> obj level i display?) + (set! (-> active-lev-names i) (symbol->string (-> obj level i nickname)))) ) ) ) (__pc-set-levels lev-names) + (__pc-set-active-levels active-lev-names) ) 0 (none) diff --git a/goal_src/jak2/engine/math/vector-h.gc b/goal_src/jak2/engine/math/vector-h.gc index a0e51428d99..ac372d4e200 100644 --- a/goal_src/jak2/engine/math/vector-h.gc +++ b/goal_src/jak2/engine/math/vector-h.gc @@ -436,14 +436,16 @@ Changes: :flag-assert #x900000010 ) -(defmacro static-vectorm (x y z w) - `(new 'static 'vector :x (meters ,x) :y (meters ,y) :z (meters ,z) :w (meters ,w)) +(defmacro static-vectorm (x y z) + "creates a static vector using meters. w is set to 1.0" + `(new 'static 'vector :x (meters ,x) :y (meters ,y) :z (meters ,z) :w 1.0) ) (defmacro static-spherem (x y z r) - "actually makes a vector. use bspherem for sphere." + "creates a static vector using meters where the w component is used as sphere radius. for a 'real' sphere use static-bspherem." `(new 'static 'vector :x (meters ,x) :y (meters ,y) :z (meters ,z) :w (meters ,r)) ) (defmacro static-bspherem (x y z r) + "creates a static sphere using meters." `(new 'static 'sphere :x (meters ,x) :y (meters ,y) :z (meters ,z) :w (meters ,r)) ) diff --git a/goal_src/jak2/kernel-defs.gc b/goal_src/jak2/kernel-defs.gc index 2a7a9c629e4..25344745401 100644 --- a/goal_src/jak2/kernel-defs.gc +++ b/goal_src/jak2/kernel-defs.gc @@ -142,7 +142,8 @@ (mode 1) (event 2) (material 3) - (skip 4)) + (skip 4) + (skiphide 5)) (defenum pc-gfx-hack (no-tex 0)) @@ -155,6 +156,7 @@ (define-extern __pc-texture-relocate (function object object object none)) (define-extern __pc-get-mips2c (function string function)) (define-extern __pc-set-levels (function (pointer string) none)) +(define-extern __pc-set-active-levels (function (pointer string) none)) (define-extern __pc-get-tex-remap (function int int int)) ;; Input Related Functions diff --git a/goal_src/jak2/pc/debug/default-menu-pc.gc b/goal_src/jak2/pc/debug/default-menu-pc.gc index cad004cbac7..463e2ce0a9d 100644 --- a/goal_src/jak2/pc/debug/default-menu-pc.gc +++ b/goal_src/jak2/pc/debug/default-menu-pc.gc @@ -403,6 +403,13 @@ (pc-get-collision-mask (pc-collision-mode skip) arg) ) +(defun dm-collision-filter-skiphide-pick-func ((arg int) (msg debug-menu-msg)) + (when (= msg (debug-menu-msg press)) + (pc-set-collision-mask (pc-collision-mode skiphide) arg (not (pc-get-collision-mask (pc-collision-mode skiphide) arg))) + ) + (pc-get-collision-mask (pc-collision-mode skiphide) arg) + ) + (defun debug-menu-make-collision-renderer-menu ((ctx debug-menu-context)) (let ((menu (new 'debug 'debug-menu ctx "OpenGOAL collision renderer menu"))) ;; master toggle @@ -434,10 +441,17 @@ filter-menu))) (debug-menu-append-item menu (new-dm-submenu "Filter skip" (let ((filter-menu (new 'debug 'debug-menu ctx "OpenGOAL collision renderer filter skip menu"))) + (debug-menu-append-item filter-menu (new-dm-flag "(no skip)" -1 dm-collision-filter-skip-pick-func)) (doenum (name val pc-pat-skip-hack) (debug-menu-append-item filter-menu (new-dm-flag name val dm-collision-filter-skip-pick-func)) ) filter-menu))) + (debug-menu-append-item menu (new-dm-submenu "Hide skip" + (let ((filter-menu (new 'debug 'debug-menu ctx "OpenGOAL collision renderer hide skip menu"))) + (doenum (name val pc-pat-skip-hack) + (debug-menu-append-item filter-menu (new-dm-flag name val dm-collision-filter-skiphide-pick-func)) + ) + filter-menu))) (new-dm-submenu "OpenGOAL collision renderer" menu) ) diff --git a/goal_src/jak2/pc/pckernel-impl.gc b/goal_src/jak2/pc/pckernel-impl.gc index 6d45fb309f6..f0c97b11f82 100644 --- a/goal_src/jak2/pc/pckernel-impl.gc +++ b/goal_src/jak2/pc/pckernel-impl.gc @@ -165,6 +165,26 @@ (define *debug-region-show-bsphere* #f) +;; for debugging +(defenum pc-pat-skip-hack + :bitfield #t + (noentity 0) + (nocamera 1) + (noedge 2) + (nogrind 3) + (nojak 4) + (noboard 5) + (nopilot 6) + (nolineofsight 16) + (unknowncamera 17) + (probe 24) + (nomech 25) + (noproj 26) + (noendlessfall 27) + (noprobe 28) + ) + + (defun get-video-params () *video-params*) diff --git a/goalc/compiler/Compiler.cpp b/goalc/compiler/Compiler.cpp index 6078c3329b7..bb64b2512e0 100644 --- a/goalc/compiler/Compiler.cpp +++ b/goalc/compiler/Compiler.cpp @@ -393,7 +393,8 @@ void Compiler::setup_goos_forms() { std::vector> sorted_values; for (auto& val : enum_type->entries()) { - sorted_values.emplace_back(val.first, val.second); + sorted_values.emplace_back(val.first, + enum_type->is_bitfield() ? (u64)1 << val.second : val.second); } std::sort(sorted_values.begin(), sorted_values.end(), diff --git a/test/decompiler/reference/jak2/engine/collide/collide-shape_REF.gc b/test/decompiler/reference/jak2/engine/collide/collide-shape_REF.gc index 569654e9569..d4ac4f6afbf 100644 --- a/test/decompiler/reference/jak2/engine/collide/collide-shape_REF.gc +++ b/test/decompiler/reference/jak2/engine/collide/collide-shape_REF.gc @@ -828,7 +828,7 @@ (static-attack-info ((id (the-as uint 2)) (mode 'burn) (shove-up (meters 3)))) ) ) - (((pat-event deadlup)) + (((pat-event deadlyup)) (set! set-flags (logior set-flags (cshape-reaction-flags csrf14))) (target-attack-up (the-as target (-> obj process)) 'attack-or-shove 'deadlyup) ) diff --git a/test/decompiler/reference/jak2/engine/collide/pat-h_REF.gc b/test/decompiler/reference/jak2/engine/collide/pat-h_REF.gc index 5bd30290112..782e24ea71e 100644 --- a/test/decompiler/reference/jak2/engine/collide/pat-h_REF.gc +++ b/test/decompiler/reference/jak2/engine/collide/pat-h_REF.gc @@ -200,7 +200,7 @@ (((pat-event hide)) "hide" ) - (((pat-event deadlup)) + (((pat-event deadlyup)) "deadlyup" ) (((pat-event shockup)) @@ -288,7 +288,3 @@ ;; failed to figure out what this is: 0 - - - -