From 67b4afc5069619f91be928855de29076fb1599f7 Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Thu, 31 Mar 2022 19:29:48 -0400 Subject: [PATCH 001/172] Display the currently built commit sha when debugging the game (#1266) * generate a string constant with the currently built commit sha * draw the commit sha on the top left --- .gitignore | 5 ++++- game/CMakeLists.txt | 21 +++++++++++++++++++++ game/kernel/kmachine.cpp | 4 ++++ goal_src/engine/game/main.gc | 3 +++ goal_src/kernel-defs.gc | 1 + goal_src/pc/pckernel.gc | 13 +++++++++++-- 6 files changed, 44 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 536db679d9..dcf0cd6b67 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,7 @@ imgui.ini node_modules/ # texture replacements -texture_replacements/* \ No newline at end of file +texture_replacements/* + +# generated cmake files +svnrev.h diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index 3e5d0d0472..52487f5569 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -124,6 +124,27 @@ set(RUNTIME_SOURCE system/vm/dmac.cpp system/vm/vm.cpp) +find_package(Git) + +function(write_svnrev_h) + set(GIT_SHORT_SHA "") + if (GIT_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/.git) + EXECUTE_PROCESS(WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD + OUTPUT_VARIABLE GIT_SHORT_SHA + OUTPUT_STRIP_TRAILING_WHITESPACE) + else() + set(GIT_SHORT_SHA "unk. rev.") + endif() + if(NOT GIT_SHORT_SHA) + set(GIT_SHORT_SHA "unk. rev.") + else() + string(SUBSTRING ${GIT_SHORT_SHA} 0 6 GIT_SHORT_SHA) + endif() + + file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/kernel/svnrev.h "#define GIT_SHORT_SHA \"rev. ${GIT_SHORT_SHA}\"\n") +endfunction() + +write_svnrev_h() # we build the runtime as a static library. add_library(runtime STATIC ${RUNTIME_SOURCE} "../third-party/glad/src/glad.c") diff --git a/game/kernel/kmachine.cpp b/game/kernel/kmachine.cpp index 5d19c2dcd1..588384507c 100644 --- a/game/kernel/kmachine.cpp +++ b/game/kernel/kmachine.cpp @@ -40,6 +40,9 @@ #include "game/sce/libscf.h" #include "common/util/Assert.h" #include "game/discord.h" + +#include "svnrev.h" + using namespace ee; /*! @@ -884,6 +887,7 @@ void InitMachine_PCPort() { // TODO - we will eventually need a better way to know what game we are playing auto settings_path = file_util::get_user_settings_dir(); intern_from_c("*pc-settings-folder*")->value = make_string_from_c(settings_path.string().c_str()); + intern_from_c("*pc-settings-built-sha*")->value = make_string_from_c(GIT_SHORT_SHA); } void vif_interrupt_callback() { diff --git a/goal_src/engine/game/main.gc b/goal_src/engine/game/main.gc index b955de8788..4ea00c3876 100644 --- a/goal_src/engine/game/main.gc +++ b/goal_src/engine/game/main.gc @@ -665,6 +665,9 @@ (*draw-hook*) (add-ee-profile-frame 'draw :g #x80) + (#when PC_PORT + (draw-build-revision)) + (*menu-hook*) (add-ee-profile-frame 'draw :g #x40) diff --git a/goal_src/kernel-defs.gc b/goal_src/kernel-defs.gc index 4ce936e1fd..d3d445f536 100644 --- a/goal_src/kernel-defs.gc +++ b/goal_src/kernel-defs.gc @@ -341,6 +341,7 @@ ;; Constants generated within the C++ runtime (define-extern *pc-user-dir-base-path* string) (define-extern *pc-settings-folder* string) +(define-extern *pc-settings-built-sha* string) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; vm functions diff --git a/goal_src/pc/pckernel.gc b/goal_src/pc/pckernel.gc index 3a9103adaf..3708ab193f 100644 --- a/goal_src/pc/pckernel.gc +++ b/goal_src/pc/pckernel.gc @@ -898,10 +898,19 @@ (define *entity-debug-inspect* (new 'debug 'entity-debug-inspect)) -) +) ;; when debug_segment +(defun-debug draw-build-revision () + (with-dma-buffer-add-bucket ((buf (-> (current-frame) debug-buf)) + (bucket-id debug-draw1)) + (draw-string-xy *pc-settings-built-sha* + buf + 0 + (* 10 (-> *video-parms* relative-y-scale)) + (font-color flat-yellow) + (font-flags kerning)))) -) +) ;; when PC_PORT From 6f28633bc4d326ee5bc214a93ff70cd0abdcb5dd Mon Sep 17 00:00:00 2001 From: Ziemas Date: Fri, 1 Apr 2022 01:30:03 +0200 Subject: [PATCH 002/172] overlord: Fix LookupSoundIndex (#1267) --- game/overlord/sbank.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game/overlord/sbank.cpp b/game/overlord/sbank.cpp index 5a53aed469..0cede7e102 100644 --- a/game/overlord/sbank.cpp +++ b/game/overlord/sbank.cpp @@ -61,7 +61,7 @@ s32 LookupSoundIndex(const char* name, SoundBank** bank_out) { } for (int i = 0; i < bank->sound_count; i++) { - if (memcmp(bank->name, name, 16) == 0) { + if (memcmp(bank->sound[i].name, name, 16) == 0) { *bank_out = bank; return i; } From f8b00ea358aacc96e42621c4623df785e1991899 Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Fri, 1 Apr 2022 19:35:23 -0400 Subject: [PATCH 003/172] [graphics] use multidraws in tie/tfrag/shrub (#1269) --- common/custom_data/TFrag3Data.cpp | 39 +++--- common/custom_data/Tfrag3Data.h | 19 ++- decompiler/level_extractor/extract_shrub.cpp | 25 ++-- decompiler/level_extractor/extract_tfrag.cpp | 6 +- decompiler/level_extractor/extract_tie.cpp | 8 +- game/graphics/opengl_renderer/Loader.cpp | 6 - .../opengl_renderer/background/Shrub.cpp | 53 ++++---- .../opengl_renderer/background/Shrub.h | 13 +- .../opengl_renderer/background/TFragment.cpp | 24 +--- .../opengl_renderer/background/TFragment.h | 1 - .../opengl_renderer/background/Tfrag3.cpp | 48 ++++--- .../opengl_renderer/background/Tfrag3.h | 5 +- .../opengl_renderer/background/Tie3.cpp | 67 +++++----- .../opengl_renderer/background/Tie3.h | 7 +- .../background/background_common.cpp | 121 +++++++++--------- .../background/background_common.h | 23 ++-- 16 files changed, 230 insertions(+), 235 deletions(-) diff --git a/common/custom_data/TFrag3Data.cpp b/common/custom_data/TFrag3Data.cpp index 730f6196b9..8774a93e5c 100644 --- a/common/custom_data/TFrag3Data.cpp +++ b/common/custom_data/TFrag3Data.cpp @@ -25,21 +25,12 @@ void StripDraw::serialize(Serializer& ser) { ser.from_ptr(&num_triangles); } -void StripDraw::unpack() { - ASSERT(unpacked.vertex_index_stream.empty()); - for (auto& r : runs) { - for (int i = 0; i < r.length; i++) { - unpacked.vertex_index_stream.push_back(r.vertex0 + i); - } - unpacked.vertex_index_stream.push_back(UINT32_MAX); - } -} - void ShrubDraw::serialize(Serializer& ser) { ser.from_ptr(&mode); ser.from_ptr(&tree_tex_id); - ser.from_pod_vector(&vertex_index_stream); ser.from_ptr(&num_triangles); + ser.from_ptr(&first_index_index); + ser.from_ptr(&num_indices); } void InstancedStripDraw::serialize(Serializer& ser) { @@ -109,6 +100,16 @@ void TieTree::unpack() { } } } + + for (auto& draw : static_draws) { + draw.unpacked.idx_of_first_idx_in_full_buffer = unpacked.indices.size(); + for (auto& run : draw.runs) { + for (u32 ri = 0; ri < run.length; ri++) { + unpacked.indices.push_back(run.vertex0 + ri); + } + unpacked.indices.push_back(UINT32_MAX); + } + } } void ShrubTree::unpack() { @@ -154,6 +155,16 @@ void TfragTree::unpack() { o.q = 1.f; o.color_index = in.color_index; } + + for (auto& draw : draws) { + draw.unpacked.idx_of_first_idx_in_full_buffer = unpacked.indices.size(); + for (auto& run : draw.runs) { + for (u32 ri = 0; ri < run.length; ri++) { + unpacked.indices.push_back(run.vertex0 + ri); + } + unpacked.indices.push_back(UINT32_MAX); + } + } } void TieTree::serialize(Serializer& ser) { @@ -191,6 +202,7 @@ void TieTree::serialize(Serializer& ser) { void ShrubTree::serialize(Serializer& ser) { ser.from_pod_vector(&time_of_day_colors); + ser.from_pod_vector(&indices); packed_vertices.serialize(ser); if (ser.is_saving()) { ser.save(static_draws.size()); @@ -338,10 +350,7 @@ std::array Level::get_memory_usage() c shrub_tree.packed_vertices.vertices.size() * sizeof(PackedShrubVertices::Vertex); result[SHRUB_VERT] += shrub_tree.packed_vertices.instance_groups.size() * sizeof(PackedShrubVertices::InstanceGroup); - - for (const auto& draw : shrub_tree.static_draws) { - result[SHRUB_IND] += sizeof(u32) * draw.vertex_index_stream.size(); - } + result[SHRUB_IND] += sizeof(u32) * shrub_tree.indices.size(); } return result; diff --git a/common/custom_data/Tfrag3Data.h b/common/custom_data/Tfrag3Data.h index 566c8e83da..50a895a555 100644 --- a/common/custom_data/Tfrag3Data.h +++ b/common/custom_data/Tfrag3Data.h @@ -47,7 +47,7 @@ enum MemoryUsageCategory { NUM_CATEGORIES }; -constexpr int TFRAG3_VERSION = 13; +constexpr int TFRAG3_VERSION = 14; // These vertices should be uploaded to the GPU at load time and don't change struct PreloadedVertex { @@ -135,13 +135,9 @@ struct StripDraw { u32 tree_tex_id = 0; // the texture that should be bound for the draw struct { - // the list of vertices in the draw. This includes the restart code of UINT32_MAX that OpenGL - // will use to start a new strip. - std::vector vertex_index_stream; + u32 idx_of_first_idx_in_full_buffer = 0; } unpacked; - void unpack(); - struct VertexRun { u32 vertex0; u16 length; @@ -152,7 +148,8 @@ struct StripDraw { // to do culling, the above vertex stream is grouped. // by following the visgroups and checking the visibility, you can leave out invisible vertices. struct VisGroup { - u32 num = 0; // number of vertex indices in this group + u32 num_inds = 0; // number of vertex indices in this group + u32 num_tris = 0; // number of triangles u32 vis_idx_in_pc_bvh = 0; // the visibility group they belong to (in BVH) }; std::vector vis_groups; @@ -166,9 +163,8 @@ struct ShrubDraw { DrawMode mode; // the OpenGL draw settings. u32 tree_tex_id = 0; // the texture that should be bound for the draw - // the list of vertices in the draw. This includes the restart code of UINT32_MAX that OpenGL - // will use to start a new strip. - std::vector vertex_index_stream; + u32 first_index_index; + u32 num_indices; // for debug counting. u32 num_triangles = 0; @@ -261,6 +257,7 @@ struct TfragTree { struct { std::vector vertices; // mesh vertices + std::vector indices; } unpacked; void unpack(); void serialize(Serializer& ser); @@ -286,6 +283,7 @@ struct TieTree { struct { std::vector vertices; // mesh vertices + std::vector indices; } unpacked; void serialize(Serializer& ser); @@ -298,6 +296,7 @@ struct ShrubTree { PackedShrubVertices packed_vertices; std::vector static_draws; // the actual topology and settings + std::vector indices; struct { std::vector vertices; // mesh vertices diff --git a/decompiler/level_extractor/extract_shrub.cpp b/decompiler/level_extractor/extract_shrub.cpp index fa6ecf6421..4224656055 100644 --- a/decompiler/level_extractor/extract_shrub.cpp +++ b/decompiler/level_extractor/extract_shrub.cpp @@ -443,6 +443,7 @@ void make_draws(tfrag3::Level& lev, tfrag3::ShrubTree& tree_out, const std::vector& protos, const TextureDB& tdb) { + std::vector> indices_regrouped_by_draw; std::unordered_map> static_draws_by_tex; size_t global_vert_counter = 0; for (auto& proto : protos) { @@ -528,10 +529,12 @@ void make_draws(tfrag3::Level& lev, // okay, we now have a texture and draw mode, let's see if we can add to an existing... auto existing_draws_in_tex = static_draws_by_tex.find(idx_in_lev_data); tfrag3::ShrubDraw* draw_to_add_to = nullptr; + std::vector* verts_to_add_to = nullptr; if (existing_draws_in_tex != static_draws_by_tex.end()) { for (auto idx : existing_draws_in_tex->second) { if (tree_out.static_draws.at(idx).mode == mode) { draw_to_add_to = &tree_out.static_draws[idx]; + verts_to_add_to = &indices_regrouped_by_draw[idx]; } } } @@ -543,6 +546,7 @@ void make_draws(tfrag3::Level& lev, draw_to_add_to = &tree_out.static_draws.back(); draw_to_add_to->mode = mode; draw_to_add_to->tree_tex_id = idx_in_lev_data; + verts_to_add_to = &indices_regrouped_by_draw.emplace_back(); } // now we have a draw, time to add vertices @@ -556,25 +560,30 @@ void make_draws(tfrag3::Level& lev, for (size_t vidx = 0; vidx < draw.vertices.size(); vidx++) { if (draw.vertices[vidx].adc) { - draw_to_add_to->vertex_index_stream.push_back(vidx + global_vert_counter); + verts_to_add_to->push_back(vidx + global_vert_counter); draw_to_add_to->num_triangles++; } else { - draw_to_add_to->vertex_index_stream.push_back(UINT32_MAX); - draw_to_add_to->vertex_index_stream.push_back(vidx + global_vert_counter - 1); - draw_to_add_to->vertex_index_stream.push_back(vidx + global_vert_counter); + verts_to_add_to->push_back(UINT32_MAX); + verts_to_add_to->push_back(vidx + global_vert_counter - 1); + verts_to_add_to->push_back(vidx + global_vert_counter); } } - draw_to_add_to->vertex_index_stream.push_back(UINT32_MAX); - + verts_to_add_to->push_back(UINT32_MAX); global_vert_counter += draw.vertices.size(); } } } } - for (auto& draw : tree_out.static_draws) { - draw.num_triangles = clean_up_vertex_indices(draw.vertex_index_stream); + for (size_t didx = 0; didx < tree_out.static_draws.size(); didx++) { + auto& draw = tree_out.static_draws[didx]; + auto& inds = indices_regrouped_by_draw[didx]; + draw.num_triangles = clean_up_vertex_indices(inds); + draw.num_indices = inds.size(); + draw.first_index_index = tree_out.indices.size(); + tree_out.indices.insert(tree_out.indices.end(), inds.begin(), inds.end()); } + tree_out.packed_vertices.total_vertex_count = global_vert_counter; } diff --git a/decompiler/level_extractor/extract_tfrag.cpp b/decompiler/level_extractor/extract_tfrag.cpp index bec1c02b14..65fb5767c6 100644 --- a/decompiler/level_extractor/extract_tfrag.cpp +++ b/decompiler/level_extractor/extract_tfrag.cpp @@ -2043,7 +2043,8 @@ void make_tfrag3_data(std::map>& draws, for (auto& strip : draw.strips) { tfrag3::StripDraw::VisGroup vgroup; vgroup.vis_idx_in_pc_bvh = strip.tfrag_id; // associate with the tfrag for culling - vgroup.num = strip.verts.size() + 1; // one for the primitive restart! + vgroup.num_inds = strip.verts.size() + 1; // one for the primitive restart! + vgroup.num_tris = strip.verts.size() - 2; tdraw.num_triangles += strip.verts.size() - 2; tfrag3::StripDraw::VertexRun run; @@ -2127,7 +2128,8 @@ void merge_groups(std::vector& grps) { result.push_back(grps.at(0)); for (size_t i = 1; i < grps.size(); i++) { if (grps[i].vis_idx_in_pc_bvh == result.back().vis_idx_in_pc_bvh) { - result.back().num += grps[i].num; + result.back().num_inds += grps[i].num_inds; + result.back().num_tris += grps[i].num_tris; } else { result.push_back(grps[i]); } diff --git a/decompiler/level_extractor/extract_tie.cpp b/decompiler/level_extractor/extract_tie.cpp index 44663efc6b..4d444fe785 100644 --- a/decompiler/level_extractor/extract_tie.cpp +++ b/decompiler/level_extractor/extract_tie.cpp @@ -2211,8 +2211,9 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree, // now we have a draw, time to add vertices tfrag3::StripDraw::VisGroup vgroup; - vgroup.vis_idx_in_pc_bvh = inst.vis_id; // associate with the instance for culling - vgroup.num = strip.verts.size() + 1; // one for the primitive restart! + vgroup.vis_idx_in_pc_bvh = inst.vis_id; // associate with the instance for culling + vgroup.num_inds = strip.verts.size() + 1; // one for the primitive restart! + vgroup.num_tris = strip.verts.size() - 2; draw_to_add_to->num_triangles += strip.verts.size() - 2; tfrag3::PackedTieVertices::MatrixGroup grp; grp.matrix_idx = matrix_idx; @@ -2275,7 +2276,8 @@ void merge_groups(std::vector& grps) { result.push_back(grps.at(0)); for (size_t i = 1; i < grps.size(); i++) { if (grps[i].vis_idx_in_pc_bvh == result.back().vis_idx_in_pc_bvh) { - result.back().num += grps[i].num; + result.back().num_tris += grps[i].num_tris; + result.back().num_inds += grps[i].num_inds; } else { result.push_back(grps[i]); } diff --git a/game/graphics/opengl_renderer/Loader.cpp b/game/graphics/opengl_renderer/Loader.cpp index ae353a047d..0f20a805cf 100644 --- a/game/graphics/opengl_renderer/Loader.cpp +++ b/game/graphics/opengl_renderer/Loader.cpp @@ -118,17 +118,11 @@ void Loader::loader_thread() { for (auto& tie_tree : result->tie_trees) { for (auto& tree : tie_tree) { tree.unpack(); - for (auto& d : tree.static_draws) { - d.unpack(); - } } } for (auto& t_tree : result->tfrag_trees) { for (auto& tree : t_tree) { tree.unpack(); - for (auto& d : tree.draws) { - d.unpack(); - } } } diff --git a/game/graphics/opengl_renderer/background/Shrub.cpp b/game/graphics/opengl_renderer/background/Shrub.cpp index 8b2c0e4945..f1eee8a0b2 100644 --- a/game/graphics/opengl_renderer/background/Shrub.cpp +++ b/game/graphics/opengl_renderer/background/Shrub.cpp @@ -69,13 +69,20 @@ void Shrub::update_load(const Loader::LevelData* loader_data) { size_t max_draws = 0; size_t time_of_day_count = 0; + size_t max_num_grps = 0; + for (u32 l_tree = 0; l_tree < lev_data->shrub_trees.size(); l_tree++) { - size_t idx_buffer_len = 0; + size_t num_grps = 0; + const auto& tree = lev_data->shrub_trees[l_tree]; max_draws = std::max(tree.static_draws.size(), max_draws); for (auto& draw : tree.static_draws) { - idx_buffer_len += draw.vertex_index_stream.size(); + (void)draw; + // num_grps += draw.vis_groups.size(); TODO + max_num_grps += 1; } + max_num_grps = std::max(max_num_grps, num_grps); + time_of_day_count = std::max(tree.time_of_day_colors.size(), time_of_day_count); u32 verts = tree.unpacked.vertices.size(); glGenVertexArrays(1, &m_trees[l_tree].vao); @@ -124,8 +131,8 @@ void Shrub::update_load(const Loader::LevelData* loader_data) { glGenBuffers(1, &m_trees[l_tree].index_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_trees[l_tree].index_buffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_len * sizeof(u32), nullptr, GL_STREAM_DRAW); - m_trees[l_tree].index_list.resize(idx_buffer_len); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, tree.indices.size() * sizeof(u32), tree.indices.data(), + GL_STATIC_DRAW); glActiveTexture(GL_TEXTURE10); glGenTextures(1, &m_trees[l_tree].time_of_day_texture); @@ -138,7 +145,9 @@ void Shrub::update_load(const Loader::LevelData* loader_data) { glBindVertexArray(0); } - m_cache.draw_idx_temp.resize(max_draws); + m_cache.multidraw_offset_per_stripdraw.resize(max_draws); + m_cache.multidraw_count_buffer.resize(max_num_grps); + m_cache.multidraw_index_offset_buffer.resize(max_num_grps); ASSERT(time_of_day_count <= TIME_OF_DAY_COLOR_COUNT); } @@ -198,7 +207,6 @@ void Shrub::render_tree(int idx, auto& tree = m_trees.at(idx); tree.perf.draws = 0; tree.perf.verts = 0; - tree.perf.full_draws = 0; tree.perf.wind_draws = 0; if (!m_has_level) { return; @@ -229,24 +237,22 @@ void Shrub::render_tree(int idx, tree.perf.tod_time.add(setup_timer.getSeconds()); int last_texture = -1; - u32 idx_buffer_ptr = 0; tree.perf.cull_time.add(0); Timer index_timer; - idx_buffer_ptr = make_all_visible_index_list(m_cache.draw_idx_temp.data(), tree.index_list.data(), - *tree.draws); + make_all_visible_multidraws(m_cache.multidraw_offset_per_stripdraw.data(), + m_cache.multidraw_count_buffer.data(), + m_cache.multidraw_index_offset_buffer.data(), *tree.draws); + tree.perf.index_time.add(index_timer.getSeconds()); - tree.perf.index_upload = sizeof(u32) * idx_buffer_ptr; Timer draw_timer; - glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_ptr * sizeof(u32), tree.index_list.data(), - GL_STREAM_DRAW); for (size_t draw_idx = 0; draw_idx < tree.draws->size(); draw_idx++) { const auto& draw = tree.draws->operator[](draw_idx); - const auto& indices = m_cache.draw_idx_temp[draw_idx]; + const auto& indices = m_cache.multidraw_offset_per_stripdraw[draw_idx]; - if (indices.second <= indices.first) { + if (indices.second == 0) { continue; } @@ -257,20 +263,16 @@ void Shrub::render_tree(int idx, auto double_draw = setup_tfrag_shader(render_state, draw.mode, ShaderId::SHRUB); int draw_size = indices.second - indices.first; - void* offset = (void*)(indices.first * sizeof(u32)); prof.add_draw_call(); - prof.add_tri(draw.num_triangles * (float)draw_size / draw.vertex_index_stream.size()); - - bool is_full = draw_size == (int)draw.vertex_index_stream.size(); + prof.add_tri(draw.num_triangles); tree.perf.draws++; - if (is_full) { - tree.perf.full_draws++; - } tree.perf.verts += draw_size; - glDrawElements(GL_TRIANGLE_STRIP, draw_size, GL_UNSIGNED_INT, (void*)offset); + glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first], + GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first], + indices.second); switch (double_draw.kind) { case DoubleDrawKind::NONE: @@ -278,9 +280,6 @@ void Shrub::render_tree(int idx, case DoubleDrawKind::AFAIL_NO_DEPTH_WRITE: tree.perf.draws++; tree.perf.verts += draw_size; - if (is_full) { - tree.perf.full_draws++; - } prof.add_draw_call(); prof.add_tri(draw_size); glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::SHRUB].id(), "alpha_min"), @@ -288,7 +287,9 @@ void Shrub::render_tree(int idx, glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::SHRUB].id(), "alpha_max"), double_draw.aref_second); glDepthMask(GL_FALSE); - glDrawElements(GL_TRIANGLE_STRIP, draw_size, GL_UNSIGNED_INT, (void*)offset); + glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first], + GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first], + indices.second); break; default: ASSERT(false); diff --git a/game/graphics/opengl_renderer/background/Shrub.h b/game/graphics/opengl_renderer/background/Shrub.h index 88ef8086e7..d330fbb76b 100644 --- a/game/graphics/opengl_renderer/background/Shrub.h +++ b/game/graphics/opengl_renderer/background/Shrub.h @@ -31,7 +31,6 @@ class Shrub : public BucketRenderer { GLuint vertex_buffer; GLuint index_buffer; GLuint time_of_day_texture; - std::vector index_list; GLuint vao; u32 vert_count; const std::vector* draws = nullptr; @@ -39,17 +38,9 @@ class Shrub : public BucketRenderer { const std::vector* colors = nullptr; SwizzledTimeOfDay tod_cache; - std::vector> wind_matrix_cache; - - bool has_wind = false; - GLuint wind_vertex_index_buffer; - std::vector wind_vertex_index_offsets; - struct { - u32 index_upload = 0; u32 verts = 0; u32 draws = 0; - u32 full_draws = 0; // ones that have all visible u32 wind_draws = 0; Filtered cull_time; Filtered index_time; @@ -71,7 +62,9 @@ class Shrub : public BucketRenderer { bool m_has_level = false; struct Cache { - std::vector> draw_idx_temp; + std::vector> multidraw_offset_per_stripdraw; + std::vector multidraw_count_buffer; + std::vector multidraw_index_offset_buffer; } m_cache; TfragPcPortData m_pc_port_data; }; diff --git a/game/graphics/opengl_renderer/background/TFragment.cpp b/game/graphics/opengl_renderer/background/TFragment.cpp index 8b685510f6..d6833c1a96 100644 --- a/game/graphics/opengl_renderer/background/TFragment.cpp +++ b/game/graphics/opengl_renderer/background/TFragment.cpp @@ -38,8 +38,6 @@ constexpr const char* level_names[] = {"bea", "cit", "dar", "fin", "int", "jub", void TFragment::render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) { - m_debug_string.clear(); - if (!m_enabled) { while (dma.current_tag_offset() != render_state->next_bucket) { dma.read_and_advance(); @@ -148,13 +146,9 @@ void TFragment::render(DmaFollower& dma, m_tfrag3.render_matching_trees(m_tfrag3.lod(), m_tree_kinds, settings, render_state, t3prof); } - m_debug_string += fmt::format("fail: {}\n", dma.current_tag().print()); - while (dma.current_tag_offset() != render_state->next_bucket) { auto tag = dma.current_tag().print(); - auto data = dma.read_and_advance(); - m_debug_string += - fmt::format("DMA {} {} bytes, {}\n", tag, data.size_bytes, data.vifcode0().print()); + dma.read_and_advance(); } if (m_hack_test_many_levels) { @@ -211,8 +205,6 @@ void TFragment::draw_debug_window() { } m_tfrag3.draw_debug_window(); - - ImGui::TextUnformatted(m_debug_string.data()); } void TFragment::handle_initialization(DmaFollower& dma) { @@ -238,7 +230,6 @@ void TFragment::handle_initialization(DmaFollower& dma) { auto data_upload = dma.read_and_advance(); unpack_to_stcycl(&m_tfrag_data, data_upload, VifCode::Kind::UNPACK_V4_32, 4, 4, sizeof(TFragData), TFragDataMem::TFragFrameData, false, false); - m_debug_string += fmt::format("Frame Data:\n {}\n", m_tfrag_data.print()); // call the setup program auto mscal_setup = dma.read_and_advance(); @@ -249,19 +240,6 @@ void TFragment::handle_initialization(DmaFollower& dma) { memcpy(&m_pc_port_data, pc_port_data.data, sizeof(TfragPcPortData)); m_pc_port_data.level_name[11] = '\0'; - for (int i = 0; i < 4; i++) { - m_debug_string += fmt::format("p[{}]: {}\n", i, m_pc_port_data.planes[i].to_string_aligned()); - } - - for (int i = 0; i < 4; i++) { - m_debug_string += fmt::format("t[{}]: {:x} {:x} {:x} {:x}\n", i, m_pc_port_data.itimes[i].x(), - m_pc_port_data.itimes[i].y(), m_pc_port_data.itimes[i].z(), - m_pc_port_data.itimes[i].w()); - } - - m_debug_string += - fmt::format("level: {}, tree: {}\n", m_pc_port_data.level_name, m_pc_port_data.tree_idx); - // setup double buffering. auto db_setup = dma.read_and_advance(); ASSERT(db_setup.size_bytes == 0); diff --git a/game/graphics/opengl_renderer/background/TFragment.h b/game/graphics/opengl_renderer/background/TFragment.h index 1b091824ab..c079a00555 100644 --- a/game/graphics/opengl_renderer/background/TFragment.h +++ b/game/graphics/opengl_renderer/background/TFragment.h @@ -46,7 +46,6 @@ class TFragment : public BucketRenderer { private: void handle_initialization(DmaFollower& dma); - std::string m_debug_string; bool m_child_mode = false; bool m_hack_test_many_levels = false; bool m_override_time_of_day = false; diff --git a/game/graphics/opengl_renderer/background/Tfrag3.cpp b/game/graphics/opengl_renderer/background/Tfrag3.cpp index 2e949dc86c..6835fef3df 100644 --- a/game/graphics/opengl_renderer/background/Tfrag3.cpp +++ b/game/graphics/opengl_renderer/background/Tfrag3.cpp @@ -48,22 +48,24 @@ void Tfrag3::update_load(const std::vector& tree_kind size_t time_of_day_count = 0; size_t vis_temp_len = 0; - size_t max_draw = 0; + size_t max_draws = 0; + size_t max_num_grps = 0; for (int geom = 0; geom < GEOM_MAX; ++geom) { for (size_t tree_idx = 0; tree_idx < lev_data->tfrag_trees[geom].size(); tree_idx++) { - size_t idx_buffer_len = 0; - const auto& tree = lev_data->tfrag_trees[geom][tree_idx]; auto& tree_cache = m_cached_trees[geom].emplace_back(); tree_cache.kind = tree.kind; if (std::find(tree_kinds.begin(), tree_kinds.end(), tree.kind) != tree_kinds.end()) { - max_draw = std::max(tree.draws.size(), max_draw); + max_draws = std::max(tree.draws.size(), max_draws); + size_t num_grps = 0; for (auto& draw : tree.draws) { - idx_buffer_len += draw.unpacked.vertex_index_stream.size(); + num_grps += draw.vis_groups.size(); } + max_num_grps = std::max(max_num_grps, num_grps); + time_of_day_count = std::max(tree.colors.size(), time_of_day_count); u32 verts = tree.packed_vertices.vertices.size(); glGenVertexArrays(1, &tree_cache.vao); @@ -109,9 +111,8 @@ void Tfrag3::update_load(const std::vector& tree_kind glGenBuffers(1, &tree_cache.index_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tree_cache.index_buffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_len * sizeof(u32), nullptr, - GL_STREAM_DRAW); - tree_cache.index_list.resize(idx_buffer_len); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, tree.unpacked.indices.size() * sizeof(u32), + tree.unpacked.indices.data(), GL_STREAM_DRAW); glGenTextures(1, &tree_cache.time_of_day_texture); glBindTexture(GL_TEXTURE_1D, tree_cache.time_of_day_texture); @@ -125,7 +126,9 @@ void Tfrag3::update_load(const std::vector& tree_kind } m_cache.vis_temp.resize(vis_temp_len); - m_cache.draw_idx_temp.resize(max_draw); + m_cache.multidraw_offset_per_stripdraw.resize(max_draws); + m_cache.multidraw_count_buffer.resize(max_num_grps); + m_cache.multidraw_index_offset_buffer.resize(max_num_grps); ASSERT(time_of_day_count <= TIME_OF_DAY_COLOR_COUNT); } @@ -196,17 +199,17 @@ void Tfrag3::render_tree(int geom, cull_check_all_slow(settings.planes, tree.vis->vis_nodes, settings.occlusion_culling, m_cache.vis_temp.data()); - int idx_buffer_ptr = make_index_list_from_vis_string( - m_cache.draw_idx_temp.data(), tree.index_list.data(), *tree.draws, m_cache.vis_temp); + u32 total_tris = make_multidraws_from_vis_string( + m_cache.multidraw_offset_per_stripdraw.data(), m_cache.multidraw_count_buffer.data(), + m_cache.multidraw_index_offset_buffer.data(), *tree.draws, m_cache.vis_temp); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_ptr * sizeof(u32), tree.index_list.data(), - GL_STREAM_DRAW); + prof.add_tri(total_tris); for (size_t draw_idx = 0; draw_idx < tree.draws->size(); draw_idx++) { const auto& draw = tree.draws->operator[](draw_idx); - const auto& indices = m_cache.draw_idx_temp[draw_idx]; + const auto& indices = m_cache.multidraw_offset_per_stripdraw[draw_idx]; - if (indices.second <= indices.first) { + if (indices.second == 0) { continue; } @@ -215,13 +218,16 @@ void Tfrag3::render_tree(int geom, auto double_draw = setup_tfrag_shader(render_state, draw.mode, ShaderId::TFRAG3); tree.tris_this_frame += draw.num_triangles; tree.draws_this_frame++; - int draw_size = indices.second - indices.first; - void* offset = (void*)(indices.first * sizeof(u32)); + int draw_size = 0; + for (int i = 0; i < indices.second; i++) { + draw_size += m_cache.multidraw_count_buffer[indices.first + i]; + } prof.add_draw_call(); - prof.add_tri(draw.num_triangles * (float)draw_size / draw.unpacked.vertex_index_stream.size()); - glDrawElements(GL_TRIANGLE_STRIP, draw_size, GL_UNSIGNED_INT, (void*)offset); + glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first], + GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first], + indices.second); switch (double_draw.kind) { case DoubleDrawKind::NONE: @@ -234,7 +240,9 @@ void Tfrag3::render_tree(int geom, glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3].id(), "alpha_max"), double_draw.aref_second); glDepthMask(GL_FALSE); - glDrawElements(GL_TRIANGLE_STRIP, draw_size, GL_UNSIGNED_INT, (void*)offset); + glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first], + GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first], + indices.second); break; default: ASSERT(false); diff --git a/game/graphics/opengl_renderer/background/Tfrag3.h b/game/graphics/opengl_renderer/background/Tfrag3.h index 07fc50f9e7..e79aad3301 100644 --- a/game/graphics/opengl_renderer/background/Tfrag3.h +++ b/game/graphics/opengl_renderer/background/Tfrag3.h @@ -60,7 +60,6 @@ class Tfrag3 { tfrag3::TFragmentTreeKind kind; GLuint vertex_buffer = -1; GLuint index_buffer = -1; - std::vector index_list; GLuint time_of_day_texture; GLuint vao; u32 vert_count = 0; @@ -84,7 +83,9 @@ class Tfrag3 { struct Cache { std::vector vis_temp; - std::vector> draw_idx_temp; + std::vector> multidraw_offset_per_stripdraw; + std::vector multidraw_count_buffer; + std::vector multidraw_index_offset_buffer; } m_cache; std::string m_level_name; diff --git a/game/graphics/opengl_renderer/background/Tie3.cpp b/game/graphics/opengl_renderer/background/Tie3.cpp index 95b8204941..868bd2f141 100644 --- a/game/graphics/opengl_renderer/background/Tie3.cpp +++ b/game/graphics/opengl_renderer/background/Tie3.cpp @@ -25,17 +25,19 @@ void Tie3::update_load(const Loader::LevelData* loader_data) { size_t vis_temp_len = 0; size_t max_draws = 0; + size_t max_num_grps = 0; u16 max_wind_idx = 0; size_t time_of_day_count = 0; for (u32 l_geo = 0; l_geo < tfrag3::TIE_GEOS; l_geo++) { for (u32 l_tree = 0; l_tree < lev_data->tie_trees[l_geo].size(); l_tree++) { - size_t idx_buffer_len = 0; size_t wind_idx_buffer_len = 0; + size_t num_grps = 0; const auto& tree = lev_data->tie_trees[l_geo][l_tree]; max_draws = std::max(tree.static_draws.size(), max_draws); for (auto& draw : tree.static_draws) { - idx_buffer_len += draw.unpacked.vertex_index_stream.size(); + num_grps += draw.vis_groups.size(); } + max_num_grps = std::max(max_num_grps, num_grps); for (auto& draw : tree.instanced_wind_draws) { wind_idx_buffer_len += draw.vertex_index_stream.size(); } @@ -86,8 +88,9 @@ void Tie3::update_load(const Loader::LevelData* loader_data) { glGenBuffers(1, &lod_tree[l_tree].index_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lod_tree[l_tree].index_buffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_len * sizeof(u32), nullptr, GL_STREAM_DRAW); - lod_tree[l_tree].index_list.resize(idx_buffer_len); + // todo: move to loader, this will probably be quite slow. + glBufferData(GL_ELEMENT_ARRAY_BUFFER, tree.unpacked.indices.size() * sizeof(u32), + tree.unpacked.indices.data(), GL_STATIC_DRAW); if (wind_idx_buffer_len > 0) { lod_tree[l_tree].wind_matrix_cache.resize(tree.wind_instance_info.size()); @@ -114,7 +117,9 @@ void Tie3::update_load(const Loader::LevelData* loader_data) { } m_cache.vis_temp.resize(vis_temp_len); - m_cache.draw_idx_temp.resize(max_draws); + m_cache.multidraw_offset_per_stripdraw.resize(max_draws); + m_cache.multidraw_count_buffer.resize(max_num_grps); + m_cache.multidraw_index_offset_buffer.resize(max_num_grps); m_wind_vectors.resize(4 * max_wind_idx + 4); // 4x u32's per wind. ASSERT(time_of_day_count <= TIME_OF_DAY_COLOR_COUNT); } @@ -501,7 +506,6 @@ void Tie3::render_tree(int idx, auto& tree = m_trees.at(geom).at(idx); tree.perf.draws = 0; tree.perf.verts = 0; - tree.perf.full_draws = 0; tree.perf.wind_draws = 0; if (!m_has_level) { return; @@ -536,15 +540,15 @@ void Tie3::render_tree(int idx, tree.perf.tod_time.add(setup_timer.getSeconds()); int last_texture = -1; - u32 idx_buffer_ptr = 0; + u32 num_tris; if (m_debug_all_visible) { tree.perf.cull_time.add(0); Timer index_timer; - idx_buffer_ptr = make_all_visible_index_list(m_cache.draw_idx_temp.data(), - tree.index_list.data(), *tree.draws); + num_tris = make_all_visible_multidraws( + m_cache.multidraw_offset_per_stripdraw.data(), m_cache.multidraw_count_buffer.data(), + m_cache.multidraw_index_offset_buffer.data(), *tree.draws); tree.perf.index_time.add(index_timer.getSeconds()); - tree.perf.index_upload = sizeof(u32) * idx_buffer_ptr; } else { Timer cull_timer; cull_check_all_slow(settings.planes, tree.vis->vis_nodes, settings.occlusion_culling, @@ -552,21 +556,20 @@ void Tie3::render_tree(int idx, tree.perf.cull_time.add(cull_timer.getSeconds()); Timer index_timer; - idx_buffer_ptr = make_index_list_from_vis_string( - m_cache.draw_idx_temp.data(), tree.index_list.data(), *tree.draws, m_cache.vis_temp); + num_tris = make_multidraws_from_vis_string( + m_cache.multidraw_offset_per_stripdraw.data(), m_cache.multidraw_count_buffer.data(), + m_cache.multidraw_index_offset_buffer.data(), *tree.draws, m_cache.vis_temp); tree.perf.index_time.add(index_timer.getSeconds()); - tree.perf.index_upload = sizeof(u32) * idx_buffer_ptr; } Timer draw_timer; - glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_ptr * sizeof(u32), tree.index_list.data(), - GL_STREAM_DRAW); + prof.add_tri(num_tris); for (size_t draw_idx = 0; draw_idx < tree.draws->size(); draw_idx++) { const auto& draw = tree.draws->operator[](draw_idx); - const auto& indices = m_cache.draw_idx_temp[draw_idx]; + const auto& indices = m_cache.multidraw_offset_per_stripdraw[draw_idx]; - if (indices.second <= indices.first) { + if (indices.second == 0) { continue; } @@ -576,21 +579,19 @@ void Tie3::render_tree(int idx, } auto double_draw = setup_tfrag_shader(render_state, draw.mode, ShaderId::TFRAG3); - int draw_size = indices.second - indices.first; - void* offset = (void*)(indices.first * sizeof(u32)); + int draw_size = 0; + for (int i = 0; i < indices.second; i++) { + draw_size += m_cache.multidraw_count_buffer[indices.first + i]; + } prof.add_draw_call(); - prof.add_tri(draw.num_triangles * (float)draw_size / draw.unpacked.vertex_index_stream.size()); - - bool is_full = draw_size == (int)draw.unpacked.vertex_index_stream.size(); tree.perf.draws++; - if (is_full) { - tree.perf.full_draws++; - } tree.perf.verts += draw_size; - glDrawElements(GL_TRIANGLE_STRIP, draw_size, GL_UNSIGNED_INT, (void*)offset); + glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first], + GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first], + indices.second); switch (double_draw.kind) { case DoubleDrawKind::NONE: @@ -598,9 +599,6 @@ void Tie3::render_tree(int idx, case DoubleDrawKind::AFAIL_NO_DEPTH_WRITE: tree.perf.draws++; tree.perf.verts += draw_size; - if (is_full) { - tree.perf.full_draws++; - } prof.add_draw_call(); prof.add_tri(draw_size); glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3].id(), "alpha_min"), @@ -608,7 +606,9 @@ void Tie3::render_tree(int idx, glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3].id(), "alpha_max"), double_draw.aref_second); glDepthMask(GL_FALSE); - glDrawElements(GL_TRIANGLE_STRIP, draw_size, GL_UNSIGNED_INT, (void*)offset); + glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first], + GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first], + indices.second); break; default: ASSERT(false); @@ -628,7 +628,9 @@ void Tie3::render_tree(int idx, settings.fog.x()); glDisable(GL_BLEND); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glDrawElements(GL_TRIANGLE_STRIP, draw_size, GL_UNSIGNED_INT, (void*)offset); + glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first], + GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first], + indices.second); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); prof.add_draw_call(); prof.add_tri(draw_size); @@ -662,9 +664,8 @@ void Tie3::draw_debug_window() { for (u32 i = 0; i < m_trees[lod()].size(); i++) { auto& perf = m_trees[lod()][i].perf; ImGui::Text("Tree: %d", i); - ImGui::Text("index data bytes: %d", perf.index_upload); ImGui::Text("time of days: %d", (int)m_trees[lod()][i].colors->size()); - ImGui::Text("draw: %d, full: %d, verts: %d", perf.draws, perf.full_draws, perf.verts); + ImGui::Text("draw: %d, verts: %d", perf.draws, perf.verts); ImGui::Text("wind draw: %d", perf.wind_draws); ImGui::Text("total: %.2f", perf.tree_time.get()); ImGui::Text("cull: %.2f index: %.2f tod: %.2f setup: %.2f draw: %.2f", diff --git a/game/graphics/opengl_renderer/background/Tie3.h b/game/graphics/opengl_renderer/background/Tie3.h index 723b4a7bba..ede3d5ec68 100644 --- a/game/graphics/opengl_renderer/background/Tie3.h +++ b/game/graphics/opengl_renderer/background/Tie3.h @@ -52,7 +52,6 @@ class Tie3 : public BucketRenderer { GLuint vertex_buffer; GLuint index_buffer; GLuint time_of_day_texture; - std::vector index_list; GLuint vao; u32 vert_count; const std::vector* draws = nullptr; @@ -69,10 +68,8 @@ class Tie3 : public BucketRenderer { std::vector wind_vertex_index_offsets; struct { - u32 index_upload = 0; u32 verts = 0; u32 draws = 0; - u32 full_draws = 0; // ones that have all visible u32 wind_draws = 0; Filtered cull_time; Filtered index_time; @@ -90,7 +87,9 @@ class Tie3 : public BucketRenderer { struct Cache { std::vector vis_temp; - std::vector> draw_idx_temp; + std::vector> multidraw_offset_per_stripdraw; + std::vector multidraw_count_buffer; + std::vector multidraw_index_offset_buffer; } m_cache; std::vector> m_color_result; diff --git a/game/graphics/opengl_renderer/background/background_common.cpp b/game/graphics/opengl_renderer/background/background_common.cpp index 4fc14ec005..0802524176 100644 --- a/game/graphics/opengl_renderer/background/background_common.cpp +++ b/game/graphics/opengl_renderer/background/background_common.cpp @@ -483,82 +483,77 @@ void cull_check_all_slow(const math::Vector4f* planes, } } -u32 make_all_visible_index_list(std::pair* group_out, - u32* idx_out, - const std::vector& draws) { - int idx_buffer_ptr = 0; +void make_all_visible_multidraws(std::pair* draw_ptrs_out, + GLsizei* counts_out, + void** index_offsets_out, + const std::vector& draws) { + u64 md_idx = 0; for (size_t i = 0; i < draws.size(); i++) { const auto& draw = draws[i]; + u64 iidx = draw.first_index_index; std::pair ds; - ds.first = idx_buffer_ptr; - memcpy(&idx_out[idx_buffer_ptr], draw.unpacked.vertex_index_stream.data(), - draw.unpacked.vertex_index_stream.size() * sizeof(u32)); - idx_buffer_ptr += draw.unpacked.vertex_index_stream.size(); - ds.second = idx_buffer_ptr; - group_out[i] = ds; + ds.first = md_idx; + ds.second = 1; + counts_out[md_idx] = draw.num_indices; + index_offsets_out[md_idx] = (void*)(iidx * sizeof(u32)); + md_idx++; + draw_ptrs_out[i] = ds; } - return idx_buffer_ptr; } -u32 make_all_visible_index_list(std::pair* group_out, - u32* idx_out, - const std::vector& draws) { - int idx_buffer_ptr = 0; - for (size_t i = 0; i < draws.size(); i++) { - const auto& draw = draws[i]; - std::pair ds; - ds.first = idx_buffer_ptr; - memcpy(&idx_out[idx_buffer_ptr], draw.vertex_index_stream.data(), - draw.vertex_index_stream.size() * sizeof(u32)); - idx_buffer_ptr += draw.vertex_index_stream.size(); - ds.second = idx_buffer_ptr; - group_out[i] = ds; - } - return idx_buffer_ptr; -} - -u32 make_index_list_from_vis_string(std::pair* group_out, - u32* idx_out, +u32 make_multidraws_from_vis_string(std::pair* draw_ptrs_out, + GLsizei* counts_out, + void** index_offsets_out, const std::vector& draws, const std::vector& vis_data) { - int idx_buffer_ptr = 0; + u64 md_idx = 0; + u32 num_tris = 0; for (size_t i = 0; i < draws.size(); i++) { const auto& draw = draws[i]; - int vtx_idx = 0; + u64 iidx = draw.unpacked.idx_of_first_idx_in_full_buffer; std::pair ds; - ds.first = idx_buffer_ptr; - bool building_run = false; - int run_start_out = 0; - int run_start_in = 0; + ds.first = md_idx; + ds.second = 0; for (auto& grp : draw.vis_groups) { - bool vis = grp.vis_idx_in_pc_bvh == 0xffffffff || vis_data[grp.vis_idx_in_pc_bvh]; - if (building_run) { - if (vis) { - idx_buffer_ptr += grp.num; - } else { - building_run = false; - idx_buffer_ptr += grp.num; - memcpy(&idx_out[run_start_out], &draw.unpacked.vertex_index_stream[run_start_in], - (idx_buffer_ptr - run_start_out) * sizeof(u32)); - } - } else { - if (vis) { - building_run = true; - run_start_out = idx_buffer_ptr; - run_start_in = vtx_idx; - idx_buffer_ptr += grp.num; - } else { - } + if (grp.vis_idx_in_pc_bvh == 0xffffffff || vis_data[grp.vis_idx_in_pc_bvh]) { + // visible! + // let's use a multidraw + counts_out[md_idx] = grp.num_inds; + index_offsets_out[md_idx] = (void*)(iidx * sizeof(u32)); + ds.second++; + md_idx++; + num_tris += grp.num_tris; } - vtx_idx += grp.num; + iidx += grp.num_inds; } - if (building_run) { - memcpy(&idx_out[run_start_out], &draw.unpacked.vertex_index_stream[run_start_in], - (idx_buffer_ptr - run_start_out) * sizeof(u32)); - } - - ds.second = idx_buffer_ptr; - group_out[i] = ds; + draw_ptrs_out[i] = ds; } - return idx_buffer_ptr; + return num_tris; +} + +u32 make_all_visible_multidraws(std::pair* draw_ptrs_out, + GLsizei* counts_out, + void** index_offsets_out, + const std::vector& draws) { + u64 md_idx = 0; + u32 num_tris = 0; + for (size_t i = 0; i < draws.size(); i++) { + const auto& draw = draws[i]; + u64 iidx = draw.unpacked.idx_of_first_idx_in_full_buffer; + std::pair ds; + ds.first = md_idx; + ds.second = 0; + for (auto& grp : draw.vis_groups) { + // visible! + // let's use a multidraw + counts_out[md_idx] = grp.num_inds; + index_offsets_out[md_idx] = (void*)(iidx * sizeof(u32)); + ds.second++; + md_idx++; + num_tris += grp.num_tris; + iidx += grp.num_inds; + } + draw_ptrs_out[i] = ds; + } + return num_tris; } diff --git a/game/graphics/opengl_renderer/background/background_common.h b/game/graphics/opengl_renderer/background/background_common.h index 57266be720..a648ebe43c 100644 --- a/game/graphics/opengl_renderer/background/background_common.h +++ b/game/graphics/opengl_renderer/background/background_common.h @@ -60,13 +60,18 @@ struct TfragPcPortData { u32 tree_idx; }; -u32 make_index_list_from_vis_string(std::pair* group_out, - u32* idx_out, - const std::vector& draws, - const std::vector& vis_data); -u32 make_all_visible_index_list(std::pair* group_out, - u32* idx_out, +void make_all_visible_multidraws(std::pair* draw_ptrs_out, + GLsizei* counts_out, + void** index_offsets_out, + const std::vector& draws); + +u32 make_all_visible_multidraws(std::pair* draw_ptrs_out, + GLsizei* counts_out, + void** index_offsets_out, const std::vector& draws); -u32 make_all_visible_index_list(std::pair* group_out, - u32* idx_out, - const std::vector& draws); \ No newline at end of file + +u32 make_multidraws_from_vis_string(std::pair* draw_ptrs_out, + GLsizei* counts_out, + void** index_offsets_out, + const std::vector& draws, + const std::vector& vis_data); \ No newline at end of file From 4310bb1419258cf5687d2b4cff42b912fbf04e1c Mon Sep 17 00:00:00 2001 From: Ziemas Date: Sat, 2 Apr 2022 16:46:42 +0200 Subject: [PATCH 004/172] A few overlord fixes (#1273) * Fix RPC Player buffer size * Fix calculateFallofVolume * Fix CalculateAngle --- game/overlord/srpc.cpp | 2 +- game/overlord/ssound.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/game/overlord/srpc.cpp b/game/overlord/srpc.cpp index 7aa54f2897..2e594d28fb 100644 --- a/game/overlord/srpc.cpp +++ b/game/overlord/srpc.cpp @@ -16,7 +16,7 @@ using namespace iop; MusicTweaks gMusicTweakInfo; constexpr int SRPC_MESSAGE_SIZE = 0x50; static uint8_t gLoaderBuf[SRPC_MESSAGE_SIZE]; -static uint8_t gPlayerBuf[SRPC_MESSAGE_SIZE * 127]; +static uint8_t gPlayerBuf[SRPC_MESSAGE_SIZE * 128]; int32_t gSoundEnable = 1; static u32 gInfoEE = 0; // EE address where we should send info on each frame. s16 gFlava; diff --git a/game/overlord/ssound.cpp b/game/overlord/ssound.cpp index a79efef572..51e368beab 100644 --- a/game/overlord/ssound.cpp +++ b/game/overlord/ssound.cpp @@ -252,7 +252,7 @@ s32 CalculateFallofVolume(Vec3w* pos, s32 volume, s32 fo_curve, s32 fo_min, s32 s32 distance = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff; if (distance != 0) { s32 steps = 0; - while ((steps & 0xc0000000) == 0) { + while ((distance & 0xc0000000) == 0) { distance <<= 2; steps++; } @@ -292,7 +292,7 @@ s32 CalculateFallofVolume(Vec3w* pos, s32 volume, s32 fo_curve, s32 fo_min, s32 factor = 0x10000; } - return factor; // TODO + return (factor * volume) >> 16; } s32 CalculateAngle(Vec3w* trans) { @@ -303,7 +303,7 @@ s32 CalculateAngle(Vec3w* trans) { s32 lookupZ = diffZ; if (diffX < 0) { - lookupZ = trans->x - gCamTrans.x; + lookupX = trans->x - gCamTrans.x; } if (diffZ < 0) { From 9495d1fcce8d0fc2cbbc616717d6921e3bdc7c5f Mon Sep 17 00:00:00 2001 From: Ziemas Date: Sun, 3 Apr 2022 18:19:39 +0200 Subject: [PATCH 005/172] Unpause sounds when leaving start menu (#1275) --- goal_src/engine/game/main.gc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/goal_src/engine/game/main.gc b/goal_src/engine/game/main.gc index 4ea00c3876..4c04bff803 100644 --- a/goal_src/engine/game/main.gc +++ b/goal_src/engine/game/main.gc @@ -147,7 +147,7 @@ (('game) ;; allow pausable/menu to run. (logclear! (-> *setting-control* default process-mask) (process-mask pause menu)) - ;; (sound-group-continue (the-as uint 255)) TODO (we need to flush sound commands) + (sound-group-continue (the-as uint 255)) (hide-progress-screen) ) ) From 2e31c9f09b9921e7859eed9670fc2f0c56cef488 Mon Sep 17 00:00:00 2001 From: water Date: Sun, 3 Apr 2022 13:56:45 -0400 Subject: [PATCH 006/172] toggle for old format --- .../graphics/opengl_renderer/BucketRenderer.h | 1 + .../opengl_renderer/OpenGLRenderer.cpp | 1 + .../opengl_renderer/background/Shrub.cpp | 65 +++++-- .../opengl_renderer/background/Shrub.h | 5 +- .../opengl_renderer/background/Tfrag3.cpp | 72 +++++--- .../opengl_renderer/background/Tfrag3.h | 8 +- .../opengl_renderer/background/Tie3.cpp | 122 +++++++++---- .../opengl_renderer/background/Tie3.h | 5 +- .../background/background_common.cpp | 162 ++++++++++++++---- .../background/background_common.h | 20 ++- 10 files changed, 347 insertions(+), 114 deletions(-) diff --git a/game/graphics/opengl_renderer/BucketRenderer.h b/game/graphics/opengl_renderer/BucketRenderer.h index 3493c42f92..77d9aea1f6 100644 --- a/game/graphics/opengl_renderer/BucketRenderer.h +++ b/game/graphics/opengl_renderer/BucketRenderer.h @@ -42,6 +42,7 @@ struct SharedRenderState { bool use_generic2 = true; math::Vector fog_color; float fog_intensity = 1.f; + bool no_multidraw = false; void reset(); bool has_camera_planes = false; diff --git a/game/graphics/opengl_renderer/OpenGLRenderer.cpp b/game/graphics/opengl_renderer/OpenGLRenderer.cpp index 340201051f..e73ee673cd 100644 --- a/game/graphics/opengl_renderer/OpenGLRenderer.cpp +++ b/game/graphics/opengl_renderer/OpenGLRenderer.cpp @@ -366,6 +366,7 @@ void OpenGLRenderer::render(DmaFollower dma, const RenderOptions& settings) { void OpenGLRenderer::draw_renderer_selection_window() { ImGui::Begin("Renderer Debug"); + ImGui::Checkbox("Use old single-draw", &m_render_state.no_multidraw); ImGui::SliderFloat("Fog Adjust", &m_render_state.fog_intensity, 0, 10); ImGui::Checkbox("Sky CPU", &m_render_state.use_sky_cpu); ImGui::Checkbox("Occlusion Cull", &m_render_state.use_occlusion_culling); diff --git a/game/graphics/opengl_renderer/background/Shrub.cpp b/game/graphics/opengl_renderer/background/Shrub.cpp index f1eee8a0b2..38f5d06d40 100644 --- a/game/graphics/opengl_renderer/background/Shrub.cpp +++ b/game/graphics/opengl_renderer/background/Shrub.cpp @@ -70,6 +70,7 @@ void Shrub::update_load(const Loader::LevelData* loader_data) { size_t max_draws = 0; size_t time_of_day_count = 0; size_t max_num_grps = 0; + size_t max_inds = 0; for (u32 l_tree = 0; l_tree < lev_data->shrub_trees.size(); l_tree++) { size_t num_grps = 0; @@ -84,6 +85,7 @@ void Shrub::update_load(const Loader::LevelData* loader_data) { max_num_grps = std::max(max_num_grps, num_grps); time_of_day_count = std::max(tree.time_of_day_colors.size(), time_of_day_count); + max_inds = std::max(tree.indices.size(), max_inds); u32 verts = tree.unpacked.vertices.size(); glGenVertexArrays(1, &m_trees[l_tree].vao); glBindVertexArray(m_trees[l_tree].vao); @@ -91,6 +93,7 @@ void Shrub::update_load(const Loader::LevelData* loader_data) { m_trees[l_tree].vert_count = verts; m_trees[l_tree].draws = &tree.static_draws; m_trees[l_tree].colors = &tree.time_of_day_colors; + m_trees[l_tree].index_data = tree.indices.data(); m_trees[l_tree].tod_cache = swizzle_time_of_day(tree.time_of_day_colors); glBindBuffer(GL_ARRAY_BUFFER, m_trees[l_tree].vertex_buffer); glEnableVertexAttribArray(0); @@ -129,6 +132,7 @@ void Shrub::update_load(const Loader::LevelData* loader_data) { (void*)offsetof(tfrag3::ShrubGpuVertex, color_index) // offset (0) ); + glGenBuffers(1, &m_trees[l_tree].single_draw_index_buffer); glGenBuffers(1, &m_trees[l_tree].index_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_trees[l_tree].index_buffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, tree.indices.size() * sizeof(u32), tree.indices.data(), @@ -148,6 +152,8 @@ void Shrub::update_load(const Loader::LevelData* loader_data) { m_cache.multidraw_offset_per_stripdraw.resize(max_draws); m_cache.multidraw_count_buffer.resize(max_num_grps); m_cache.multidraw_index_offset_buffer.resize(max_num_grps); + m_cache.draw_idx_temp.resize(max_draws); + m_cache.index_temp.resize(max_inds); ASSERT(time_of_day_count <= TIME_OF_DAY_COLOR_COUNT); } @@ -185,6 +191,7 @@ void Shrub::discard_tree_cache() { glBindTexture(GL_TEXTURE_1D, tree.time_of_day_texture); glDeleteTextures(1, &tree.time_of_day_texture); glDeleteBuffers(1, &tree.index_buffer); + glDeleteBuffers(1, &tree.single_draw_index_buffer); glDeleteVertexArrays(1, &tree.vao); } @@ -206,7 +213,6 @@ void Shrub::render_tree(int idx, Timer tree_timer; auto& tree = m_trees.at(idx); tree.perf.draws = 0; - tree.perf.verts = 0; tree.perf.wind_draws = 0; if (!m_has_level) { return; @@ -230,7 +236,8 @@ void Shrub::render_tree(int idx, glBindVertexArray(tree.vao); glBindBuffer(GL_ARRAY_BUFFER, tree.vertex_buffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tree.index_buffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, + render_state->no_multidraw ? tree.single_draw_index_buffer : tree.index_buffer); glActiveTexture(GL_TEXTURE0); glEnable(GL_PRIMITIVE_RESTART); glPrimitiveRestartIndex(UINT32_MAX); @@ -240,9 +247,16 @@ void Shrub::render_tree(int idx, tree.perf.cull_time.add(0); Timer index_timer; - make_all_visible_multidraws(m_cache.multidraw_offset_per_stripdraw.data(), - m_cache.multidraw_count_buffer.data(), - m_cache.multidraw_index_offset_buffer.data(), *tree.draws); + if (render_state->no_multidraw) { + u32 idx_buffer_size = make_all_visible_index_list( + m_cache.draw_idx_temp.data(), m_cache.index_temp.data(), *tree.draws, tree.index_data); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size * sizeof(u32), m_cache.index_temp.data(), + GL_STREAM_DRAW); + } else { + make_all_visible_multidraws(m_cache.multidraw_offset_per_stripdraw.data(), + m_cache.multidraw_count_buffer.data(), + m_cache.multidraw_index_offset_buffer.data(), *tree.draws); + } tree.perf.index_time.add(index_timer.getSeconds()); @@ -250,10 +264,17 @@ void Shrub::render_tree(int idx, for (size_t draw_idx = 0; draw_idx < tree.draws->size(); draw_idx++) { const auto& draw = tree.draws->operator[](draw_idx); - const auto& indices = m_cache.multidraw_offset_per_stripdraw[draw_idx]; + const auto& multidraw_indices = m_cache.multidraw_offset_per_stripdraw[draw_idx]; + const auto& singledraw_indices = m_cache.draw_idx_temp[draw_idx]; - if (indices.second == 0) { - continue; + if (render_state->no_multidraw) { + if (singledraw_indices.second == 0) { + continue; + } + } else { + if (multidraw_indices.second == 0) { + continue; + } } if ((int)draw.tree_tex_id != last_texture) { @@ -262,34 +283,42 @@ void Shrub::render_tree(int idx, } auto double_draw = setup_tfrag_shader(render_state, draw.mode, ShaderId::SHRUB); - int draw_size = indices.second - indices.first; prof.add_draw_call(); prof.add_tri(draw.num_triangles); tree.perf.draws++; - tree.perf.verts += draw_size; - glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first], - GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first], - indices.second); + if (render_state->no_multidraw) { + glDrawElements(GL_TRIANGLE_STRIP, singledraw_indices.second, GL_UNSIGNED_INT, + (void*)(singledraw_indices.first * sizeof(u32))); + } else { + glMultiDrawElements(GL_TRIANGLE_STRIP, + &m_cache.multidraw_count_buffer[multidraw_indices.first], GL_UNSIGNED_INT, + &m_cache.multidraw_index_offset_buffer[multidraw_indices.first], + multidraw_indices.second); + } switch (double_draw.kind) { case DoubleDrawKind::NONE: break; case DoubleDrawKind::AFAIL_NO_DEPTH_WRITE: tree.perf.draws++; - tree.perf.verts += draw_size; prof.add_draw_call(); - prof.add_tri(draw_size); glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::SHRUB].id(), "alpha_min"), -10.f); glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::SHRUB].id(), "alpha_max"), double_draw.aref_second); glDepthMask(GL_FALSE); - glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first], - GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first], - indices.second); + if (render_state->no_multidraw) { + glDrawElements(GL_TRIANGLE_STRIP, singledraw_indices.second, GL_UNSIGNED_INT, + (void*)(singledraw_indices.first * sizeof(u32))); + } else { + glMultiDrawElements( + GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[multidraw_indices.first], + GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[multidraw_indices.first], + multidraw_indices.second); + } break; default: ASSERT(false); diff --git a/game/graphics/opengl_renderer/background/Shrub.h b/game/graphics/opengl_renderer/background/Shrub.h index d330fbb76b..5da8fc17df 100644 --- a/game/graphics/opengl_renderer/background/Shrub.h +++ b/game/graphics/opengl_renderer/background/Shrub.h @@ -30,16 +30,17 @@ class Shrub : public BucketRenderer { struct Tree { GLuint vertex_buffer; GLuint index_buffer; + GLuint single_draw_index_buffer; GLuint time_of_day_texture; GLuint vao; u32 vert_count; const std::vector* draws = nullptr; const std::vector* instance_info = nullptr; const std::vector* colors = nullptr; + const u32* index_data = nullptr; SwizzledTimeOfDay tod_cache; struct { - u32 verts = 0; u32 draws = 0; u32 wind_draws = 0; Filtered cull_time; @@ -62,6 +63,8 @@ class Shrub : public BucketRenderer { bool m_has_level = false; struct Cache { + std::vector> draw_idx_temp; + std::vector index_temp; std::vector> multidraw_offset_per_stripdraw; std::vector multidraw_count_buffer; std::vector multidraw_index_offset_buffer; diff --git a/game/graphics/opengl_renderer/background/Tfrag3.cpp b/game/graphics/opengl_renderer/background/Tfrag3.cpp index 6835fef3df..01906e2156 100644 --- a/game/graphics/opengl_renderer/background/Tfrag3.cpp +++ b/game/graphics/opengl_renderer/background/Tfrag3.cpp @@ -50,6 +50,7 @@ void Tfrag3::update_load(const std::vector& tree_kind size_t vis_temp_len = 0; size_t max_draws = 0; size_t max_num_grps = 0; + size_t max_inds = 0; for (int geom = 0; geom < GEOM_MAX; ++geom) { for (size_t tree_idx = 0; tree_idx < lev_data->tfrag_trees[geom].size(); tree_idx++) { @@ -65,7 +66,7 @@ void Tfrag3::update_load(const std::vector& tree_kind num_grps += draw.vis_groups.size(); } max_num_grps = std::max(max_num_grps, num_grps); - + max_inds = std::max(tree.unpacked.indices.size(), max_inds); time_of_day_count = std::max(tree.colors.size(), time_of_day_count); u32 verts = tree.packed_vertices.vertices.size(); glGenVertexArrays(1, &tree_cache.vao); @@ -76,6 +77,7 @@ void Tfrag3::update_load(const std::vector& tree_kind tree_cache.draws = &tree.draws; // todo - should we just copy this? tree_cache.colors = &tree.colors; tree_cache.vis = &tree.bvh; + tree_cache.index_data = tree.unpacked.indices.data(); tree_cache.tod_cache = swizzle_time_of_day(tree.colors); vis_temp_len = std::max(vis_temp_len, tree.bvh.vis_nodes.size()); glBindBuffer(GL_ARRAY_BUFFER, tree_cache.vertex_buffer); @@ -108,7 +110,7 @@ void Tfrag3::update_load(const std::vector& tree_kind sizeof(tfrag3::PreloadedVertex), // stride (void*)offsetof(tfrag3::PreloadedVertex, color_index) // offset (0) ); - + glGenBuffers(1, &tree_cache.single_draw_index_buffer); glGenBuffers(1, &tree_cache.index_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tree_cache.index_buffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, tree.unpacked.indices.size() * sizeof(u32), @@ -129,7 +131,8 @@ void Tfrag3::update_load(const std::vector& tree_kind m_cache.multidraw_offset_per_stripdraw.resize(max_draws); m_cache.multidraw_count_buffer.resize(max_num_grps); m_cache.multidraw_index_offset_buffer.resize(max_num_grps); - + m_cache.draw_idx_temp.resize(max_draws); + m_cache.index_temp.resize(max_inds); ASSERT(time_of_day_count <= TIME_OF_DAY_COLOR_COUNT); } @@ -191,7 +194,8 @@ void Tfrag3::render_tree(int geom, glBindVertexArray(tree.vao); glBindBuffer(GL_ARRAY_BUFFER, tree.vertex_buffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tree.index_buffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, + render_state->no_multidraw ? tree.single_draw_index_buffer : tree.index_buffer); glActiveTexture(GL_TEXTURE0); glEnable(GL_PRIMITIVE_RESTART); glPrimitiveRestartIndex(UINT32_MAX); @@ -199,18 +203,34 @@ void Tfrag3::render_tree(int geom, cull_check_all_slow(settings.planes, tree.vis->vis_nodes, settings.occlusion_culling, m_cache.vis_temp.data()); - u32 total_tris = make_multidraws_from_vis_string( - m_cache.multidraw_offset_per_stripdraw.data(), m_cache.multidraw_count_buffer.data(), - m_cache.multidraw_index_offset_buffer.data(), *tree.draws, m_cache.vis_temp); + u32 total_tris; + if (render_state->no_multidraw) { + u32 idx_buffer_size = make_index_list_from_vis_string( + m_cache.draw_idx_temp.data(), m_cache.index_temp.data(), *tree.draws, m_cache.vis_temp, + tree.index_data, &total_tris); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size * sizeof(u32), m_cache.index_temp.data(), + GL_STREAM_DRAW); + } else { + total_tris = make_multidraws_from_vis_string( + m_cache.multidraw_offset_per_stripdraw.data(), m_cache.multidraw_count_buffer.data(), + m_cache.multidraw_index_offset_buffer.data(), *tree.draws, m_cache.vis_temp); + } prof.add_tri(total_tris); for (size_t draw_idx = 0; draw_idx < tree.draws->size(); draw_idx++) { const auto& draw = tree.draws->operator[](draw_idx); - const auto& indices = m_cache.multidraw_offset_per_stripdraw[draw_idx]; + const auto& multidraw_indices = m_cache.multidraw_offset_per_stripdraw[draw_idx]; + const auto& singledraw_indices = m_cache.draw_idx_temp[draw_idx]; - if (indices.second == 0) { - continue; + if (render_state->no_multidraw) { + if (singledraw_indices.second == 0) { + continue; + } + } else { + if (multidraw_indices.second == 0) { + continue; + } } ASSERT(m_textures); @@ -218,31 +238,37 @@ void Tfrag3::render_tree(int geom, auto double_draw = setup_tfrag_shader(render_state, draw.mode, ShaderId::TFRAG3); tree.tris_this_frame += draw.num_triangles; tree.draws_this_frame++; - int draw_size = 0; - for (int i = 0; i < indices.second; i++) { - draw_size += m_cache.multidraw_count_buffer[indices.first + i]; - } prof.add_draw_call(); - - glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first], - GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first], - indices.second); + if (render_state->no_multidraw) { + glDrawElements(GL_TRIANGLE_STRIP, singledraw_indices.second, GL_UNSIGNED_INT, + (void*)(singledraw_indices.first * sizeof(u32))); + } else { + glMultiDrawElements(GL_TRIANGLE_STRIP, + &m_cache.multidraw_count_buffer[multidraw_indices.first], GL_UNSIGNED_INT, + &m_cache.multidraw_index_offset_buffer[multidraw_indices.first], + multidraw_indices.second); + } switch (double_draw.kind) { case DoubleDrawKind::NONE: break; case DoubleDrawKind::AFAIL_NO_DEPTH_WRITE: prof.add_draw_call(); - prof.add_tri(draw_size); glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3].id(), "alpha_min"), -10.f); glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3].id(), "alpha_max"), double_draw.aref_second); glDepthMask(GL_FALSE); - glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first], - GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first], - indices.second); + if (render_state->no_multidraw) { + glDrawElements(GL_TRIANGLE_STRIP, singledraw_indices.second, GL_UNSIGNED_INT, + (void*)(singledraw_indices.first * sizeof(u32))); + } else { + glMultiDrawElements( + GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[multidraw_indices.first], + GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[multidraw_indices.first], + multidraw_indices.second); + } break; default: ASSERT(false); @@ -344,7 +370,7 @@ void Tfrag3::discard_tree_cache() { if (tree.kind != tfrag3::TFragmentTreeKind::INVALID) { glBindTexture(GL_TEXTURE_1D, tree.time_of_day_texture); glDeleteTextures(1, &tree.time_of_day_texture); - // glDeleteBuffers(1, &tree.vertex_buffer); + glDeleteBuffers(1, &tree.single_draw_index_buffer); glDeleteBuffers(1, &tree.index_buffer); glDeleteVertexArrays(1, &tree.vao); } diff --git a/game/graphics/opengl_renderer/background/Tfrag3.h b/game/graphics/opengl_renderer/background/Tfrag3.h index e79aad3301..c259342f8f 100644 --- a/game/graphics/opengl_renderer/background/Tfrag3.h +++ b/game/graphics/opengl_renderer/background/Tfrag3.h @@ -60,12 +60,14 @@ class Tfrag3 { tfrag3::TFragmentTreeKind kind; GLuint vertex_buffer = -1; GLuint index_buffer = -1; - GLuint time_of_day_texture; - GLuint vao; + GLuint single_draw_index_buffer = -1; + GLuint time_of_day_texture = -1; + GLuint vao = -1; u32 vert_count = 0; const std::vector* draws = nullptr; const std::vector* colors = nullptr; const tfrag3::BVH* vis = nullptr; + const u32* index_data = nullptr; SwizzledTimeOfDay tod_cache; void reset_stats() { @@ -83,6 +85,8 @@ class Tfrag3 { struct Cache { std::vector vis_temp; + std::vector> draw_idx_temp; + std::vector index_temp; std::vector> multidraw_offset_per_stripdraw; std::vector multidraw_count_buffer; std::vector multidraw_index_offset_buffer; diff --git a/game/graphics/opengl_renderer/background/Tie3.cpp b/game/graphics/opengl_renderer/background/Tie3.cpp index 868bd2f141..5590bf6577 100644 --- a/game/graphics/opengl_renderer/background/Tie3.cpp +++ b/game/graphics/opengl_renderer/background/Tie3.cpp @@ -28,6 +28,7 @@ void Tie3::update_load(const Loader::LevelData* loader_data) { size_t max_num_grps = 0; u16 max_wind_idx = 0; size_t time_of_day_count = 0; + size_t max_inds = 0; for (u32 l_geo = 0; l_geo < tfrag3::TIE_GEOS; l_geo++) { for (u32 l_tree = 0; l_tree < lev_data->tie_trees[l_geo].size(); l_tree++) { size_t wind_idx_buffer_len = 0; @@ -45,6 +46,7 @@ void Tie3::update_load(const Loader::LevelData* loader_data) { max_wind_idx = std::max(max_wind_idx, inst.wind_idx); } time_of_day_count = std::max(tree.colors.size(), time_of_day_count); + max_inds = std::max(tree.unpacked.indices.size(), max_inds); u32 verts = tree.packed_vertices.color_indices.size(); auto& lod_tree = m_trees.at(l_geo); glGenVertexArrays(1, &lod_tree[l_tree].vao); @@ -54,6 +56,7 @@ void Tie3::update_load(const Loader::LevelData* loader_data) { lod_tree[l_tree].draws = &tree.static_draws; lod_tree[l_tree].colors = &tree.colors; lod_tree[l_tree].vis = &tree.bvh; + lod_tree[l_tree].index_data = tree.unpacked.indices.data(); lod_tree[l_tree].instance_info = &tree.wind_instance_info; lod_tree[l_tree].wind_draws = &tree.instanced_wind_draws; vis_temp_len = std::max(vis_temp_len, tree.bvh.vis_nodes.size()); @@ -86,6 +89,7 @@ void Tie3::update_load(const Loader::LevelData* loader_data) { (void*)offsetof(tfrag3::PreloadedVertex, color_index) // offset (0) ); + glGenBuffers(1, &lod_tree[l_tree].single_draw_index_buffer); glGenBuffers(1, &lod_tree[l_tree].index_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lod_tree[l_tree].index_buffer); // todo: move to loader, this will probably be quite slow. @@ -121,6 +125,8 @@ void Tie3::update_load(const Loader::LevelData* loader_data) { m_cache.multidraw_count_buffer.resize(max_num_grps); m_cache.multidraw_index_offset_buffer.resize(max_num_grps); m_wind_vectors.resize(4 * max_wind_idx + 4); // 4x u32's per wind. + m_cache.draw_idx_temp.resize(max_draws); + m_cache.index_temp.resize(max_inds); ASSERT(time_of_day_count <= TIME_OF_DAY_COLOR_COUNT); } @@ -273,6 +279,7 @@ void Tie3::discard_tree_cache() { glBindTexture(GL_TEXTURE_1D, tree.time_of_day_texture); glDeleteTextures(1, &tree.time_of_day_texture); glDeleteBuffers(1, &tree.index_buffer); + glDeleteBuffers(1, &tree.single_draw_index_buffer); glDeleteVertexArrays(1, &tree.vao); } @@ -465,7 +472,6 @@ void Tie3::render_tree_wind(int idx, tree.perf.draws++; tree.perf.wind_draws++; - tree.perf.verts += grp.num; glDrawElements(GL_TRIANGLE_STRIP, grp.num, GL_UNSIGNED_INT, (void*)((off + tree.wind_vertex_index_offsets.at(draw_idx)) * sizeof(u32))); @@ -477,7 +483,6 @@ void Tie3::render_tree_wind(int idx, case DoubleDrawKind::AFAIL_NO_DEPTH_WRITE: tree.perf.draws++; tree.perf.wind_draws++; - tree.perf.verts += grp.num; prof.add_draw_call(); prof.add_tri(grp.num); glUniform1f( @@ -502,15 +507,18 @@ void Tie3::render_tree(int idx, const TfragRenderSettings& settings, SharedRenderState* render_state, ScopedProfilerNode& prof) { + // reset perf Timer tree_timer; auto& tree = m_trees.at(geom).at(idx); tree.perf.draws = 0; - tree.perf.verts = 0; tree.perf.wind_draws = 0; + + // don't render if we haven't loaded if (!m_has_level) { return; } + // update time of day if (m_color_result.size() < tree.colors->size()) { m_color_result.resize(tree.colors->size()); } @@ -529,11 +537,13 @@ void Tie3::render_tree(int idx, glTexSubImage1D(GL_TEXTURE_1D, 0, 0, tree.colors->size(), GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, m_color_result.data()); + // setup OpenGL shader first_tfrag_draw_setup(settings, render_state, ShaderId::TFRAG3); glBindVertexArray(tree.vao); glBindBuffer(GL_ARRAY_BUFFER, tree.vertex_buffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tree.index_buffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, + render_state->no_multidraw ? tree.single_draw_index_buffer : tree.index_buffer); glActiveTexture(GL_TEXTURE0); glEnable(GL_PRIMITIVE_RESTART); glPrimitiveRestartIndex(UINT32_MAX); @@ -541,25 +551,49 @@ void Tie3::render_tree(int idx, int last_texture = -1; - u32 num_tris; - if (m_debug_all_visible) { - tree.perf.cull_time.add(0); - Timer index_timer; - num_tris = make_all_visible_multidraws( - m_cache.multidraw_offset_per_stripdraw.data(), m_cache.multidraw_count_buffer.data(), - m_cache.multidraw_index_offset_buffer.data(), *tree.draws); - tree.perf.index_time.add(index_timer.getSeconds()); - } else { + if (!m_debug_all_visible) { + // need culling data Timer cull_timer; cull_check_all_slow(settings.planes, tree.vis->vis_nodes, settings.occlusion_culling, m_cache.vis_temp.data()); tree.perf.cull_time.add(cull_timer.getSeconds()); + } else { + // no culling. + tree.perf.cull_time.add(0); + } + u32 num_tris; + if (render_state->no_multidraw) { Timer index_timer; - num_tris = make_multidraws_from_vis_string( - m_cache.multidraw_offset_per_stripdraw.data(), m_cache.multidraw_count_buffer.data(), - m_cache.multidraw_index_offset_buffer.data(), *tree.draws, m_cache.vis_temp); + u32 idx_buffer_size; + if (m_debug_all_visible) { + idx_buffer_size = + make_all_visible_index_list(m_cache.draw_idx_temp.data(), m_cache.index_temp.data(), + *tree.draws, tree.index_data, &num_tris); + } else { + idx_buffer_size = make_index_list_from_vis_string( + m_cache.draw_idx_temp.data(), m_cache.index_temp.data(), *tree.draws, m_cache.vis_temp, + tree.index_data, &num_tris); + } + + glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size * sizeof(u32), m_cache.index_temp.data(), + GL_STREAM_DRAW); tree.perf.index_time.add(index_timer.getSeconds()); + + } else { + if (m_debug_all_visible) { + Timer index_timer; + num_tris = make_all_visible_multidraws( + m_cache.multidraw_offset_per_stripdraw.data(), m_cache.multidraw_count_buffer.data(), + m_cache.multidraw_index_offset_buffer.data(), *tree.draws); + tree.perf.index_time.add(index_timer.getSeconds()); + } else { + Timer index_timer; + num_tris = make_multidraws_from_vis_string( + m_cache.multidraw_offset_per_stripdraw.data(), m_cache.multidraw_count_buffer.data(), + m_cache.multidraw_index_offset_buffer.data(), *tree.draws, m_cache.vis_temp); + tree.perf.index_time.add(index_timer.getSeconds()); + } } Timer draw_timer; @@ -567,10 +601,17 @@ void Tie3::render_tree(int idx, for (size_t draw_idx = 0; draw_idx < tree.draws->size(); draw_idx++) { const auto& draw = tree.draws->operator[](draw_idx); - const auto& indices = m_cache.multidraw_offset_per_stripdraw[draw_idx]; + const auto& multidraw_indices = m_cache.multidraw_offset_per_stripdraw[draw_idx]; + const auto& singledraw_indices = m_cache.draw_idx_temp[draw_idx]; - if (indices.second == 0) { - continue; + if (render_state->no_multidraw) { + if (singledraw_indices.second == 0) { + continue; + } + } else { + if (multidraw_indices.second == 0) { + continue; + } } if ((int)draw.tree_tex_id != last_texture) { @@ -579,42 +620,47 @@ void Tie3::render_tree(int idx, } auto double_draw = setup_tfrag_shader(render_state, draw.mode, ShaderId::TFRAG3); - int draw_size = 0; - for (int i = 0; i < indices.second; i++) { - draw_size += m_cache.multidraw_count_buffer[indices.first + i]; - } prof.add_draw_call(); tree.perf.draws++; - tree.perf.verts += draw_size; - glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first], - GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first], - indices.second); + if (render_state->no_multidraw) { + glDrawElements(GL_TRIANGLE_STRIP, singledraw_indices.second, GL_UNSIGNED_INT, + (void*)(singledraw_indices.first * sizeof(u32))); + } else { + glMultiDrawElements(GL_TRIANGLE_STRIP, + &m_cache.multidraw_count_buffer[multidraw_indices.first], GL_UNSIGNED_INT, + &m_cache.multidraw_index_offset_buffer[multidraw_indices.first], + multidraw_indices.second); + } switch (double_draw.kind) { case DoubleDrawKind::NONE: break; case DoubleDrawKind::AFAIL_NO_DEPTH_WRITE: tree.perf.draws++; - tree.perf.verts += draw_size; prof.add_draw_call(); - prof.add_tri(draw_size); glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3].id(), "alpha_min"), -10.f); glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3].id(), "alpha_max"), double_draw.aref_second); glDepthMask(GL_FALSE); - glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first], - GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first], - indices.second); + if (render_state->no_multidraw) { + glDrawElements(GL_TRIANGLE_STRIP, singledraw_indices.second, GL_UNSIGNED_INT, + (void*)(singledraw_indices.first * sizeof(u32))); + } else { + glMultiDrawElements( + GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[multidraw_indices.first], + GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[multidraw_indices.first], + multidraw_indices.second); + } break; default: ASSERT(false); } - if (m_debug_wireframe) { + if (m_debug_wireframe && !render_state->no_multidraw) { render_state->shaders[ShaderId::TFRAG3_NO_TEX].activate(); glUniformMatrix4fv( glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3_NO_TEX].id(), "camera"), 1, @@ -628,12 +674,12 @@ void Tie3::render_tree(int idx, settings.fog.x()); glDisable(GL_BLEND); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glMultiDrawElements(GL_TRIANGLE_STRIP, &m_cache.multidraw_count_buffer[indices.first], - GL_UNSIGNED_INT, &m_cache.multidraw_index_offset_buffer[indices.first], - indices.second); + glMultiDrawElements(GL_TRIANGLE_STRIP, + &m_cache.multidraw_count_buffer[multidraw_indices.first], GL_UNSIGNED_INT, + &m_cache.multidraw_index_offset_buffer[multidraw_indices.first], + multidraw_indices.second); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); prof.add_draw_call(); - prof.add_tri(draw_size); render_state->shaders[ShaderId::TFRAG3].activate(); } } @@ -665,7 +711,7 @@ void Tie3::draw_debug_window() { auto& perf = m_trees[lod()][i].perf; ImGui::Text("Tree: %d", i); ImGui::Text("time of days: %d", (int)m_trees[lod()][i].colors->size()); - ImGui::Text("draw: %d, verts: %d", perf.draws, perf.verts); + ImGui::Text("draw: %d", perf.draws); ImGui::Text("wind draw: %d", perf.wind_draws); ImGui::Text("total: %.2f", perf.tree_time.get()); ImGui::Text("cull: %.2f index: %.2f tod: %.2f setup: %.2f draw: %.2f", diff --git a/game/graphics/opengl_renderer/background/Tie3.h b/game/graphics/opengl_renderer/background/Tie3.h index ede3d5ec68..7da1bc1752 100644 --- a/game/graphics/opengl_renderer/background/Tie3.h +++ b/game/graphics/opengl_renderer/background/Tie3.h @@ -51,6 +51,7 @@ class Tie3 : public BucketRenderer { struct Tree { GLuint vertex_buffer; GLuint index_buffer; + GLuint single_draw_index_buffer; GLuint time_of_day_texture; GLuint vao; u32 vert_count; @@ -59,6 +60,7 @@ class Tie3 : public BucketRenderer { const std::vector* instance_info = nullptr; const std::vector* colors = nullptr; const tfrag3::BVH* vis = nullptr; + const u32* index_data = nullptr; SwizzledTimeOfDay tod_cache; std::vector> wind_matrix_cache; @@ -68,7 +70,6 @@ class Tie3 : public BucketRenderer { std::vector wind_vertex_index_offsets; struct { - u32 verts = 0; u32 draws = 0; u32 wind_draws = 0; Filtered cull_time; @@ -86,6 +87,8 @@ class Tie3 : public BucketRenderer { u64 m_load_id = -1; struct Cache { + std::vector> draw_idx_temp; + std::vector index_temp; std::vector vis_temp; std::vector> multidraw_offset_per_stripdraw; std::vector multidraw_count_buffer; diff --git a/game/graphics/opengl_renderer/background/background_common.cpp b/game/graphics/opengl_renderer/background/background_common.cpp index 0802524176..7326d9863f 100644 --- a/game/graphics/opengl_renderer/background/background_common.cpp +++ b/game/graphics/opengl_renderer/background/background_common.cpp @@ -501,36 +501,6 @@ void make_all_visible_multidraws(std::pair* draw_ptrs_out, } } -u32 make_multidraws_from_vis_string(std::pair* draw_ptrs_out, - GLsizei* counts_out, - void** index_offsets_out, - const std::vector& draws, - const std::vector& vis_data) { - u64 md_idx = 0; - u32 num_tris = 0; - for (size_t i = 0; i < draws.size(); i++) { - const auto& draw = draws[i]; - u64 iidx = draw.unpacked.idx_of_first_idx_in_full_buffer; - std::pair ds; - ds.first = md_idx; - ds.second = 0; - for (auto& grp : draw.vis_groups) { - if (grp.vis_idx_in_pc_bvh == 0xffffffff || vis_data[grp.vis_idx_in_pc_bvh]) { - // visible! - // let's use a multidraw - counts_out[md_idx] = grp.num_inds; - index_offsets_out[md_idx] = (void*)(iidx * sizeof(u32)); - ds.second++; - md_idx++; - num_tris += grp.num_tris; - } - iidx += grp.num_inds; - } - draw_ptrs_out[i] = ds; - } - return num_tris; -} - u32 make_all_visible_multidraws(std::pair* draw_ptrs_out, GLsizei* counts_out, void** index_offsets_out, @@ -557,3 +527,135 @@ u32 make_all_visible_multidraws(std::pair* draw_ptrs_out, } return num_tris; } + +u32 make_all_visible_index_list(std::pair* group_out, + u32* idx_out, + const std::vector& draws, + const u32* idx_in) { + int idx_buffer_ptr = 0; + for (size_t i = 0; i < draws.size(); i++) { + const auto& draw = draws[i]; + std::pair ds; + ds.first = idx_buffer_ptr; + memcpy(&idx_out[idx_buffer_ptr], idx_in + draw.first_index_index, + draw.num_indices * sizeof(u32)); + idx_buffer_ptr += draw.num_indices; + ds.second = idx_buffer_ptr - ds.first; + group_out[i] = ds; + } + return idx_buffer_ptr; +} + +u32 make_multidraws_from_vis_string(std::pair* draw_ptrs_out, + GLsizei* counts_out, + void** index_offsets_out, + const std::vector& draws, + const std::vector& vis_data) { + u64 md_idx = 0; + u32 num_tris = 0; + u32 sanity_check = 0; + for (size_t i = 0; i < draws.size(); i++) { + const auto& draw = draws[i]; + u64 iidx = draw.unpacked.idx_of_first_idx_in_full_buffer; + ASSERT(sanity_check == iidx); + std::pair ds; + ds.first = md_idx; + ds.second = 0; + for (auto& grp : draw.vis_groups) { + sanity_check += grp.num_inds; + if (grp.vis_idx_in_pc_bvh == 0xffffffff || vis_data[grp.vis_idx_in_pc_bvh]) { + // visible! + // let's use a multidraw + counts_out[md_idx] = grp.num_inds; + index_offsets_out[md_idx] = (void*)(iidx * sizeof(u32)); + ds.second++; + md_idx++; + num_tris += grp.num_tris; + } + iidx += grp.num_inds; + } + draw_ptrs_out[i] = ds; + } + return num_tris; +} + +u32 make_index_list_from_vis_string(std::pair* group_out, + u32* idx_out, + const std::vector& draws, + const std::vector& vis_data, + const u32* idx_in, + u32* num_tris_out) { + int idx_buffer_ptr = 0; + u32 num_tris = 0; + for (size_t i = 0; i < draws.size(); i++) { + const auto& draw = draws[i]; + int vtx_idx = 0; + std::pair ds; + ds.first = idx_buffer_ptr; + bool building_run = false; + int run_start_out = 0; + int run_start_in = 0; + for (auto& grp : draw.vis_groups) { + bool vis = grp.vis_idx_in_pc_bvh == 0xffffffff || vis_data[grp.vis_idx_in_pc_bvh]; + if (vis) { + num_tris += grp.num_tris; + } + + if (building_run) { + if (vis) { + idx_buffer_ptr += grp.num_inds; + } else { + building_run = false; + memcpy(&idx_out[run_start_out], + idx_in + draw.unpacked.idx_of_first_idx_in_full_buffer + run_start_in, + (idx_buffer_ptr - run_start_out) * sizeof(u32)); + } + } else { + if (vis) { + building_run = true; + run_start_out = idx_buffer_ptr; + run_start_in = vtx_idx; + idx_buffer_ptr += grp.num_inds; + } + } + vtx_idx += grp.num_inds; + } + + if (building_run) { + memcpy(&idx_out[run_start_out], + idx_in + draw.unpacked.idx_of_first_idx_in_full_buffer + run_start_in, + (idx_buffer_ptr - run_start_out) * sizeof(u32)); + } + + ds.second = idx_buffer_ptr - ds.first; + group_out[i] = ds; + } + *num_tris_out = num_tris; + return idx_buffer_ptr; +} + +u32 make_all_visible_index_list(std::pair* group_out, + u32* idx_out, + const std::vector& draws, + const u32* idx_in, + u32* num_tris_out) { + int idx_buffer_ptr = 0; + u32 num_tris = 0; + for (size_t i = 0; i < draws.size(); i++) { + const auto& draw = draws[i]; + std::pair ds; + ds.first = idx_buffer_ptr; + u32 num_inds = 0; + for (auto& grp : draw.vis_groups) { + num_inds += grp.num_inds; + num_tris += grp.num_tris; + } + memcpy(&idx_out[idx_buffer_ptr], idx_in + draw.unpacked.idx_of_first_idx_in_full_buffer, + num_inds * sizeof(u32)); + idx_buffer_ptr += num_inds; + ds.second = idx_buffer_ptr - ds.first; + group_out[i] = ds; + } + *num_tris_out = num_tris; + return idx_buffer_ptr; +} \ No newline at end of file diff --git a/game/graphics/opengl_renderer/background/background_common.h b/game/graphics/opengl_renderer/background/background_common.h index a648ebe43c..908386dc3f 100644 --- a/game/graphics/opengl_renderer/background/background_common.h +++ b/game/graphics/opengl_renderer/background/background_common.h @@ -74,4 +74,22 @@ u32 make_multidraws_from_vis_string(std::pair* draw_ptrs_out, GLsizei* counts_out, void** index_offsets_out, const std::vector& draws, - const std::vector& vis_data); \ No newline at end of file + const std::vector& vis_data); + +u32 make_all_visible_index_list(std::pair* group_out, + u32* idx_out, + const std::vector& draws, + const u32* idx_in, + u32* num_tris_out); + +u32 make_index_list_from_vis_string(std::pair* group_out, + u32* idx_out, + const std::vector& draws, + const std::vector& vis_data, + const u32* idx_in, + u32* num_tris_out); + +u32 make_all_visible_index_list(std::pair* group_out, + u32* idx_out, + const std::vector& draws, + const u32* idx_in); \ No newline at end of file From 5bd0b735a547620ca143a331004a572abc6ce82d Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Sun, 3 Apr 2022 19:17:03 -0400 Subject: [PATCH 007/172] Add extractor tool (#1276) * first attempt * fix * zip to tar * windows * try again, std::filesystem sucks * std::filesystem is still garbage * std::filesystem is terrible * std::filesystem continues to waste my time * again * neadsflaldksal;df --- .github/workflows/linux-workflow.yaml | 16 +--- common/goos/Reader.cpp | 7 -- common/goos/Reader.h | 1 - common/util/FileUtil.cpp | 93 ++++++++++++++----- common/util/FileUtil.h | 7 +- decompiler/CMakeLists.txt | 11 +++ decompiler/extractor/main.cpp | 129 ++++++++++++++++++++++++++ decompiler/main.cpp | 4 +- game/graphics/pipelines/opengl.cpp | 3 +- game/kernel/kmachine.cpp | 8 ++ game/main.cpp | 4 + game/overlord/fake_iso.cpp | 2 +- goal_src/game.gp | 17 +++- goalc/compiler/Compiler.h | 1 + goalc/main.cpp | 4 +- goalc/make/MakeSystem.cpp | 12 +++ goalc/make/MakeSystem.h | 2 + scripts/shell/extract_build.sh | 28 ++++++ test/offline/offline_test_main.cpp | 21 +++-- test/test_main.cpp | 1 + 20 files changed, 311 insertions(+), 60 deletions(-) create mode 100644 decompiler/extractor/main.cpp create mode 100755 scripts/shell/extract_build.sh diff --git a/.github/workflows/linux-workflow.yaml b/.github/workflows/linux-workflow.yaml index b77a98d1b6..1f4d5dbfb3 100644 --- a/.github/workflows/linux-workflow.yaml +++ b/.github/workflows/linux-workflow.yaml @@ -41,7 +41,7 @@ jobs: run: git submodule update --init --recursive -j 2 - name: Get Common Package Dependencies - run: sudo apt install build-essential cmake clang gcc g++ lcov make nasm libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev + run: sudo apt install build-essential cmake clang gcc g++ lcov make nasm libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev zip - name: Get Clang if: matrix.compiler == 'clang' @@ -100,22 +100,16 @@ jobs: - name: Prepare Build Artifacts if: github.repository == 'open-goal/jak-project' && startsWith(github.ref, 'refs/tags/') && matrix.compiler == 'clang' run: | - mkdir -p ./ci-artifacts/ - cp ./build/decompiler/decompiler ./ci-artifacts/linux-decompiler.bin - cp ./build/game/gk ./ci-artifacts/linux-gk.bin - cp ./build/goalc/goalc ./ci-artifacts/linux-goalc.bin - chmod +x ./ci-artifacts/*.bin - strip --strip-debug ./ci-artifacts/linux-decompiler.bin - strip --strip-debug ./ci-artifacts/linux-gk.bin - strip --strip-debug ./ci-artifacts/linux-goalc.bin - ls -l ./ci-artifacts/ + mkdir -p ./ci-artifacts/out + ./scripts/shell/extract_build.sh ./ci-artifacts/out ./ + tar czf ./ci-artifacts/opengoal.tar.gz ./ci-artifacts/out - name: Upload Assets and Potential Publish Release if: github.repository == 'open-goal/jak-project' && startsWith(github.ref, 'refs/tags/') && matrix.compiler == 'clang' env: GITHUB_TOKEN: ${{ secrets.BOT_PAT }} ASSET_DIR: ${{ github.WORKSPACE }}/ci-artifacts - ASSET_EXTENSION: bin + ASSET_EXTENSION: zip TAG_TO_SEARCH_FOR: ${{ github.REF }} run: | cd ./.github/scripts/releases/upload-release-artifacts diff --git a/common/goos/Reader.cpp b/common/goos/Reader.cpp index 2ff07bc453..54a3567375 100644 --- a/common/goos/Reader.cpp +++ b/common/goos/Reader.cpp @@ -835,13 +835,6 @@ void Reader::throw_reader_error(TextStream& here, const std::string& err, int se db.get_info_for(here.text, here.seek + seek_offset)); } -/*! - * Get the source directory of the current project. - */ -std::string Reader::get_source_dir() { - return file_util::get_project_path(); -} - /*! * Convert any string into one that can be read. * Unprintable characters become escape sequences, including tab and newline. diff --git a/common/goos/Reader.h b/common/goos/Reader.h index efe29b676d..357ff52d38 100644 --- a/common/goos/Reader.h +++ b/common/goos/Reader.h @@ -78,7 +78,6 @@ class Reader { std::optional read_from_stdin(const std::string& prompt, ReplWrapper& repl); Object read_from_file(const std::vector& file_path, bool check_encoding = false); bool check_string_is_valid(const std::string& str) const; - std::string get_source_dir(); SymbolTable symbolTable; TextDb db; diff --git a/common/util/FileUtil.cpp b/common/util/FileUtil.cpp index 2889e5a566..ece3fc595b 100644 --- a/common/util/FileUtil.cpp +++ b/common/util/FileUtil.cpp @@ -56,14 +56,19 @@ std::filesystem::path get_user_memcard_dir() { return get_user_game_dir() / "jak1" / "saves"; } -std::string get_project_path() { +struct { + bool initialized = false; + std::filesystem::path path_to_data; +} gFilePathInfo; + +/*! + * Get the path to the current executable. + */ +std::string get_current_executable_path() { #ifdef _WIN32 char buffer[FILENAME_MAX]; GetModuleFileNameA(NULL, buffer, FILENAME_MAX); - std::string::size_type pos = - std::string(buffer).rfind("jak-project"); // Strip file path down to \jak-project\ directory - return std::string(buffer).substr( - 0, pos + 11); // + 12 to include "\jak-project" in the returned filepath + return std::string(buffer); #else // do Linux stuff char buffer[FILENAME_MAX + 1]; @@ -71,13 +76,66 @@ std::string get_project_path() { FILENAME_MAX); // /proc/self acts like a "virtual folder" containing // information about the current process buffer[len] = '\0'; - std::string::size_type pos = - std::string(buffer).rfind("jak-project"); // Strip file path down to /jak-project/ directory - return std::string(buffer).substr( - 0, pos + 11); // + 12 to include "/jak-project" in the returned filepath + return std::string(buffer); #endif } +/*! + * See if the current executable is somewhere in jak-project/. If so, return the path to jak-project + */ +std::optional try_get_jak_project_path() { + std::string my_path = get_current_executable_path(); + + std::string::size_type pos = + std::string(my_path).rfind("jak-project"); // Strip file path down to /jak-project/ directory + if (pos == std::string::npos) { + return {}; + } + + return std::string(my_path).substr( + 0, pos + 11); // + 12 to include "/jak-project" in the returned filepath +} + +std::optional try_get_data_dir() { + std::filesystem::path my_path = get_current_executable_path(); + auto data_dir = my_path.parent_path() / "data"; + if (std::filesystem::exists(data_dir) && std::filesystem::is_directory(data_dir)) { + return data_dir; + } else { + return {}; + } +} + +bool setup_project_path() { + if (gFilePathInfo.initialized) { + return true; + } + + auto data_path = try_get_data_dir(); + if (data_path) { + gFilePathInfo.path_to_data = *data_path; + gFilePathInfo.initialized = true; + fmt::print("Using data path: {}\n", data_path->string()); + return true; + } + + auto development_repo_path = try_get_jak_project_path(); + if (development_repo_path) { + gFilePathInfo.path_to_data = *development_repo_path; + gFilePathInfo.initialized = true; + fmt::print("Using development repo path: {}\n", *development_repo_path); + return true; + } + + fmt::print("Failed to initialize project path.\n"); + return false; +} + +std::filesystem::path get_jak_project_dir() { + ASSERT(gFilePathInfo.initialized); + return gFilePathInfo.path_to_data; +} + std::string get_file_path(const std::vector& input) { // TODO - clean this behaviour up, it causes unexpected behaviour when working with files // the project path should be explicitly provided by whatever if needed @@ -87,21 +145,12 @@ std::string get_file_path(const std::vector& input) { return input.at(0); } - std::string currentPath = file_util::get_project_path(); - char dirSeparator; - -#ifdef _WIN32 - dirSeparator = '\\'; -#else - dirSeparator = '/'; -#endif - - std::string filePath = currentPath; - for (int i = 0; i < int(input.size()); i++) { - filePath = filePath + dirSeparator + input[i]; + auto current_path = file_util::get_jak_project_dir(); + for (auto& str : input) { + current_path /= str; } - return filePath; + return current_path.string(); } bool create_dir_if_needed(const std::string& path) { diff --git a/common/util/FileUtil.h b/common/util/FileUtil.h index 35b2806ebd..b829ef5be9 100644 --- a/common/util/FileUtil.h +++ b/common/util/FileUtil.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "common/common_types.h" namespace fs = std::filesystem; @@ -17,12 +18,12 @@ std::filesystem::path get_user_home_dir(); std::filesystem::path get_user_game_dir(); std::filesystem::path get_user_settings_dir(); std::filesystem::path get_user_memcard_dir(); -std::string get_project_path(); -std::string get_file_path(const std::vector& input); +std::filesystem::path get_jak_project_dir(); bool create_dir_if_needed(const std::string& path); bool create_dir_if_needed_for_file(const std::string& path); - +bool setup_project_path(); +std::string get_file_path(const std::vector& path); void write_binary_file(const std::string& name, const void* data, size_t size); void write_rgba_png(const std::string& name, void* data, int w, int h); void write_text_file(const std::string& file_name, const std::string& text); diff --git a/decompiler/CMakeLists.txt b/decompiler/CMakeLists.txt index 8cd6ddd378..0e326b9bd5 100644 --- a/decompiler/CMakeLists.txt +++ b/decompiler/CMakeLists.txt @@ -93,3 +93,14 @@ target_link_libraries(decompiler common lzokay fmt) + + +add_executable(extractor + extractor/main.cpp) + +target_link_libraries(extractor + decomp + common + lzokay + fmt + compiler) diff --git a/decompiler/extractor/main.cpp b/decompiler/extractor/main.cpp new file mode 100644 index 0000000000..110f9a78d9 --- /dev/null +++ b/decompiler/extractor/main.cpp @@ -0,0 +1,129 @@ +#include "third-party/fmt/core.h" +#include "common/util/FileUtil.h" +#include "decompiler/Disasm/OpcodeInfo.h" +#include "decompiler/ObjectFile/ObjectFileDB.h" +#include "decompiler/level_extractor/extract_level.h" +#include "decompiler/config.h" +#include "goalc/compiler/Compiler.h" + +void setup_global_decompiler_stuff() { + file_util::init_crc(); + decompiler::init_opcode_info(); + file_util::setup_project_path(); +} + +int main(int argc, char** argv) { + using namespace decompiler; + fmt::print("OpenGOAL Level Extraction Tool\n"); + if (argc != 2) { + fmt::print(" usage: extractor \n"); + return 1; + } + + // todo: print revision here. + setup_global_decompiler_stuff(); + + std::filesystem::path jak1_input_files(argv[1]); + // make sure the input looks right + if (!std::filesystem::exists(jak1_input_files)) { + fmt::print("Error: input folder {} does not exist\n", jak1_input_files.string()); + return 1; + } + + if (!std::filesystem::is_directory(jak1_input_files)) { + fmt::print("Error: input folder {} is not a folder.\n", jak1_input_files.string()); + return 1; + } + + if (!std::filesystem::exists(jak1_input_files / "DGO")) { + fmt::print("Error: input folder doesn't have a DGO folder. Is this the right input?\n"); + return 1; + } + + Config config = read_config_file( + (file_util::get_jak_project_dir() / "decompiler" / "config" / "jak1_ntsc_black_label.jsonc") + .string(), + {}); + + std::vector dgos, objs; + + // grab all DGOS we need (level + common) + for (const auto& dgo_name : config.dgo_names) { + std::string common_name = "GAME.CGO"; + if (dgo_name.length() > 3 && dgo_name.substr(dgo_name.length() - 3) == "DGO") { + // ends in DGO, it's a level + dgos.push_back((jak1_input_files / dgo_name).string()); + } else if (dgo_name.length() >= common_name.length() && + dgo_name.substr(dgo_name.length() - common_name.length()) == common_name) { + // it's COMMON.CGO, we need that too. + dgos.push_back((jak1_input_files / dgo_name).string()); + } + } + + // grab all the object files we need (just text) + for (const auto& obj_name : config.object_file_names) { + if (obj_name.length() > 3 && obj_name.substr(obj_name.length() - 3) == "TXT") { + // ends in DGO, it's a level + objs.push_back((jak1_input_files / obj_name).string()); + } + } + + // set up objects + ObjectFileDB db(dgos, config.obj_file_name_map_file, objs, {}, config); + + // save object files + auto out_folder = (file_util::get_jak_project_dir() / "decompiler_out" / "jak1").string(); + auto raw_obj_folder = file_util::combine_path(out_folder, "raw_obj"); + file_util::create_dir_if_needed(raw_obj_folder); + db.dump_raw_objects(raw_obj_folder); + + // analyze object file link data + db.process_link_data(config); + db.find_code(config); + db.process_labels(); + + // text files + { + auto result = db.process_game_text_files(config); + if (!result.empty()) { + file_util::write_text_file(file_util::get_file_path({"assets", "game_text.txt"}), result); + } + } + + // textures + decompiler::TextureDB tex_db; + file_util::write_text_file(file_util::get_file_path({"assets", "tpage-dir.txt"}), + db.process_tpages(tex_db)); + // texture replacements + auto replacements_path = file_util::get_file_path({"texture_replacements"}); + if (std::filesystem::exists(replacements_path)) { + tex_db.replace_textures(replacements_path); + } + + // game count + { + auto result = db.process_game_count_file(); + if (!result.empty()) { + file_util::write_text_file(file_util::get_file_path({"assets", "game_count.txt"}), result); + } + } + + // levels + { + extract_common(db, tex_db, "GAME.CGO"); + for (auto& lev : config.levels_to_extract) { + extract_from_level(db, tex_db, lev, config.hacks, config.rip_levels); + } + } + + // Compile! + Compiler compiler; + compiler.make_system().set_constant("*iso-data*", jak1_input_files.string()); + compiler.make_system().set_constant("*use-iso-data-path*", true); + + compiler.make_system().load_project_file( + (file_util::get_jak_project_dir() / "goal_src" / "game.gp").string()); + compiler.run_front_end_on_string("(mi)"); + + system((file_util::get_jak_project_dir() / "../gk").string().c_str()); +} \ No newline at end of file diff --git a/decompiler/main.cpp b/decompiler/main.cpp index ebcf610a66..46240f0129 100644 --- a/decompiler/main.cpp +++ b/decompiler/main.cpp @@ -13,9 +13,11 @@ #include "common/util/diff.h" int main(int argc, char** argv) { - fmt::print("[Mem] Size of linked word: {}\n", sizeof(decompiler::LinkedWord)); fmt::print("[Mem] Top of main: {} MB\n", get_peak_rss() / (1024 * 1024)); using namespace decompiler; + if (!file_util::setup_project_path()) { + return 1; + } lg::set_file(file_util::get_file_path({"log/decompiler.txt"})); lg::set_file_level(lg::level::info); lg::set_stdout_level(lg::level::info); diff --git a/game/graphics/pipelines/opengl.cpp b/game/graphics/pipelines/opengl.cpp index fc39ebaf91..ade6f5c909 100644 --- a/game/graphics/pipelines/opengl.cpp +++ b/game/graphics/pipelines/opengl.cpp @@ -156,7 +156,8 @@ static std::shared_ptr gl_make_main_display(int width, return NULL; } - std::string image_path = fmt::format("{}/game/assets/appicon.png", file_util::get_project_path()); + std::string image_path = + (file_util::get_jak_project_dir() / "game" / "assets" / "appicon.png").string(); GLFWimage images[1]; images[0].pixels = diff --git a/game/kernel/kmachine.cpp b/game/kernel/kmachine.cpp index 588384507c..e323127485 100644 --- a/game/kernel/kmachine.cpp +++ b/game/kernel/kmachine.cpp @@ -81,6 +81,14 @@ void kmachine_init_globals() { * Modified to use std::string, and removed call to fflush. */ void InitParms(int argc, const char* const* argv) { + // Modified default settings: + if (argc == 1) { + DiskBoot = 1; + isodrv = fakeiso; + modsrc = 0; + reboot = 0; + } + for (int i = 1; i < argc; i++) { std::string arg = argv[i]; // DVD Settings diff --git a/game/main.cpp b/game/main.cpp index 93b44ba7ce..c875dad4ec 100644 --- a/game/main.cpp +++ b/game/main.cpp @@ -50,6 +50,10 @@ int main(int argc, char** argv) { } } + if (!file_util::setup_project_path()) { + return 1; + } + gStartTime = time(0); init_discord_rpc(); diff --git a/game/overlord/fake_iso.cpp b/game/overlord/fake_iso.cpp index 9b137001e5..47bbe1c9d5 100644 --- a/game/overlord/fake_iso.cpp +++ b/game/overlord/fake_iso.cpp @@ -147,7 +147,7 @@ FileRecord* FS_FindIN(const char* iso_name) { static const char* get_file_path(FileRecord* fr) { ASSERT(fr->location < fake_iso_entry_count); static char path_buffer[1024]; - strcpy(path_buffer, file_util::get_project_path().c_str()); + strcpy(path_buffer, file_util::get_jak_project_dir().string().c_str()); strcat(path_buffer, "/"); strcat(path_buffer, fake_iso_entries[fr->location].file_path); return path_buffer; diff --git a/goal_src/game.gp b/goal_src/game.gp index f8ccbc94bc..2a75dfb9a0 100644 --- a/goal_src/game.gp +++ b/goal_src/game.gp @@ -131,8 +131,15 @@ ) ) +(defun get-iso-data-path () + (if *use-iso-data-path* + (string-append *iso-data* "/") + (string-append "iso_data/" *game-directory* "/") + ) + ) + (defun copy-iso-file (name subdir ext) - (let* ((path (string-append "iso_data/" *game-directory* subdir name ext)) + (let* ((path (string-append (get-iso-data-path) subdir name ext)) (out-name (string-append "out/iso/" name ext))) (defstep :in path :tool 'copy @@ -222,22 +229,22 @@ ) ;; the TWEAKVAL file -(defstep :in (string-append "iso_data/" *game-directory* "MUS/TWEAKVAL.MUS") +(defstep :in (string-append (get-iso-data-path) "MUS/TWEAKVAL.MUS") :tool 'copy :out '("out/iso/TWEAKVAL.MUS")) ;; the VAGDIR file -(defstep :in (string-append "iso_data/" *game-directory* "VAG/VAGDIR.AYB") +(defstep :in (string-append (get-iso-data-path) "VAG/VAGDIR.AYB") :tool 'copy :out '("out/iso/VAGDIR.AYB")) ;; the save icon file -(defstep :in (string-append "iso_data/" *game-directory* "DRIVERS/SAVEGAME.ICO") +(defstep :in (string-append (get-iso-data-path) "DRIVERS/SAVEGAME.ICO") :tool 'copy :out '("out/iso/SAVEGAME.ICO")) ;; the loading screen file -(defstep :in (string-append "iso_data/" *game-directory* "DRIVERS/SCREEN1.USA") +(defstep :in (string-append (get-iso-data-path) "DRIVERS/SCREEN1.USA") :tool 'copy :out '("out/iso/SCREEN1.USA")) diff --git a/goalc/compiler/Compiler.h b/goalc/compiler/Compiler.h index a23f100c50..51d70a93fd 100644 --- a/goalc/compiler/Compiler.h +++ b/goalc/compiler/Compiler.h @@ -66,6 +66,7 @@ class Compiler { Replxx::colors_t& colors, std::vector> const& user_data); bool knows_object_file(const std::string& name); + MakeSystem& make_system() { return m_make; } private: TypeSystem m_ts; diff --git a/goalc/main.cpp b/goalc/main.cpp index a49c1ae526..395e434674 100644 --- a/goalc/main.cpp +++ b/goalc/main.cpp @@ -26,7 +26,9 @@ void setup_logging(bool verbose) { int main(int argc, char** argv) { (void)argc; (void)argv; - + if (!file_util::setup_project_path()) { + return 1; + } std::string argument; std::string username = "#f"; bool verbose = false; diff --git a/goalc/make/MakeSystem.cpp b/goalc/make/MakeSystem.cpp index 0173815e8a..75d282d41d 100644 --- a/goalc/make/MakeSystem.cpp +++ b/goalc/make/MakeSystem.cpp @@ -9,6 +9,7 @@ #include "common/util/Timer.h" #include "goalc/make/Tools.h" +#include "common/util/FileUtil.h" std::string MakeStep::print() const { std::string result = fmt::format("Tool {} with inputs", tool); @@ -55,6 +56,9 @@ MakeSystem::MakeSystem() { m_goos.set_global_variable_to_symbol("ASSETS", "#t"); + set_constant("*iso-data*", file_util::get_file_path({"iso_data"})); + set_constant("*use-iso-data-path*", false); + add_tool(); add_tool(); add_tool(); @@ -365,3 +369,11 @@ bool MakeSystem::make(const std::string& target, bool force, bool verbose) { make_timer.getSeconds()); return true; } + +void MakeSystem::set_constant(const std::string& name, const std::string& value) { + m_goos.set_global_variable_by_name(name, goos::StringObject::make_new(value)); +} + +void MakeSystem::set_constant(const std::string& name, bool value) { + m_goos.set_global_variable_to_symbol(name, value ? "#t" : "#f"); +} \ No newline at end of file diff --git a/goalc/make/MakeSystem.h b/goalc/make/MakeSystem.h index 4231e90a9e..ad96d5fefd 100644 --- a/goalc/make/MakeSystem.h +++ b/goalc/make/MakeSystem.h @@ -35,6 +35,8 @@ class MakeSystem { bool make(const std::string& target, bool force, bool verbose); void add_tool(std::shared_ptr tool); + void set_constant(const std::string& name, const std::string& value); + void set_constant(const std::string& name, bool value); template void add_tool() { diff --git a/scripts/shell/extract_build.sh b/scripts/shell/extract_build.sh new file mode 100755 index 0000000000..d92bfb85a6 --- /dev/null +++ b/scripts/shell/extract_build.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +set -e + +DEST=${1} +SOURCE=${2} + +mkdir -p $DEST + +cp $SOURCE/build/game/gk $DEST +cp $SOURCE/build/goalc/goalc $DEST +cp $SOURCE/build/decompiler/extractor $DEST + +strip $DEST/gk +strip $DEST/goalc +strip $DEST/extractor + +mkdir -p $DEST/data +mkdir -p $DEST/data/decompiler/ +mkdir -p $DEST/data/assets +mkdir -p $DEST/data/game +mkdir -p $DEST/data/log +mkdir -p $DEST/data/game/graphics/opengl_renderer/ + +cp -r $SOURCE/decompiler/config $DEST/data/decompiler/ +cp -r $SOURCE/goal_src $DEST/data +cp -r $SOURCE/game/assets $DEST/data/game/ +cp -r $SOURCE/game/graphics/opengl_renderer/shaders $DEST/data/game/graphics/opengl_renderer \ No newline at end of file diff --git a/test/offline/offline_test_main.cpp b/test/offline/offline_test_main.cpp index b51c9995ed..2641731d2f 100644 --- a/test/offline/offline_test_main.cpp +++ b/test/offline/offline_test_main.cpp @@ -65,8 +65,9 @@ struct OfflineTestConfig { * Read and parse the json config file, config.json, located in test/offline */ OfflineTestConfig parse_config() { - auto json_file_path = file_util::get_file_path({"test", "offline", "config.jsonc"}); - auto json = parse_commented_json(file_util::read_text_file(json_file_path), json_file_path); + auto json_file_path = file_util::get_jak_project_dir() / "test" / "offline" / "config.jsonc"; + auto json = parse_commented_json(file_util::read_text_file(json_file_path.string()), + json_file_path.string()); OfflineTestConfig result; result.dgos = json["dgos"].get>(); result.skip_compile_files = json["skip_compile_files"].get>(); @@ -98,8 +99,8 @@ std::vector find_files(const std::vector& dgos) { std::vector result; std::unordered_map files_with_ref; - for (auto& p : fs::recursive_directory_iterator( - file_util::get_file_path({"test", "decompiler", "reference"}))) { + for (auto& p : fs::recursive_directory_iterator(file_util::get_jak_project_dir() / "test" / + "decompiler" / "reference")) { if (p.is_regular_file()) { std::string file_name = fs::path(p.path()).replace_extension().filename().string(); if (file_name.find("_REF") == std::string::npos) { @@ -114,7 +115,8 @@ std::vector find_files(const std::vector& dgos) { // use the all_objs.json file to place them in the correct build order auto j = parse_commented_json( - file_util::read_text_file(file_util::get_file_path({"goal_src", "build", "all_objs.json"})), + file_util::read_text_file( + (file_util::get_jak_project_dir() / "goal_src" / "build" / "all_objs.json").string()), "all_objs.json"); std::unordered_set matched_files; @@ -180,7 +182,9 @@ Decompiler setup_decompiler(const std::vector& files, file_util::init_crc(); decompiler::init_opcode_info(); dc.config = std::make_unique(decompiler::read_config_file( - file_util::get_file_path({"decompiler", "config", "jak1_ntsc_black_label.jsonc"}), {})); + (file_util::get_jak_project_dir() / "decompiler" / "config" / "jak1_ntsc_black_label.jsonc") + .string(), + {})); // modify the config std::unordered_set object_files; @@ -195,7 +199,7 @@ Decompiler setup_decompiler(const std::vector& files, std::vector dgo_paths; if (args.iso_data_path.empty()) { for (auto& x : offline_config.dgos) { - dgo_paths.push_back(file_util::get_file_path({"iso_data/jak1", x})); + dgo_paths.push_back((file_util::get_jak_project_dir() / "iso_data" / "jak1").string()); } } else { for (auto& x : offline_config.dgos) { @@ -343,6 +347,9 @@ bool compile(Decompiler& dc, int main(int argc, char* argv[]) { fmt::print("Offline Decompiler Test 2\n"); lg::initialize(); + if (!file_util::setup_project_path()) { + return 1; + } fmt::print("Reading config...\n"); auto args = parse_args(argc, argv); diff --git a/test/test_main.cpp b/test/test_main.cpp index b912fd6235..9a3ba4a4bd 100644 --- a/test/test_main.cpp +++ b/test/test_main.cpp @@ -20,6 +20,7 @@ int main(int argc, char** argv) { // hopefully get a debug print on github actions setup_cpu_info(); + file_util::setup_project_path(); lg::initialize(); ::testing::InitGoogleTest(&argc, argv); From 8e71184daf844de0a0ee19ee61d2fcfb09603cf3 Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Sun, 3 Apr 2022 19:44:25 -0400 Subject: [PATCH 008/172] rename linux artifact (#1277) * rename linux artifact * just linux --- .github/scripts/releases/upload-release-artifacts/index.js | 4 +--- .github/workflows/linux-workflow.yaml | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/scripts/releases/upload-release-artifacts/index.js b/.github/scripts/releases/upload-release-artifacts/index.js index 57cf2f38ea..be7b65f0e0 100644 --- a/.github/scripts/releases/upload-release-artifacts/index.js +++ b/.github/scripts/releases/upload-release-artifacts/index.js @@ -114,9 +114,7 @@ let expectedAssets = { "windows-decompiler": false, "windows-gk": false, "windows-goalc": false, - "linux-decompiler": false, - "linux-gk": false, - "linux-goalc": false, + "linux" : false, } for (var i = 0; i < releaseAssetsPost.length; i++) { diff --git a/.github/workflows/linux-workflow.yaml b/.github/workflows/linux-workflow.yaml index 1f4d5dbfb3..923da57237 100644 --- a/.github/workflows/linux-workflow.yaml +++ b/.github/workflows/linux-workflow.yaml @@ -102,14 +102,14 @@ jobs: run: | mkdir -p ./ci-artifacts/out ./scripts/shell/extract_build.sh ./ci-artifacts/out ./ - tar czf ./ci-artifacts/opengoal.tar.gz ./ci-artifacts/out + tar czf ./ci-artifacts/linux.tar.gz ./ci-artifacts/out - name: Upload Assets and Potential Publish Release if: github.repository == 'open-goal/jak-project' && startsWith(github.ref, 'refs/tags/') && matrix.compiler == 'clang' env: GITHUB_TOKEN: ${{ secrets.BOT_PAT }} ASSET_DIR: ${{ github.WORKSPACE }}/ci-artifacts - ASSET_EXTENSION: zip + ASSET_EXTENSION: gz TAG_TO_SEARCH_FOR: ${{ github.REF }} run: | cd ./.github/scripts/releases/upload-release-artifacts From dba95660ea4fa8ed84f06793f87bc4f3f8c22fb8 Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Mon, 4 Apr 2022 20:50:08 -0400 Subject: [PATCH 009/172] release: fix windows artifacts and stop building asan when releasing on linux (#1283) * release: fix windows artifacts and stop building asan when releasing on linux * release: use valid paths in the container's context --- .../scripts/releases/extract_build_linux.sh | 0 .../scripts/releases/extract_build_windows.sh | 24 +++++++++++++++++++ .../upload-release-artifacts/index.js | 4 +--- .github/workflows/linux-workflow.yaml | 18 +++++++++++--- .github/workflows/windows-workflow.yaml | 11 ++++----- .gitignore | 1 + CMakeLists.txt | 2 +- 7 files changed, 47 insertions(+), 13 deletions(-) rename scripts/shell/extract_build.sh => .github/scripts/releases/extract_build_linux.sh (100%) create mode 100755 .github/scripts/releases/extract_build_windows.sh diff --git a/scripts/shell/extract_build.sh b/.github/scripts/releases/extract_build_linux.sh similarity index 100% rename from scripts/shell/extract_build.sh rename to .github/scripts/releases/extract_build_linux.sh diff --git a/.github/scripts/releases/extract_build_windows.sh b/.github/scripts/releases/extract_build_windows.sh new file mode 100755 index 0000000000..c89efb8cf5 --- /dev/null +++ b/.github/scripts/releases/extract_build_windows.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +set -e + +DEST=${1} +SOURCE=${2} + +mkdir -p $DEST + +cp $SOURCE/build/bin/gk.exe $DEST +cp $SOURCE/build/bin/goalc.exe $DEST +cp $SOURCE/build/bin/extractor.exe $DEST + +mkdir -p $DEST/data +mkdir -p $DEST/data/decompiler/ +mkdir -p $DEST/data/assets +mkdir -p $DEST/data/game +mkdir -p $DEST/data/log +mkdir -p $DEST/data/game/graphics/opengl_renderer/ + +cp -r $SOURCE/decompiler/config $DEST/data/decompiler/ +cp -r $SOURCE/goal_src $DEST/data +cp -r $SOURCE/game/assets $DEST/data/game/ +cp -r $SOURCE/game/graphics/opengl_renderer/shaders $DEST/data/game/graphics/opengl_renderer diff --git a/.github/scripts/releases/upload-release-artifacts/index.js b/.github/scripts/releases/upload-release-artifacts/index.js index be7b65f0e0..c8bd86ad4d 100644 --- a/.github/scripts/releases/upload-release-artifacts/index.js +++ b/.github/scripts/releases/upload-release-artifacts/index.js @@ -111,9 +111,7 @@ const { data: releaseAssetsPost } = await octokit.rest.repos.listReleaseAssets({ // Expected Assets, if we have all of them, we will publish it let expectedAssets = { - "windows-decompiler": false, - "windows-gk": false, - "windows-goalc": false, + "windows": false, "linux" : false, } diff --git a/.github/workflows/linux-workflow.yaml b/.github/workflows/linux-workflow.yaml index 923da57237..d5dc0e570b 100644 --- a/.github/workflows/linux-workflow.yaml +++ b/.github/workflows/linux-workflow.yaml @@ -53,7 +53,7 @@ jobs: cache_key: ${{ matrix.os }}-${{ matrix.compiler }} - name: CMake Generation - Clang - if: matrix.compiler == 'clang' + if: matrix.compiler == 'clang' && !startsWith(github.ref, 'refs/tags/') run: | export CC=clang export CXX=clang++ @@ -64,6 +64,18 @@ jobs: -DCMAKE_CXX_COMPILER_LAUNCHER="${{ github.workspace }}"/buildcache/bin/buildcache \ -DCODE_COVERAGE=ON -DASAN_BUILD=ON + - name: CMake Generation - Clang - No ASAN + if: matrix.compiler == 'clang' && startsWith(github.ref, 'refs/tags/') + run: | + export CC=clang + export CXX=clang++ + cmake -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_FOR_RELEASE=ON \ + -DCMAKE_C_COMPILER_LAUNCHER="${{ github.workspace }}"/buildcache/bin/buildcache \ + -DCMAKE_CXX_COMPILER_LAUNCHER="${{ github.workspace }}"/buildcache/bin/buildcache \ + -DCODE_COVERAGE=ON -DASAN_BUILD=OFF + - name: CMake Generation - GCC if: matrix.compiler == 'gcc' run: | @@ -88,7 +100,7 @@ jobs: run: ./test_code_coverage.sh - name: Submit Coverage Report to Codacy - if: ${{ matrix.compiler }} == 'gcc' + if: matrix.compiler == 'gcc' uses: codacy/codacy-coverage-reporter-action@v1 continue-on-error: true with: @@ -101,7 +113,7 @@ jobs: if: github.repository == 'open-goal/jak-project' && startsWith(github.ref, 'refs/tags/') && matrix.compiler == 'clang' run: | mkdir -p ./ci-artifacts/out - ./scripts/shell/extract_build.sh ./ci-artifacts/out ./ + ./.github/scripts/releases/extract_build_linux.sh ./ci-artifacts/out ./ tar czf ./ci-artifacts/linux.tar.gz ./ci-artifacts/out - name: Upload Assets and Potential Publish Release diff --git a/.github/workflows/windows-workflow.yaml b/.github/workflows/windows-workflow.yaml index 8f8f24f040..bd05aaac15 100644 --- a/.github/workflows/windows-workflow.yaml +++ b/.github/workflows/windows-workflow.yaml @@ -81,19 +81,18 @@ jobs: # ---- Release / Tagging related steps ---- - name: Prepare Build Artifacts if: github.repository == 'open-goal/jak-project' && startsWith(github.ref, 'refs/tags/') && matrix.compiler == 'clang' + shell: bash run: | - mkdir -p ./ci-artifacts/ - cp ./build/bin/decompiler.exe ./ci-artifacts/windows-decompiler.exe - cp ./build/bin/gk.exe ./ci-artifacts/windows-gk.exe - cp ./build/bin/goalc.exe ./ci-artifacts/windows-goalc.exe - ls ./ci-artifacts/ + mkdir -p ./ci-artifacts/out + ./.github/scripts/releases/extract_build_windows.sh ./ci-artifacts/out ./ + zip -r ./ci-artifacts/windows.zip ./ci-artfacts/out - name: Upload Assets and Potential Publish Release if: github.repository == 'open-goal/jak-project' && startsWith(github.ref, 'refs/tags/') && matrix.compiler == 'clang' env: GITHUB_TOKEN: ${{ secrets.BOT_PAT }} ASSET_DIR: ${{ github.WORKSPACE }}/ci-artifacts - ASSET_EXTENSION: exe + ASSET_EXTENSION: zip TAG_TO_SEARCH_FOR: ${{ github.REF }} run: | cd ./.github/scripts/releases/upload-release-artifacts diff --git a/.gitignore b/.gitignore index dcf0cd6b67..1ea801c871 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,4 @@ texture_replacements/* # generated cmake files svnrev.h +ci-artifacts/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 69e689aea1..cdbcc6e5d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,7 +70,7 @@ elseif(MSVC) endif() # c++ flags for all build types set(CMAKE_CXX_FLAGS "/EHsc /utf-8 /arch:AVX") - + # linker flags set(CMAKE_EXE_LINKER_FLAGS "/STACK:16000000,16384") endif() From 79f255bcc16e4cb79133340679a48f1f906360f9 Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Mon, 4 Apr 2022 21:24:52 -0400 Subject: [PATCH 010/172] release: switch to `7z` on windows because it doesnt have `zip` (#1284) --- .github/workflows/windows-workflow.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows-workflow.yaml b/.github/workflows/windows-workflow.yaml index bd05aaac15..3f4d5ec071 100644 --- a/.github/workflows/windows-workflow.yaml +++ b/.github/workflows/windows-workflow.yaml @@ -85,7 +85,7 @@ jobs: run: | mkdir -p ./ci-artifacts/out ./.github/scripts/releases/extract_build_windows.sh ./ci-artifacts/out ./ - zip -r ./ci-artifacts/windows.zip ./ci-artfacts/out + 7z a -tzip ./ci-artifacts/windows.zip ./ci-artfacts/out - name: Upload Assets and Potential Publish Release if: github.repository == 'open-goal/jak-project' && startsWith(github.ref, 'refs/tags/') && matrix.compiler == 'clang' From 2caf75a11c10294b9b61c1eba564a1214cc23793 Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Mon, 4 Apr 2022 21:29:38 -0400 Subject: [PATCH 011/172] ci: there is no point in building with code-coverage on clang (#1285) --- .github/workflows/linux-workflow.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linux-workflow.yaml b/.github/workflows/linux-workflow.yaml index d5dc0e570b..cb135154ac 100644 --- a/.github/workflows/linux-workflow.yaml +++ b/.github/workflows/linux-workflow.yaml @@ -62,7 +62,7 @@ jobs: -DBUILD_FOR_RELEASE=ON \ -DCMAKE_C_COMPILER_LAUNCHER="${{ github.workspace }}"/buildcache/bin/buildcache \ -DCMAKE_CXX_COMPILER_LAUNCHER="${{ github.workspace }}"/buildcache/bin/buildcache \ - -DCODE_COVERAGE=ON -DASAN_BUILD=ON + -DASAN_BUILD=ON - name: CMake Generation - Clang - No ASAN if: matrix.compiler == 'clang' && startsWith(github.ref, 'refs/tags/') @@ -74,7 +74,7 @@ jobs: -DBUILD_FOR_RELEASE=ON \ -DCMAKE_C_COMPILER_LAUNCHER="${{ github.workspace }}"/buildcache/bin/buildcache \ -DCMAKE_CXX_COMPILER_LAUNCHER="${{ github.workspace }}"/buildcache/bin/buildcache \ - -DCODE_COVERAGE=ON -DASAN_BUILD=OFF + -DASAN_BUILD=OFF - name: CMake Generation - GCC if: matrix.compiler == 'gcc' From 1db96c72abff7da01fca721417e218a106b392d8 Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Thu, 7 Apr 2022 19:13:22 -0400 Subject: [PATCH 012/172] [goalc] macro expansion in integer constants (#1282) * [goalc] macro expansion in integer constants * working * didn't break it yet * support conditional compilation * fix up some more small bugs * fix duplicate evaluation of bitfield definitions * paranoid --- common/goos/Interpreter.cpp | 11 - common/goos/Interpreter.h | 10 - common/versions.h | 2 +- docs/progress-notes/changelog.md | 7 +- .../opengl_renderer/DirectRenderer.cpp | 2 +- goal_src/goal-lib.gc | 4 +- goalc/CMakeLists.txt | 1 + goalc/compiler/Compiler.cpp | 16 +- goalc/compiler/Compiler.h | 28 +- goalc/compiler/Util.cpp | 58 +--- goalc/compiler/Val.h | 15 + goalc/compiler/compilation/Asm.cpp | 8 +- goalc/compiler/compilation/Atoms.cpp | 28 +- .../compilation/ConstantPropagation.cpp | 319 ++++++++++++++++++ goalc/compiler/compilation/Define.cpp | 2 +- goalc/compiler/compilation/Function.cpp | 6 +- goalc/compiler/compilation/Macro.cpp | 4 +- goalc/compiler/compilation/Math.cpp | 33 +- goalc/compiler/compilation/Static.cpp | 117 +++---- goalc/compiler/compilation/Type.cpp | 45 +-- goalc/debugger/DebugInfo.cpp | 2 +- goalc/debugger/Debugger.cpp | 3 +- goalc/debugger/disassemble.cpp | 7 +- goalc/debugger/disassemble.h | 3 +- test/test_goos.cpp | 11 - 25 files changed, 501 insertions(+), 241 deletions(-) create mode 100644 goalc/compiler/compilation/ConstantPropagation.cpp diff --git a/common/goos/Interpreter.cpp b/common/goos/Interpreter.cpp index 407b952207..243e614844 100644 --- a/common/goos/Interpreter.cpp +++ b/common/goos/Interpreter.cpp @@ -12,8 +12,6 @@ namespace goos { Interpreter::Interpreter(const std::string& username) { // Interpreter startup: - goal_to_goos.reset(); - // create the GOOS global environment global_environment = EnvironmentObject::make_new("global"); @@ -73,7 +71,6 @@ Interpreter::Interpreter(const std::string& username) { {">=", &Interpreter::eval_geq}, {"null?", &Interpreter::eval_null}, {"type?", &Interpreter::eval_type}, - {"current-method-type", &Interpreter::eval_current_method_type}, {"fmt", &Interpreter::eval_format}, {"error", &Interpreter::eval_error}, {"string-ref", &Interpreter::eval_string_ref}, @@ -1550,14 +1547,6 @@ Object Interpreter::eval_type(const Object& form, } } -Object Interpreter::eval_current_method_type(const Object& form, - Arguments& args, - const std::shared_ptr& env) { - (void)env; - vararg_check(form, args, {}, {}); - return SymbolObject::make_new(reader.symbolTable, goal_to_goos.enclosing_method_type); -} - Object Interpreter::eval_format(const Object& form, Arguments& args, const std::shared_ptr& env) { diff --git a/common/goos/Interpreter.h b/common/goos/Interpreter.h index 7fffb1af61..049fa2a743 100644 --- a/common/goos/Interpreter.h +++ b/common/goos/Interpreter.h @@ -49,13 +49,6 @@ class Interpreter { Object global_environment; Object goal_env; - // data passed from GOAL to GOOS available to any evaluation. - struct GoalToGoosData { - std::string enclosing_method_type; - - void reset() { enclosing_method_type = "#f"; } - } goal_to_goos; - private: friend class Goal; void load_goos_library(); @@ -188,9 +181,6 @@ class Interpreter { Object eval_type(const Object& form, Arguments& args, const std::shared_ptr& env); - Object eval_current_method_type(const Object& form, - Arguments& args, - const std::shared_ptr& env); Object eval_format(const Object& form, Arguments& args, const std::shared_ptr& env); diff --git a/common/versions.h b/common/versions.h index 5e99f048b7..de8cf234d4 100644 --- a/common/versions.h +++ b/common/versions.h @@ -10,7 +10,7 @@ namespace versions { // language version (OpenGOAL) constexpr s32 GOAL_VERSION_MAJOR = 0; -constexpr s32 GOAL_VERSION_MINOR = 8; +constexpr s32 GOAL_VERSION_MINOR = 9; constexpr int DECOMPILER_VERSION = 4; diff --git a/docs/progress-notes/changelog.md b/docs/progress-notes/changelog.md index b55e67b620..46753db894 100644 --- a/docs/progress-notes/changelog.md +++ b/docs/progress-notes/changelog.md @@ -214,4 +214,9 @@ - Asm ops requiring 128-bit inputs will now try harder to convert their inputs when it is appropriate. - 0's that are constant propagated to the input of a 128-bit instruction will use `vpxor` instruction to generate the value, instead of `xor` and a `mov`. - Add a `stack-singleton-no-clear` stack construction type. It will create a "singleton" inside this function - all other `(new 'stack-singleton` forms with the same type will return the same stack object. -- Added support for using `(new 'static 'array ...)` for setting a static field of type `(pointer ...)` \ No newline at end of file +- Added support for using `(new 'static 'array ...)` for setting a static field of type `(pointer ...)` + +## V0.9 Large change to macro expansion and constant propagation +The compiler is now much more aggressive in where and how it expands macros and handles expressions at compiler time. +- Several places where macros could be incorrectly executed more than once (possibly causing unwanted side effects) have been fixed. +- Fixed bug in size calculation of non-inline stack arrays. Previous behavior was a compiler assert. \ No newline at end of file diff --git a/game/graphics/opengl_renderer/DirectRenderer.cpp b/game/graphics/opengl_renderer/DirectRenderer.cpp index fe8b150f6c..410731f7ef 100644 --- a/game/graphics/opengl_renderer/DirectRenderer.cpp +++ b/game/graphics/opengl_renderer/DirectRenderer.cpp @@ -617,7 +617,7 @@ void DirectRenderer::render_gif(const u8* data, } if (size != UINT32_MAX) { - if (!(offset + 15) / 16 == size / 16) { + if ((offset + 15) / 16 != size / 16) { fmt::print("DirectRenderer size failed in {}\n", name_and_id()); fmt::print("expected: {}, got: {}\n", size, offset); ASSERT(false); diff --git a/goal_src/goal-lib.gc b/goal_src/goal-lib.gc index cdd1020c30..a359c54cd9 100644 --- a/goal_src/goal-lib.gc +++ b/goal_src/goal-lib.gc @@ -799,8 +799,8 @@ (defmacro object-new (allocation type-to-make &rest sz) (if (null? sz) - `(the ,(current-method-type) ((method-of-type object new) ,allocation ,type-to-make (the int (-> ,type-to-make size)))) - `(the ,(current-method-type) ((method-of-type object new) ,allocation ,type-to-make ,@sz)) + `(the (current-method-type) ((method-of-type object new) ,allocation ,type-to-make (the int (-> ,type-to-make size)))) + `(the (current-method-type) ((method-of-type object new) ,allocation ,type-to-make ,@sz)) ) ) diff --git a/goalc/CMakeLists.txt b/goalc/CMakeLists.txt index 4b0c61fc5d..72dfd374f4 100644 --- a/goalc/CMakeLists.txt +++ b/goalc/CMakeLists.txt @@ -15,6 +15,7 @@ add_library(compiler compiler/compilation/Asm.cpp compiler/compilation/Atoms.cpp compiler/compilation/CompilerControl.cpp + compiler/compilation/ConstantPropagation.cpp compiler/compilation/Block.cpp compiler/compilation/Macro.cpp compiler/compilation/Math.cpp diff --git a/goalc/compiler/Compiler.cpp b/goalc/compiler/Compiler.cpp index 86040ceb59..6766d3db70 100644 --- a/goalc/compiler/Compiler.cpp +++ b/goalc/compiler/Compiler.cpp @@ -8,6 +8,7 @@ #include "goalc/regalloc/Allocator.h" #include "goalc/regalloc/Allocator_v2.h" #include "third-party/fmt/core.h" +#include "common/goos/PrettyPrinter.h" using namespace goos; @@ -184,11 +185,6 @@ Val* Compiler::compile_error_guard(const goos::Object& code, Env* env) { return compile(code, env); } catch (CompilerException& ce) { if (ce.print_err_stack) { - auto obj_print = code.print(); - if (obj_print.length() > 80) { - obj_print = obj_print.substr(0, 80); - obj_print += "..."; - } bool term; auto loc_info = m_goos.reader.db.get_info_for(code, &term); if (term) { @@ -197,7 +193,7 @@ Val* Compiler::compile_error_guard(const goos::Object& code, Env* env) { } fmt::print(fg(fmt::color::yellow) | fmt::emphasis::bold, "Code:\n"); - fmt::print("{}\n", obj_print); + fmt::print("{}\n", pretty_print::to_string(code, 120)); if (term) { ce.print_err_stack = false; @@ -212,12 +208,6 @@ Val* Compiler::compile_error_guard(const goos::Object& code, Env* env) { catch (std::runtime_error& e) { fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold, "-- Compilation Error! --\n"); fmt::print(fmt::emphasis::bold, "{}\n", e.what()); - - auto obj_print = code.print(); - if (obj_print.length() > 80) { - obj_print = obj_print.substr(0, 80); - obj_print += "..."; - } bool term; auto loc_info = m_goos.reader.db.get_info_for(code, &term); if (term) { @@ -226,7 +216,7 @@ Val* Compiler::compile_error_guard(const goos::Object& code, Env* env) { } fmt::print(fg(fmt::color::yellow) | fmt::emphasis::bold, "Code:\n"); - fmt::print("{}\n", obj_print); + fmt::print("{}\n", pretty_print::to_string(code, 120)); CompilerException ce("Compiler Exception"); if (term) { diff --git a/goalc/compiler/Compiler.h b/goalc/compiler/Compiler.h index 51d70a93fd..7bd3d4abfe 100644 --- a/goalc/compiler/Compiler.h +++ b/goalc/compiler/Compiler.h @@ -34,6 +34,8 @@ class Compiler { const goos::Object& code, Env* env); Val* compile(const goos::Object& code, Env* env); + Val* compile_no_const_prop(const goos::Object& code, Env* env); + Val* compile_error_guard(const goos::Object& code, Env* env); None* get_none() { return m_none.get(); } std::vector run_test_from_file(const std::string& source_code); @@ -212,7 +214,7 @@ class Compiler { const Val* actual, const std::string& error_message = ""); - TypeSpec parse_typespec(const goos::Object& src); + TypeSpec parse_typespec(const goos::Object& src, Env* env); bool is_local_symbol(const goos::Object& obj, Env* env); emitter::HWRegKind get_preferred_reg_kind(const TypeSpec& ts); Val* compile_real_function_call(const goos::Object& form, @@ -221,8 +223,10 @@ class Compiler { Env* env, const std::string& method_type_name = ""); - bool try_getting_constant_integer(const goos::Object& in, int64_t* out, Env* env); - bool try_getting_constant_float(const goos::Object& in, float* out, Env* env); + s64 get_constant_integer_or_error(const goos::Object& in, Env* env); + ValOrConstInt get_constant_integer_or_variable(const goos::Object& in, Env* env); + ValOrConstFloat get_constant_float_or_variable(const goos::Object& in, Env* env); + Val* compile_heap_new(const goos::Object& form, const std::string& allocation, const goos::Object& type, @@ -385,7 +389,9 @@ class Compiler { int get_size_for_size_of(const goos::Object& form, const goos::Object& rest); template - void throw_compiler_error(const goos::Object& code, const std::string& str, Args&&... args) { + [[noreturn]] void throw_compiler_error(const goos::Object& code, + const std::string& str, + Args&&... args) { fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold, "-- Compilation Error! --\n"); if (!str.empty() && str.back() == '\n') { fmt::print(fmt::emphasis::bold, str, std::forward(args)...); @@ -399,7 +405,7 @@ class Compiler { } template - void throw_compiler_error_no_code(const std::string& str, Args&&... args) { + [[noreturn]] void throw_compiler_error_no_code(const std::string& str, Args&&... args) { fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold, "-- Compilation Error! --\n"); if (!str.empty() && str.back() == '\n') { fmt::print(fmt::emphasis::bold, str, std::forward(args)...); @@ -431,6 +437,13 @@ class Compiler { Val*& enter_val); public: + struct ConstPropResult { + goos::Object value; + bool has_side_effects = true; + }; + ConstPropResult try_constant_propagation(const goos::Object& form, Env* env); + ConstPropResult constant_propagation_dispatch(const goos::Object& form, Env* env); + // Asm Val* compile_rlet(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_asm_ret(const goos::Object& form, const goos::Object& rest, Env* env); @@ -441,8 +454,6 @@ class Compiler { Val* compile_asm_load_sym(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_asm_jr(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_asm_mov(const goos::Object& form, const goos::Object& rest, Env* env); - Val* compile_asm_movn(const goos::Object& form, const goos::Object& rest, Env* env); - Val* compile_asm_slt(const goos::Object& form, const goos::Object& rest, Env* env); // Vector Float Operations Val* compile_asm_lvf(const goos::Object& form, const goos::Object& rest, Env* env); @@ -541,6 +552,7 @@ class Compiler { // Block Val* compile_begin(const goos::Object& form, const goos::Object& rest, Env* env); + ConstPropResult const_prop_begin(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_top_level(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_block(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_return_from(const goos::Object& form, const goos::Object& rest, Env* env); @@ -604,6 +616,7 @@ class Compiler { // Macro Val* compile_gscond(const goos::Object& form, const goos::Object& rest, Env* env); + ConstPropResult const_prop_gscond(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_quote(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_defglobalconstant(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_defconstant(const goos::Object& form, const goos::Object& rest, Env* env); @@ -652,6 +665,7 @@ class Compiler { Val* compile_none(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_defenum(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_size_of(const goos::Object& form, const goos::Object& rest, Env* env); + ConstPropResult const_prop_size_of(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_psize_of(const goos::Object& form, const goos::Object& rest, Env* env); // State diff --git a/goalc/compiler/Util.cpp b/goalc/compiler/Util.cpp index 80be666c99..eb8751aa49 100644 --- a/goalc/compiler/Util.cpp +++ b/goalc/compiler/Util.cpp @@ -124,7 +124,11 @@ void Compiler::expect_empty_list(const goos::Object& o) { } } -TypeSpec Compiler::parse_typespec(const goos::Object& src) { +TypeSpec Compiler::parse_typespec(const goos::Object& src, Env* env) { + if (src.is_pair() && src.as_pair()->car.is_symbol("current-method-type") && + src.as_pair()->cdr.is_empty_list()) { + return env->function_env()->method_of_type_name; + } return ::parse_typespec(&m_ts, src); } @@ -182,58 +186,6 @@ bool Compiler::is_pair(const TypeSpec& ts) { return m_ts.tc(m_ts.make_typespec("pair"), ts); } -bool Compiler::try_getting_constant_integer(const goos::Object& in, int64_t* out, Env* env) { - (void)env; - if (in.is_int()) { - *out = in.as_int(); - return true; - } - - if (in.is_pair()) { - auto head = in.as_pair()->car; - if (head.is_symbol()) { - auto head_sym = head.as_symbol(); - auto enum_type = m_ts.try_enum_lookup(head_sym->name); - if (enum_type) { - bool success; - u64 as_enum = enum_lookup(in, enum_type, in.as_pair()->cdr, false, &success); - if (success) { - *out = as_enum; - return true; - } - } - - if (head_sym->name == "size-of") { - *out = get_size_for_size_of(in, in.as_pair()->cdr); - return true; - } - } - } - - if (in.is_symbol()) { - auto global_constant = m_global_constants.find(in.as_symbol()); - if (global_constant != m_global_constants.end()) { - // recursively get constant integer, so we can have constants set to constants, etc. - if (try_getting_constant_integer(global_constant->second, out, env)) { - return true; - } - } - } - - return false; -} - -bool Compiler::try_getting_constant_float(const goos::Object& in, float* out, Env* env) { - (void)env; - if (in.is_float()) { - *out = in.as_float(); - return true; - } - - // todo, try more things like constants before giving up. - return false; -} - bool Compiler::get_true_or_false(const goos::Object& form, const goos::Object& boolean) { // todo try other things. if (boolean.is_symbol()) { diff --git a/goalc/compiler/Val.h b/goalc/compiler/Val.h index 94a19c8b90..db8e4cc707 100644 --- a/goalc/compiler/Val.h +++ b/goalc/compiler/Val.h @@ -293,3 +293,18 @@ class BitFieldVal : public Val { bool m_sign_extend = false; bool m_use_128 = false; }; + +template +struct ValOrConstant { + explicit ValOrConstant(const T& c) : constant(c), val(nullptr) {} + explicit ValOrConstant(Val* v) : val(v) {} + + T constant; + Val* val = nullptr; + + bool is_constant() const { return val == nullptr; } + bool is_variable() const { return val != nullptr; } +}; + +using ValOrConstInt = ValOrConstant; +using ValOrConstFloat = ValOrConstant; \ No newline at end of file diff --git a/goalc/compiler/compilation/Asm.cpp b/goalc/compiler/compilation/Asm.cpp index 091ad8e89e..ecbef4fbf6 100644 --- a/goalc/compiler/compilation/Asm.cpp +++ b/goalc/compiler/compilation/Asm.cpp @@ -54,7 +54,7 @@ Val* Compiler::compile_rlet(const goos::Object& form, const goos::Object& rest, // get the type of the new place TypeSpec ts = m_ts.make_typespec("object"); if (def_args.has_named("type")) { - ts = parse_typespec(def_args.named.at("type")); + ts = parse_typespec(def_args.named.at("type"), env); } // figure out the class @@ -590,11 +590,7 @@ Val* Compiler::compile_asm_int128_math2_imm_u8(const goos::Object& form, auto dest = compile_error_guard(args.unnamed.at(0), env)->to_reg(form, env); auto src = compile_error_guard(args.unnamed.at(1), env)->to_xmm128(form, env); - s64 imm; - if (!try_getting_constant_integer(args.unnamed.at(2), &imm, env)) { - throw_compiler_error(form, "Could not evaluate {} as a compile-time integer.", - args.unnamed.at(2).print()); - } + s64 imm = get_constant_integer_or_error(args.unnamed.at(2), env); if (imm < 0 || imm > 255) { throw_compiler_error(form, "Immediate {} is invalid. The value {} is out of range for a uint8.", diff --git a/goalc/compiler/compilation/Atoms.cpp b/goalc/compiler/compilation/Atoms.cpp index 6cbdae3331..49df6d10a3 100644 --- a/goalc/compiler/compilation/Atoms.cpp +++ b/goalc/compiler/compilation/Atoms.cpp @@ -262,10 +262,7 @@ const std::unordered_map< {"define-virtual-state-hook", &Compiler::compile_define_virtual_state_hook}, }; -/*! - * Highest level compile function - */ -Val* Compiler::compile(const goos::Object& code, Env* env) { +Val* Compiler::compile_no_const_prop(const goos::Object& code, Env* env) { switch (code.type) { case goos::ObjectType::PAIR: return compile_pair(code, env); @@ -285,6 +282,14 @@ Val* Compiler::compile(const goos::Object& code, Env* env) { return get_none(); } +/*! + * Highest level compile function + */ +Val* Compiler::compile(const goos::Object& code, Env* env) { + auto propagated = try_constant_propagation(code, env); + return compile_no_const_prop(propagated.value, env); +} + /*! * Compile a pair/list. * Can be a compiler form, function call (possibly inlined), method call, immediate application of a @@ -297,18 +302,18 @@ Val* Compiler::compile_pair(const goos::Object& code, Env* env) { if (head.is_symbol()) { auto head_sym = head.as_symbol(); - // first try as a goal compiler form - auto kv_gfs = g_goal_forms.find(head_sym->name); - if (kv_gfs != g_goal_forms.end()) { - return ((*this).*(kv_gfs->second))(code, rest, env); - } - - // next try as a macro + // first try as a macro goos::Object macro_obj; if (try_getting_macro_from_goos(head, ¯o_obj)) { return compile_goos_macro(code, macro_obj, rest, head, env); } + // next try as a goal compiler form + auto kv_gfs = g_goal_forms.find(head_sym->name); + if (kv_gfs != g_goal_forms.end()) { + return ((*this).*(kv_gfs->second))(code, rest, env); + } + // next try as an enum auto enum_type = m_ts.try_enum_lookup(head_sym->name); if (enum_type) { @@ -384,6 +389,7 @@ Val* Compiler::compile_get_symbol_value(const goos::Object& form, /*! * Compile a symbol. Can get mlet macro symbols, local variables, constants, or symbols. + * Note: order of checks here should match try_constant_propagation */ Val* Compiler::compile_symbol(const goos::Object& form, Env* env) { auto name = symbol_string(form); diff --git a/goalc/compiler/compilation/ConstantPropagation.cpp b/goalc/compiler/compilation/ConstantPropagation.cpp new file mode 100644 index 0000000000..900baa400e --- /dev/null +++ b/goalc/compiler/compilation/ConstantPropagation.cpp @@ -0,0 +1,319 @@ +#include "goalc/compiler/Compiler.h" + +/*! + * Main table for compiler forms that can be constant propagated. + */ +const std::unordered_map + g_const_prop_forms = { + // INLINE ASM + {"begin", &Compiler::const_prop_begin}, + {"size-of", &Compiler::const_prop_size_of}, + {"#cond", &Compiler::const_prop_gscond}}; + +// Note: writing const_prop functions is a bit tricky because you have to try expanding macros, but +// if you decide that you can't constant propagate, then there's no way to "undo" any side effects +// from the macro expansion. So the solution is to return a form with all macro expansions already +// applied. + +// The result should be a goos Object that is either code to be compiled, or some constant +// integer/string/float/symbol. The const prop functions should emit no code. + +/*! + * Constant propagate a form like: + * (begin a b c d ...) + * The head doesn't have to be "begin" and it will still work (the form argument is ignored). + * + * If constant propagation fails, it will return a form like + * (begin a c ..) + * where the head is always begin (even if it wasn't originally), and some of a, b, c... + * may be macro expanded, or omitted if they have no side effects. + * + * If constant propagation succeeds (the expression is a compile time constant with no side effects) + * it will return a single value. The other values don't matter at all. + * + * This applies constant propagation recursively, so elements may be macro expanded and nested + * begins can be eliminated. + * + * This function can generally be used to constant propagate any "body" of code. + */ +Compiler::ConstPropResult Compiler::const_prop_begin(const goos::Object& /*form*/, + const goos::Object& rest, + Env* env) { + ConstPropResult result; + result.has_side_effects = false; + result.value = goos::PairObject::make_new({}, {}); + goos::Object* out_it = &result.value.as_pair()->cdr; + const goos::Object* it = &rest; + while (!it->is_empty_list()) { + const goos::Object& obj = it->as_pair()->car; + + auto this_elt_prop = + result.has_side_effects ? ConstPropResult{obj, true} : try_constant_propagation(obj, env); + if (this_elt_prop.has_side_effects) { + result.has_side_effects = true; + } + it = &it->as_pair()->cdr; + if (it->is_empty_list() && !result.has_side_effects) { + // can throw out the begin and replace it with the last thing + return this_elt_prop; + } + + if (this_elt_prop.has_side_effects) { + *out_it = goos::PairObject::make_new(this_elt_prop.value, {}); + out_it = &out_it->as_pair()->cdr; + } + } + + result.value.as_pair()->car = m_goos.intern("begin"); + *out_it = goos::Object::make_empty_list(); + + return result; +} + +/*! + * Constant propagate a #cond form. + * This will always evaluate the actual conditions. + * In cases where we return none, it gives up constant propagation, as we can't really do anything + * with that. + * In other cases, it tries to constant propagate the body of the matching case. + */ +Compiler::ConstPropResult Compiler::const_prop_gscond(const goos::Object& form, + const goos::Object& rest, + Env* env) { + if (!rest.is_pair()) { + throw_compiler_error(form, "#cond must have at least one clause, which must be a form"); + } + + goos::Object lst = rest; + for (;;) { + if (lst.is_pair()) { + goos::Object current_case = lst.as_pair()->car; + if (!current_case.is_pair()) { + throw_compiler_error(lst, "Bad case in #cond"); + } + + // check condition: + goos::Object condition_result = m_goos.eval_with_rewind( + current_case.as_pair()->car, m_goos.global_environment.as_env_ptr()); + if (m_goos.truthy(condition_result)) { + if (current_case.as_pair()->cdr.is_empty_list()) { + // would return none, let's just return that this has side effects and let the compiler + // handle it. + return {form, true}; + } + // got a match! + return const_prop_begin(current_case, current_case.as_pair()->cdr, env); + } else { + // no match, continue. + lst = lst.as_pair()->cdr; + } + } else if (lst.is_empty_list()) { + return {form, true}; + } else { + throw_compiler_error(form, "malformed #cond"); + } + } +} + +namespace { +size_t code_size(Env* e) { + auto fe = e->function_env(); + if (fe) { + return fe->code().size(); + } else { + return 0; + } +} +} // namespace + +Compiler::ConstPropResult Compiler::try_constant_propagation(const goos::Object& form, Env* env) { + size_t start_size = code_size(env); + auto ret = constant_propagation_dispatch(form, env); + size_t end_size = code_size(env); + if (start_size != end_size) { + fmt::print("Compiler bug in constant propagation. Code was generated: {} vs {}\n", start_size, + end_size); + ASSERT(false); + } + return ret; +} + +/*! + * Main constant propagation dispatch. + * Note that there are some tricky orders to get right here - we don't want to use a global constant + * when the normal compiler would use a lexical variable. + */ +Compiler::ConstPropResult Compiler::constant_propagation_dispatch(const goos::Object& code, + Env* env) { + // first, expand macros. + // this only does something if code is a pair, and for pairs macros are the first check. + auto expanded = expand_macro_completely(code, env); + + switch (expanded.type) { + case goos::ObjectType::INTEGER: + case goos::ObjectType::STRING: + case goos::ObjectType::FLOAT: + // we got a plain value, no code is needed to figure out the value and we can return it + // directly. + return {expanded, false}; + case goos::ObjectType::SYMBOL: { + // NOTE: order must match compile_symbol + // #t/#f + // mlet + // lexical + // constant/symbol + + // first, try to resolve the symbol in an mlet environment. + auto mlet_env = env->symbol_macro_env(); + while (mlet_env) { + auto mlkv = mlet_env->macros.find(expanded.as_symbol()); + if (mlkv != mlet_env->macros.end()) { + // we found a match, substitute and keep trying. + return try_constant_propagation(mlkv->second, env); + } + mlet_env = mlet_env->parent()->symbol_macro_env(); + } + + // see if it's a local variable + auto lexical = env->lexical_lookup(expanded); + if (lexical) { + // if so, that's what we should use, not a constant with the same name. + // give up on constant propagation, we never do it for lexicals (can't really in a single + // pass). + return {expanded, true}; + } + + // it can either be a global or symbol + const auto& global_constant = m_global_constants.find(expanded.as_symbol()); + const auto& existing_symbol = m_symbol_types.find(expanded.as_symbol()->name); + + // see if it's a constant + if (global_constant != m_global_constants.end()) { + // check there is no symbol with the same name, this is likely a bug and complain. + if (existing_symbol != m_symbol_types.end()) { + throw_compiler_error( + code, + "Ambiguous symbol: {} is both a global variable and a constant and it " + "is not clear which should be used here."); + } + + // got a global constant + return try_constant_propagation(global_constant->second, env); + } else { + // return to the compiler, we can't figure it out. + return {expanded, true}; + } + } break; + + case goos::ObjectType::PAIR: { + auto pair = expanded.as_pair(); + auto head = pair->car; + auto rest = pair->cdr; + + // in theory you could write code like: + // ((#if PC_PORT foo bar) ...) + // and you might want the compiler to constant propagate (foo ...) + // but this is not implemented because the logic in compile_function_or_method_call + // is quite complicated and this case seems unlikely to ever be used. + + if (head.is_symbol()) { + auto head_sym = head.as_symbol(); + // the first thing tried should be macros, but we already did that. And it iterates until + // all are expanded, so we don't need to do it again. + + // first try as a goal compiler form + auto kv_gfs = g_const_prop_forms.find(head_sym->name); + if (kv_gfs != g_const_prop_forms.end()) { + return ((*this).*(kv_gfs->second))(expanded, rest, env); + } + + const auto& kv_goal = g_goal_forms.find(head_sym->name); + if (kv_goal != g_goal_forms.end()) { + // it's a compiler form that we can't constant propagate. + return {expanded, true}; + } + } + + return {expanded, true}; + } + default: + return {expanded, true}; + } +} + +s64 Compiler::get_constant_integer_or_error(const goos::Object& in, Env* env) { + auto prop = try_constant_propagation(in, env); + if (prop.value.is_pair()) { + auto head = prop.value.as_pair()->car; + if (head.is_symbol()) { + auto head_sym = head.as_symbol(); + auto enum_type = m_ts.try_enum_lookup(head_sym->name); + if (enum_type) { + bool success; + u64 as_enum = + enum_lookup(prop.value, enum_type, prop.value.as_pair()->cdr, false, &success); + if (success) { + return as_enum; + } + } + } + } + + if (prop.has_side_effects) { + throw_compiler_error(in, "Value {} cannot be used as a constant - it has side effects.", + in.print()); + } else { + if (prop.value.is_int()) { + return prop.value.as_int(); + } else { + throw_compiler_error( + in, "Value {} cannot be used as a constant integer - it has the wrong type.", in.print()); + } + } +} + +ValOrConstInt Compiler::get_constant_integer_or_variable(const goos::Object& in, Env* env) { + auto prop = try_constant_propagation(in, env); + + if (prop.value.is_pair()) { + auto head = prop.value.as_pair()->car; + if (head.is_symbol()) { + auto head_sym = head.as_symbol(); + auto enum_type = m_ts.try_enum_lookup(head_sym->name); + if (enum_type) { + bool success; + u64 as_enum = + enum_lookup(prop.value, enum_type, prop.value.as_pair()->cdr, false, &success); + if (success) { + return ValOrConstInt(as_enum); + } + } + } + } + + if (prop.has_side_effects) { + return ValOrConstInt(compile_no_const_prop(prop.value, env)); + } else { + if (prop.value.is_int()) { + return ValOrConstInt(prop.value.as_int()); + } else { + return ValOrConstInt(compile_no_const_prop(prop.value, env)); + } + } +} + +ValOrConstFloat Compiler::get_constant_float_or_variable(const goos::Object& in, Env* env) { + auto prop = try_constant_propagation(in, env); + if (prop.has_side_effects) { + return ValOrConstFloat(compile_no_const_prop(prop.value, env)); + } else { + if (prop.value.is_float()) { + return ValOrConstFloat(prop.value.as_float()); + } else { + return ValOrConstFloat(compile_no_const_prop(prop.value, env)); + } + } +} \ No newline at end of file diff --git a/goalc/compiler/compilation/Define.cpp b/goalc/compiler/compilation/Define.cpp index d3cb1fdc75..313d5f5a33 100644 --- a/goalc/compiler/compilation/Define.cpp +++ b/goalc/compiler/compilation/Define.cpp @@ -76,7 +76,7 @@ Val* Compiler::compile_define_extern(const goos::Object& form, const goos::Objec auto& sym = args.unnamed.at(0); auto& typespec = args.unnamed.at(1); - auto new_type = parse_typespec(typespec); + auto new_type = parse_typespec(typespec, env); auto existing_type = m_symbol_types.find(symbol_string(sym)); if (existing_type != m_symbol_types.end() && existing_type->second != new_type) { diff --git a/goalc/compiler/compilation/Function.cpp b/goalc/compiler/compilation/Function.cpp index bdf1d77e09..70691a21c9 100644 --- a/goalc/compiler/compilation/Function.cpp +++ b/goalc/compiler/compilation/Function.cpp @@ -71,7 +71,7 @@ Val* Compiler::compile_local_vars(const goos::Object& form, const goos::Object& auto param_args = get_va(o, o); va_check(o, param_args, {goos::ObjectType::SYMBOL, {}}, {}); auto name = symbol_string(param_args.unnamed.at(0)); - auto type = parse_typespec(param_args.unnamed.at(1)); + auto type = parse_typespec(param_args.unnamed.at(1), env); if (fe->params.find(name) != fe->params.end()) { throw_compiler_error(form, "Cannot declare a local named {}, this already exists.", name); @@ -129,7 +129,7 @@ Val* Compiler::compile_lambda(const goos::Object& form, const goos::Object& rest GoalArg parm; parm.name = symbol_string(param_args.unnamed.at(0)); - parm.type = parse_typespec(param_args.unnamed.at(1)); + parm.type = parse_typespec(param_args.unnamed.at(1), env); lambda.params.push_back(parm); lambda_ts.add_arg(parm.type); @@ -687,7 +687,7 @@ Val* Compiler::compile_declare(const goos::Object& form, const goos::Object& res throw_compiler_error( form, "Declare asm-func must provide the function's return type as an argument."); } - fe->asm_func_return_type = parse_typespec(rrest->as_pair()->car); + fe->asm_func_return_type = parse_typespec(rrest->as_pair()->car, env); if (!rrest->as_pair()->cdr.is_empty_list()) { throw_compiler_error(first, "Invalid asm-func declare"); } diff --git a/goalc/compiler/compilation/Macro.cpp b/goalc/compiler/compilation/Macro.cpp index 13cb7e5695..4d67177551 100644 --- a/goalc/compiler/compilation/Macro.cpp +++ b/goalc/compiler/compilation/Macro.cpp @@ -35,11 +35,9 @@ Val* Compiler::compile_goos_macro(const goos::Object& o, auto mac_env = mac_env_obj.as_env_ptr(); mac_env->parent_env = m_goos.global_environment.as_env_ptr(); m_goos.set_args_in_env(o, args, macro->args, mac_env); - m_goos.goal_to_goos.enclosing_method_type = env->function_env()->method_of_type_name; auto goos_result = m_goos.eval_list_return_last(macro->body, macro->body, mac_env); // make the macro expanded form point to the source where the macro was used for error messages. // m_goos.reader.db.inherit_info(o, goos_result); - m_goos.goal_to_goos.reset(); auto compile_env_for_macro = env->function_env()->alloc_env(env, name.as_symbol(), macro->body, o); @@ -267,7 +265,7 @@ bool Compiler::expand_macro_once(const goos::Object& src, goos::Object* out, Env auto goos_result = m_goos.eval_list_return_last(macro->body, macro->body, mac_env); // make the macro expanded form point to the source where the macro was used for error messages. - // m_goos.reader.db.inherit_info(src, goos_result); + m_goos.reader.db.inherit_info(src, goos_result); *out = goos_result; return true; diff --git a/goalc/compiler/compilation/Math.cpp b/goalc/compiler/compilation/Math.cpp index 8105200720..d4ca7cc8a6 100644 --- a/goalc/compiler/compilation/Math.cpp +++ b/goalc/compiler/compilation/Math.cpp @@ -530,14 +530,15 @@ Val* Compiler::compile_shl(const goos::Object& form, const goos::Object& rest, E auto args = get_va(form, rest); va_check(form, args, {{}, {}}, {}); auto first = compile_error_guard(args.unnamed.at(0), env)->to_gpr(form, env); - int64_t constant_sa = -1; - if (try_getting_constant_integer(args.unnamed.at(1), &constant_sa, env)) { - if (constant_sa < 0 || constant_sa > 64) { + + auto sa = get_constant_integer_or_variable(args.unnamed.at(1), env); + if (sa.is_constant()) { + if (sa.constant < 0 || sa.constant > 64) { throw_compiler_error(form, "Cannot shift by more than 64, or by a negative amount."); } - return compile_fixed_shift(form, first, constant_sa, env, IntegerMathKind::SHL_64); + return compile_fixed_shift(form, first, sa.constant, env, IntegerMathKind::SHL_64); } else { - auto second = compile_error_guard(args.unnamed.at(1), env)->to_gpr(form, env); + auto second = sa.val->to_gpr(form, env); return compile_variable_shift(form, first, second, env, IntegerMathKind::SHLV_64); } } @@ -546,14 +547,15 @@ Val* Compiler::compile_shr(const goos::Object& form, const goos::Object& rest, E auto args = get_va(form, rest); va_check(form, args, {{}, {}}, {}); auto first = compile_error_guard(args.unnamed.at(0), env)->to_gpr(form, env); - int64_t constant_sa = -1; - if (try_getting_constant_integer(args.unnamed.at(1), &constant_sa, env)) { - if (constant_sa < 0 || constant_sa > 64) { + + auto sa = get_constant_integer_or_variable(args.unnamed.at(1), env); + if (sa.is_constant()) { + if (sa.constant < 0 || sa.constant > 64) { throw_compiler_error(form, "Cannot shift by more than 64, or by a negative amount."); } - return compile_fixed_shift(form, first, constant_sa, env, IntegerMathKind::SHR_64); + return compile_fixed_shift(form, first, sa.constant, env, IntegerMathKind::SHR_64); } else { - auto second = compile_error_guard(args.unnamed.at(1), env)->to_gpr(form, env); + auto second = sa.val->to_gpr(form, env); return compile_variable_shift(form, first, second, env, IntegerMathKind::SHRV_64); } } @@ -562,14 +564,15 @@ Val* Compiler::compile_sar(const goos::Object& form, const goos::Object& rest, E auto args = get_va(form, rest); va_check(form, args, {{}, {}}, {}); auto first = compile_error_guard(args.unnamed.at(0), env)->to_gpr(form, env); - int64_t constant_sa = -1; - if (try_getting_constant_integer(args.unnamed.at(1), &constant_sa, env)) { - if (constant_sa < 0 || constant_sa > 64) { + + auto sa = get_constant_integer_or_variable(args.unnamed.at(1), env); + if (sa.is_constant()) { + if (sa.constant < 0 || sa.constant > 64) { throw_compiler_error(form, "Cannot shift by more than 64, or by a negative amount."); } - return compile_fixed_shift(form, first, constant_sa, env, IntegerMathKind::SAR_64); + return compile_fixed_shift(form, first, sa.constant, env, IntegerMathKind::SAR_64); } else { - auto second = compile_error_guard(args.unnamed.at(1), env)->to_gpr(form, env); + auto second = sa.val->to_gpr(form, env); return compile_variable_shift(form, first, second, env, IntegerMathKind::SARV_64); } } diff --git a/goalc/compiler/compilation/Static.cpp b/goalc/compiler/compilation/Static.cpp index 9ac4f3042c..b90633a7ac 100644 --- a/goalc/compiler/compilation/Static.cpp +++ b/goalc/compiler/compilation/Static.cpp @@ -84,7 +84,7 @@ void Compiler::compile_static_structure_inline(const goos::Object& form, "Array field must be defined with (new 'static ['array, 'inline-array] type-name ...)"); } - auto array_content_type = parse_typespec(new_form.at(3)); + auto array_content_type = parse_typespec(new_form.at(3), env); if (is_inline) { if (field_info.field.type() != array_content_type) { @@ -96,11 +96,7 @@ void Compiler::compile_static_structure_inline(const goos::Object& form, m_ts.typecheck_and_throw(field_info.field.type(), array_content_type, "Array content type"); } - s64 elt_array_len; - if (!try_getting_constant_integer(new_form.at(4), &elt_array_len, env)) { - throw_compiler_error(field_value, "Array field size is invalid, got {}", - new_form.at(4).print()); - } + s64 elt_array_len = get_constant_integer_or_error(new_form.at(4), env); if (elt_array_len != field_info.field.array_size()) { throw_compiler_error(field_value, "Array field had an expected size of {} but got {}", @@ -171,7 +167,7 @@ void Compiler::compile_static_structure_inline(const goos::Object& form, "Inline field must be defined with (new 'static 'type-name ...)"); } - auto inlined_type = parse_typespec(unquote(new_form.at(2))); + auto inlined_type = parse_typespec(unquote(new_form.at(2)), env); if (inlined_type != field_info.type) { throw_compiler_error(field_value, "Cannot store a {} in an inline {}", inlined_type.print(), field_info.type.print()); @@ -321,7 +317,8 @@ Val* Compiler::compile_bitfield_definition(const goos::Object& form, // dynamic_defs list below. The second pass will combine the constant and dynamic defs to build // the final value. struct DynamicDef { - goos::Object definition; + // goos::Object definition; + RegVal* value = nullptr; int field_offset, field_size; std::string field_name; // for error message TypeSpec expected_type; @@ -351,9 +348,8 @@ Val* Compiler::compile_bitfield_definition(const goos::Object& form, if (is_integer(field_info.result_type) || field_info.result_type.base_type() == "pointer") { // first, try as a constant - s64 value = 0; - bool got_constant = false; - got_constant = try_getting_constant_integer(field_value, &value, env); + auto compiled_field_val = get_constant_integer_or_variable(field_value, env); + bool got_constant = compiled_field_val.is_constant(); if (!got_constant && is_bitfield(field_info.result_type) && !allow_dynamic_construction) { auto static_result = compile_static(field_value, env); if (static_result.is_constant_data()) { @@ -362,7 +358,9 @@ Val* Compiler::compile_bitfield_definition(const goos::Object& form, typecheck(field_value, field_info.result_type, static_result.typespec(), "Type of static constant"); got_constant = true; - value = constant_data.value_64(); + compiled_field_val.val = nullptr; + compiled_field_val.constant = constant_data.value_64(); + // TODO: handle this in the constant propagation stuff } } } @@ -370,7 +368,7 @@ Val* Compiler::compile_bitfield_definition(const goos::Object& form, // failed to get as constant, add to dynamic or error. if (allow_dynamic_construction) { DynamicDef dyn; - dyn.definition = field_value; + dyn.value = compiled_field_val.val->to_gpr(field_value, env); dyn.field_offset = field_offset; dyn.field_size = field_size; dyn.field_name = field_name_def; @@ -383,11 +381,11 @@ Val* Compiler::compile_bitfield_definition(const goos::Object& form, } else { throw_compiler_error(form, "Field {} is an integer, but the value given couldn't be " - "converted to an integer at compile time.", - field_name_def); + "converted to an integer at compile time: {}", + field_name_def, field_value.print()); } } else { - u64 unsigned_value = value; + u64 unsigned_value = compiled_field_val.constant; u64 or_value = unsigned_value; ASSERT(field_size <= 64); // shift us all the way left to clear upper bits. @@ -415,12 +413,13 @@ Val* Compiler::compile_bitfield_definition(const goos::Object& form, "bytes. This is probably not what you wanted to do."); } - float value = 0.f; - if (!try_getting_constant_float(field_value, &value, env)) { + // float value = 0.f; + auto float_value_or_const = get_constant_float_or_variable(field_value, env); + if (float_value_or_const.is_variable()) { // failed to get as constant, add to dynamic or error. if (allow_dynamic_construction) { DynamicDef dyn; - dyn.definition = field_value; + dyn.value = float_value_or_const.val->to_gpr(field_value, env); dyn.field_offset = field_offset; dyn.field_size = field_size; dyn.field_name = field_name_def; @@ -432,20 +431,21 @@ Val* Compiler::compile_bitfield_definition(const goos::Object& form, "be converted to a float at compile time.", field_name_def); } - } - u64 float_value = float_as_u32(value); - bool start_lo = field_offset < 64; - bool end_lo = (field_offset + field_size) <= 64; - ASSERT(start_lo == end_lo); - if (end_lo) { - constant_integer_part.lo |= (float_value << field_offset); } else { - constant_integer_part.hi |= (float_value << (field_offset - 64)); + u64 float_value = float_as_u32(float_value_or_const.constant); + bool start_lo = field_offset < 64; + bool end_lo = (field_offset + field_size) <= 64; + ASSERT(start_lo == end_lo); + if (end_lo) { + constant_integer_part.lo |= (float_value << field_offset); + } else { + constant_integer_part.hi |= (float_value << (field_offset - 64)); + } } } else if (field_info.result_type == TypeSpec("symbol")) { if (allow_dynamic_construction) { DynamicDef dyn; - dyn.definition = field_value; + dyn.value = compile_error_guard(field_value, env)->to_gpr(field_value, env); dyn.field_offset = field_offset; dyn.field_size = field_size; dyn.field_name = field_name_def; @@ -459,7 +459,7 @@ Val* Compiler::compile_bitfield_definition(const goos::Object& form, } else if (m_ts.tc(TypeSpec("structure"), field_info.result_type)) { if (allow_dynamic_construction) { DynamicDef dyn; - dyn.definition = field_value; + dyn.value = compile_error_guard(field_value, env)->to_gpr(field_value, env); dyn.field_offset = field_offset; dyn.field_size = field_size; dyn.field_name = field_name_def; @@ -499,7 +499,7 @@ Val* Compiler::compile_bitfield_definition(const goos::Object& form, auto xmm_temp = fe->make_ireg(TypeSpec("object"), RegClass::INT_128); for (auto& def : dynamic_defs) { - auto field_val_in = compile_error_guard(def.definition, env)->to_gpr(def.definition, env); + auto field_val_in = def.value; auto field_val = env->make_gpr(field_val_in->type()); env->emit_ir(form, field_val, field_val_in); if (!m_ts.tc(def.expected_type, field_val->type())) { @@ -541,7 +541,7 @@ Val* Compiler::compile_bitfield_definition(const goos::Object& form, } else { RegVal* integer_reg = integer->to_gpr(form, env); for (auto& def : dynamic_defs) { - auto field_val_in = compile_error_guard(def.definition, env)->to_gpr(def.definition, env); + auto field_val_in = def.value; auto field_val = env->make_gpr(field_val_in->type()); env->emit_ir(form, field_val, field_val_in); if (!m_ts.tc(def.expected_type, field_val->type())) { @@ -735,7 +735,7 @@ StaticResult Compiler::compile_static(const goos::Object& form_before_macro, Env } else if (unquote(args.at(1)).as_symbol()->name == "inline-array") { return fill_static_inline_array(form, rest, env, segment); } else { - auto ts = parse_typespec(unquote(args.at(1))); + auto ts = parse_typespec(unquote(args.at(1)), env); if (ts == TypeSpec("string")) { // (new 'static 'string) if (rest.is_pair() && rest.as_pair()->cdr.is_empty_list() && @@ -762,25 +762,21 @@ StaticResult Compiler::compile_static(const goos::Object& form_before_macro, Env } else if (first.is_symbol() && first.as_symbol()->name == "the-as") { auto args = get_va(form, rest); va_check(form, args, {{}, {}}, {}); - auto type = parse_typespec(args.unnamed.at(0)); + auto type = parse_typespec(args.unnamed.at(0), env); if (type == TypeSpec("float")) { - s64 value; - if (try_getting_constant_integer(args.unnamed.at(1), &value, env)) { - if (integer_fits(value, 4, false)) { - return StaticResult::make_constant_data(value, TypeSpec("float")); - } + s64 value = get_constant_integer_or_error(args.unnamed.at(1), env); + if (integer_fits(value, 4, false)) { + return StaticResult::make_constant_data(value, TypeSpec("float")); } } } else if (first.is_symbol() && first.as_symbol()->name == "the") { auto args = get_va(form, rest); va_check(form, args, {{}, {}}, {}); - auto type = parse_typespec(args.unnamed.at(0)); + auto type = parse_typespec(args.unnamed.at(0), env); if (type == TypeSpec("binteger")) { - s64 value; - if (try_getting_constant_integer(args.unnamed.at(1), &value, env)) { - if (integer_fits(value, 4, true)) { - return StaticResult::make_constant_data(value << 3, TypeSpec("binteger")); - } + s64 value = get_constant_integer_or_error(args.unnamed.at(1), env); + if (integer_fits(value, 4, true)) { + return StaticResult::make_constant_data(value << 3, TypeSpec("binteger")); } } } else if (first.is_symbol("type-ref")) { @@ -823,10 +819,8 @@ StaticResult Compiler::compile_static(const goos::Object& form_before_macro, Env return StaticResult::make_func_ref(lambda->func, lambda->type()); } else { // maybe an enum - s64 int_out; - if (try_getting_constant_integer(form, &int_out, env)) { - return StaticResult::make_constant_data(int_out, TypeSpec("int")); - } + s64 int_out = get_constant_integer_or_error(form, env); + return StaticResult::make_constant_data(int_out, TypeSpec("int")); } } @@ -884,11 +878,8 @@ StaticResult Compiler::fill_static_array(const goos::Object& form, if (args.size() < 4) { throw_compiler_error(form, "new static array must have type and min-size arguments"); } - auto content_type = parse_typespec(args.at(2)); - s64 min_size; - if (!try_getting_constant_integer(args.at(3), &min_size, env)) { - throw_compiler_error(form, "The length {} is not valid.", args.at(3).print()); - } + auto content_type = parse_typespec(args.at(2), env); + s64 min_size = get_constant_integer_or_error(args.at(3), env); s32 length = std::max(min_size, s64(args.size() - 4)); // todo - generalize this array stuff if we ever need other types of static arrays. auto pointer_type = m_ts.make_pointer_typespec(content_type); @@ -929,21 +920,16 @@ StaticResult Compiler::fill_static_boxed_array(const goos::Object& form, if (!args.has_named("type")) { throw_compiler_error(form, "boxed array must have type"); } - auto content_type = parse_typespec(args.get_named("type")); + auto content_type = parse_typespec(args.get_named("type"), env); if (!args.has_named("length")) { throw_compiler_error(form, "boxed array must have length"); } - s64 length; - if (!try_getting_constant_integer(args.get_named("length"), &length, env)) { - throw_compiler_error(form, "boxed array has invalid length"); - } + s64 length = get_constant_integer_or_error(args.get_named("length"), env); s64 allocated_length; if (args.has_named("allocated-length")) { - if (!try_getting_constant_integer(args.get_named("allocated-length"), &allocated_length, env)) { - throw_compiler_error(form, "boxed array has invalid allocated-length"); - } + allocated_length = get_constant_integer_or_error(args.get_named("allocated-length"), env); } else { allocated_length = length; } @@ -1032,7 +1018,7 @@ void Compiler::fill_static_inline_array_inline(const goos::Object& form, elt_def, "Inline array element must be defined with (new 'static 'type-name ...)"); } - auto inlined_type = parse_typespec(unquote(new_form.at(2))); + auto inlined_type = parse_typespec(unquote(new_form.at(2)), env); if (inlined_type != content_type) { throw_compiler_error(elt_def, "Cannot store a {} in an inline array of {}", inlined_type.print(), content_type.print()); @@ -1056,11 +1042,8 @@ StaticResult Compiler::fill_static_inline_array(const goos::Object& form, if (args.size() < 4) { throw_compiler_error(form, "new static boxed array must have type and min-size arguments"); } - auto content_type = parse_typespec(args.at(2)); - s64 min_size; - if (!try_getting_constant_integer(args.at(3), &min_size, env)) { - throw_compiler_error(form, "The length {} is not valid.", args.at(3).print()); - } + auto content_type = parse_typespec(args.at(2), env); + s64 min_size = get_constant_integer_or_error(args.at(3), env); s32 length = std::max(min_size, s64(args.size() - 4)); auto inline_array_type = m_ts.make_inline_array_typespec(content_type); diff --git a/goalc/compiler/compilation/Type.cpp b/goalc/compiler/compilation/Type.cpp index ff91256438..d10cde8a05 100644 --- a/goalc/compiler/compilation/Type.cpp +++ b/goalc/compiler/compilation/Type.cpp @@ -463,7 +463,7 @@ Val* Compiler::compile_defmethod(const goos::Object& form, const goos::Object& _ GoalArg parm; parm.name = symbol_string(param_args.unnamed.at(0)); - parm.type = parse_typespec(param_args.unnamed.at(1)); + parm.type = parse_typespec(param_args.unnamed.at(1), env); // before substituting _type_ lambda_ts.add_arg(parm.type); @@ -754,10 +754,14 @@ Val* Compiler::compile_deref(const goos::Object& form, const goos::Object& _rest int64_t constant_index_value; RegVal* index_value = nullptr; + auto idx_val = get_constant_integer_or_variable(field_obj, env); + bool has_constant_idx = idx_val.is_constant(); + if (has_constant_idx) { + constant_index_value = idx_val.constant; + } - bool has_constant_idx = try_getting_constant_integer(field_obj, &constant_index_value, env); if (!has_constant_idx) { - index_value = compile_error_guard(field_obj, env)->to_gpr(form, env); + index_value = idx_val.val->to_gpr(form, env); if (!is_integer(index_value->type())) { throw_compiler_error(form, "Cannot use -> with field {}.", field_obj.print()); } @@ -890,7 +894,7 @@ Val* Compiler::compile_addr_of(const goos::Object& form, const goos::Object& res Val* Compiler::compile_the_as(const goos::Object& form, const goos::Object& rest, Env* env) { auto args = get_va(form, rest); va_check(form, args, {{}, {}}, {}); - auto desired_ts = parse_typespec(args.unnamed.at(0)); + auto desired_ts = parse_typespec(args.unnamed.at(0), env); auto base = compile_error_guard(args.unnamed.at(1), env); auto result = env->function_env()->alloc_val(desired_ts, base); if (base->settable()) { @@ -907,7 +911,7 @@ Val* Compiler::compile_the_as(const goos::Object& form, const goos::Object& rest Val* Compiler::compile_the(const goos::Object& form, const goos::Object& rest, Env* env) { auto args = get_va(form, rest); va_check(form, args, {{}, {}}, {}); - auto desired_ts = parse_typespec(args.unnamed.at(0)); + auto desired_ts = parse_typespec(args.unnamed.at(0), env); auto base = compile_error_guard(args.unnamed.at(1), env); if (is_number(base->type())) { @@ -960,7 +964,7 @@ Val* Compiler::compile_heap_new(const goos::Object& form, bool making_boxed_array = unquote(type).as_symbol()->name == "boxed-array"; TypeSpec main_type; if (!making_boxed_array) { - main_type = parse_typespec(unquote(type)); + main_type = parse_typespec(unquote(type), env); } if (main_type == TypeSpec("inline-array") || main_type == TypeSpec("array")) { @@ -971,8 +975,8 @@ Val* Compiler::compile_heap_new(const goos::Object& form, auto count_obj = pair_car(*rest); rest = &pair_cdr(*rest); // try to get the size as a compile time constant. - int64_t constant_count = 0; - bool is_constant_size = try_getting_constant_integer(count_obj, &constant_count, env); + auto cv = get_constant_integer_or_variable(count_obj, env); + bool is_constant_size = cv.is_constant(); if (!rest->is_empty_list()) { // got extra arguments @@ -991,12 +995,12 @@ Val* Compiler::compile_heap_new(const goos::Object& form, args.push_back(compile_get_sym_obj(allocation, env)->to_reg(form, env)); if (is_constant_size) { - auto array_size = constant_count * info.stride; + auto array_size = cv.constant * info.stride; args.push_back(compile_integer(array_size, env)->to_reg(form, env)); } else { auto array_size = compile_integer(info.stride, env)->to_reg(form, env); env->emit_ir(form, IntegerMathKind::IMUL_32, array_size, - compile_error_guard(count_obj, env)->to_gpr(form, env)); + cv.val->to_gpr(form, env)); args.push_back(array_size); } @@ -1058,7 +1062,7 @@ Val* Compiler::compile_static_new(const goos::Object& form, auto result = fe->alloc_val(sr.reference(), sr.typespec()); return result; } else { - auto type_of_object = parse_typespec(unquote(type)); + auto type_of_object = parse_typespec(unquote(type), env); if (is_structure(type_of_object)) { return compile_new_static_structure_or_basic(form, type_of_object, *rest, env, env->function_env()->segment_for_static_data()); @@ -1079,7 +1083,7 @@ Val* Compiler::compile_stack_new(const goos::Object& form, Env* env, bool call_constructor, bool use_singleton) { - auto type_of_object = parse_typespec(unquote(type)); + auto type_of_object = parse_typespec(unquote(type), env); auto fe = env->function_env(); auto st_type_info = dynamic_cast(m_ts.lookup_type(type_of_object)); if (st_type_info && st_type_info->is_always_stack_singleton()) { @@ -1103,11 +1107,7 @@ Val* Compiler::compile_stack_new(const goos::Object& form, auto count_obj = pair_car(*rest); rest = &pair_cdr(*rest); // try to get the size as a compile time constant. - int64_t constant_count = 0; - bool is_constant_size = try_getting_constant_integer(count_obj, &constant_count, env); - if (!is_constant_size) { - throw_compiler_error(form, "Cannot create a dynamically sized stack array"); - } + int64_t constant_count = get_constant_integer_or_error(count_obj, env); if (constant_count <= 0) { throw_compiler_error(form, "Cannot create a stack array with size {}", constant_count); @@ -1133,8 +1133,9 @@ Val* Compiler::compile_stack_new(const goos::Object& form, return addr; } - int stride = - align(type_info->get_size_in_memory(), type_info->get_inline_array_stride_alignment()); + int stride = is_inline ? align(type_info->get_size_in_memory(), + type_info->get_inline_array_stride_alignment()) + : 4; ASSERT(stride == info.stride); int size_in_bytes = info.stride * constant_count; @@ -1433,6 +1434,12 @@ Val* Compiler::compile_size_of(const goos::Object& form, const goos::Object& res return compile_integer(get_size_for_size_of(form, rest), env); } +Compiler::ConstPropResult Compiler::const_prop_size_of(const goos::Object& form, + const goos::Object& rest, + Env* /*env*/) { + return {goos::Object::make_integer(get_size_for_size_of(form, rest)), false}; +} + Val* Compiler::compile_psize_of(const goos::Object& form, const goos::Object& rest, Env* env) { return compile_integer((get_size_for_size_of(form, rest) + 0xf) & ~0xf, env); } diff --git a/goalc/debugger/DebugInfo.cpp b/goalc/debugger/DebugInfo.cpp index 47db9a4bd8..52d0870277 100644 --- a/goalc/debugger/DebugInfo.cpp +++ b/goalc/debugger/DebugInfo.cpp @@ -8,7 +8,7 @@ std::string FunctionDebugInfo::disassemble_debug_info(bool* had_failure, const goos::Reader* reader) { std::string result = fmt::format("[{}]\n", name); result += disassemble_x86_function(generated_code.data(), generated_code.size(), reader, 0x10000, - 0x10000, instructions, function.get(), had_failure); + 0x10000, instructions, function.get(), had_failure, true); return result; } diff --git a/goalc/debugger/Debugger.cpp b/goalc/debugger/Debugger.cpp index b4194c4b6a..897d93de81 100644 --- a/goalc/debugger/Debugger.cpp +++ b/goalc/debugger/Debugger.cpp @@ -396,7 +396,8 @@ Disassembly Debugger::disassemble_at_rip(const InstructionPointerInfo& info) { result.text += disassemble_x86_function( function_mem.data(), function_mem.size(), m_reader, m_debug_context.base + info.map_entry->start_addr + func_info->offset_in_seg, - rip + rip_offset, func_info->instructions, func_info->function.get(), &result.failed); + rip + rip_offset, func_info->instructions, func_info->function.get(), &result.failed, + false); } } else { result.failed = true; diff --git a/goalc/debugger/disassemble.cpp b/goalc/debugger/disassemble.cpp index ae3b39daee..090fb80186 100644 --- a/goalc/debugger/disassemble.cpp +++ b/goalc/debugger/disassemble.cpp @@ -81,7 +81,8 @@ std::string disassemble_x86_function(u8* data, u64 highlight_addr, const std::vector& x86_instructions, const FunctionEnv* fenv, - bool* had_failure) { + bool* had_failure, + bool print_whole_function) { std::string result; ZydisDecoder decoder; ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64); @@ -207,8 +208,8 @@ std::string disassemble_x86_function(u8* data, } for (auto& line : lines) { - if (line.first >= rip_src_idx - FORM_DUMP_SIZE_REV && - line.first < rip_src_idx + FORM_DUMP_SIZE_FWD) { + if (print_whole_function || (line.first >= rip_src_idx - FORM_DUMP_SIZE_REV && + line.first < rip_src_idx + FORM_DUMP_SIZE_FWD)) { result.append(line.second); } } diff --git a/goalc/debugger/disassemble.h b/goalc/debugger/disassemble.h index ebbffbbf91..526b47e1e7 100644 --- a/goalc/debugger/disassemble.h +++ b/goalc/debugger/disassemble.h @@ -34,4 +34,5 @@ std::string disassemble_x86_function(u8* data, u64 highlight_addr, const std::vector& x86_instructions, const FunctionEnv* fenv, - bool* had_failure); \ No newline at end of file + bool* had_failure, + bool print_whole_function); \ No newline at end of file diff --git a/test/test_goos.cpp b/test/test_goos.cpp index 15d53c349f..746427ddd2 100644 --- a/test/test_goos.cpp +++ b/test/test_goos.cpp @@ -404,17 +404,6 @@ TEST(GoosBuiltins, Null) { } } -TEST(GoosBuiltins, CurrentMethodType) { - Interpreter i; - i.goal_to_goos.enclosing_method_type = "test-type"; - EXPECT_EQ(e(i, "(current-method-type)"), "test-type"); - - i.disable_printfs(); - for (auto x : {"(current-method-type 1)"}) { - EXPECT_ANY_THROW(e(i, x)); - } -} - TEST(GoosBuiltins, Type) { Interpreter i; EXPECT_EQ(e(i, "(type? 'empty-list '())"), "#t"); From 2d32d2aba533a6073ea3c54c0d49b8e2af4cc528 Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Thu, 7 Apr 2022 20:02:33 -0400 Subject: [PATCH 013/172] fix crash when using keyboard controls (#1286) --- game/system/newpad.cpp | 51 +++++++++++++++++------------------------- game/system/newpad.h | 5 ----- 2 files changed, 21 insertions(+), 35 deletions(-) diff --git a/game/system/newpad.cpp b/game/system/newpad.cpp index 07bbbf5046..920f634d1e 100644 --- a/game/system/newpad.cpp +++ b/game/system/newpad.cpp @@ -6,9 +6,8 @@ #include "newpad.h" #include "common/log/log.h" - +#include "common/util/Assert.h" #include "game/graphics/pipelines/opengl.h" // for GLFW macros -#include "game/kernel/kscheme.h" namespace Pad { @@ -18,8 +17,11 @@ namespace Pad { ******************************** */ -std::unordered_map g_key_status; -std::unordered_map g_buffered_key_status; +constexpr int NUM_KEYS = GLFW_KEY_LAST + 1; +// key-down status of any detected key. +bool g_key_status[NUM_KEYS] = {0}; +// key-down status of any detected key. this is buffered for the remainder of a frame. +bool g_buffered_key_status[NUM_KEYS] = {0}; bool g_gamepad_buttons[(int)Button::Max] = {0}; float g_gamepad_analogs[(int)Analog::Max] = {0}; @@ -37,14 +39,17 @@ u64 input_mode_index = 0; MappingInfo g_input_mode_mapping; void ForceClearKeys() { - g_key_status.clear(); - g_buffered_key_status.clear(); + for (auto& key : g_key_status) { + key = false; + } + for (auto& key : g_buffered_key_status) { + key = false; + } } void ClearKeys() { - g_buffered_key_status.clear(); - for (auto& key : g_key_status) { - g_buffered_key_status.insert(std::make_pair(key.first, key.second)); + for (int key = 0; key < NUM_KEYS; key++) { + g_buffered_key_status[key] = g_key_status[key]; } } @@ -62,31 +67,18 @@ void OnKeyPress(int key) { return; } // set absolute key status - if (g_key_status.find(key) == g_key_status.end()) { - g_key_status.insert(std::make_pair(key, 1)); - } else { - g_key_status.at(key) = 1; - } - + ASSERT(key < NUM_KEYS); + g_key_status[key] = true; // set buffered key status - if (g_buffered_key_status.find(key) == g_buffered_key_status.end()) { - g_buffered_key_status.insert(std::make_pair(key, 1)); - } else { - g_buffered_key_status.at(key) = 1; - } + g_buffered_key_status[key] = true; } void OnKeyRelease(int key) { if (input_mode == InputModeStatus::Enabled) { return; } - - // if we come out of input mode, the key wont be found. - if (g_key_status.find(key) == g_key_status.end()) { - return; - } - // set absolute key status - g_key_status.at(key) = 0; + ASSERT(key < NUM_KEYS); + g_key_status[key] = false; } /* @@ -116,9 +108,8 @@ int IsPressed(MappingInfo& mapping, Button button, int pad = 0) { if (key == -1) return 0; auto& keymap = mapping.buffer_mode ? g_buffered_key_status : g_key_status; - if (keymap.find(key) == keymap.end()) - return 0; - return keymap.at(key); + ASSERT(key < NUM_KEYS); + return keymap[key]; } // returns the value of the analog axis (in the future, likely pressure sensitive if we support it?) diff --git a/game/system/newpad.h b/game/system/newpad.h index df7db72f44..de021e833b 100644 --- a/game/system/newpad.h +++ b/game/system/newpad.h @@ -67,11 +67,6 @@ struct MappingInfo { // TODO complex button mapping & key macros (e.g. shift+x for l2+r2 press etc.) }; -// key-down status of any detected key. -extern std::unordered_map g_key_status; -// key-down status of any detected key. this is buffered for the remainder of a frame. -extern std::unordered_map g_buffered_key_status; - void OnKeyPress(int key); void OnKeyRelease(int key); void ForceClearKeys(); From f341be65e9848977158c9a9a2898f0f047a157df Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Sat, 9 Apr 2022 11:46:56 -0400 Subject: [PATCH 014/172] remove old ir1 code (#1287) --- decompiler/CMakeLists.txt | 4 - decompiler/Function/BasicBlocks.h | 5 - decompiler/Function/Function.cpp | 31 - decompiler/Function/Function.h | 10 - decompiler/Function/TypeInspector.cpp | 848 ------ decompiler/Function/TypeInspector.h | 40 - decompiler/IR/BasicOpBuilder.cpp | 2549 ----------------- decompiler/IR/BasicOpBuilder.h | 15 - decompiler/IR/IR.cpp | 1006 ------- decompiler/IR/IR.h | 454 --- decompiler/ObjectFile/LinkedObjectFile.cpp | 23 - decompiler/ObjectFile/ObjectFileDB.cpp | 26 +- decompiler/ObjectFile/ObjectFileDB.h | 1 - decompiler/ObjectFile/ObjectFileDB_IR2.cpp | 1 - decompiler/config.cpp | 1 - decompiler/config.h | 1 - decompiler/config/jak1_ntsc_black_label.jsonc | 3 - decompiler/main.cpp | 7 - test/offline/offline_test_main.cpp | 2 +- 19 files changed, 2 insertions(+), 5025 deletions(-) delete mode 100644 decompiler/Function/TypeInspector.cpp delete mode 100644 decompiler/Function/TypeInspector.h delete mode 100644 decompiler/IR/BasicOpBuilder.cpp delete mode 100644 decompiler/IR/BasicOpBuilder.h delete mode 100644 decompiler/IR/IR.cpp delete mode 100644 decompiler/IR/IR.h diff --git a/decompiler/CMakeLists.txt b/decompiler/CMakeLists.txt index 0e326b9bd5..1f64eabc24 100644 --- a/decompiler/CMakeLists.txt +++ b/decompiler/CMakeLists.txt @@ -37,10 +37,6 @@ add_library( Function/BasicBlocks.cpp Function/CfgVtx.cpp Function/Function.cpp - Function/TypeInspector.cpp - - IR/BasicOpBuilder.cpp - IR/IR.cpp IR2/AtomicOp.cpp IR2/AtomicOpForm.cpp diff --git a/decompiler/Function/BasicBlocks.h b/decompiler/Function/BasicBlocks.h index 5f74c65e83..a9be9ecb5a 100644 --- a/decompiler/Function/BasicBlocks.h +++ b/decompiler/Function/BasicBlocks.h @@ -14,11 +14,6 @@ struct BasicBlock { int start_word; int end_word; - // [start, end) - int start_basic_op = -1; - int end_basic_op = -1; - int basic_op_size() const { return end_basic_op - start_basic_op; } - std::string label_name; std::vector pred; diff --git a/decompiler/Function/Function.cpp b/decompiler/Function/Function.cpp index 30ab73b88c..b04a59688d 100644 --- a/decompiler/Function/Function.cpp +++ b/decompiler/Function/Function.cpp @@ -4,8 +4,6 @@ #include "decompiler/Disasm/InstructionMatching.h" #include "decompiler/ObjectFile/LinkedObjectFile.h" #include "decompiler/util/DecompilerTypeSystem.h" -#include "TypeInspector.h" -#include "decompiler/IR/IR.h" #include "decompiler/IR2/Form.h" #include "common/util/BitUtils.h" #include "common/util/Assert.h" @@ -673,17 +671,6 @@ void Function::find_type_defs(LinkedObjectFile& file, DecompilerTypeSystem& dts) } } -void Function::add_basic_op(std::shared_ptr op, int start_instr, int end_instr) { - op->is_basic_op = true; - ASSERT(end_instr > start_instr); - - for (int i = start_instr; i < end_instr; i++) { - instruction_to_basic_op[i] = basic_ops.size(); - } - basic_op_to_instruction[basic_ops.size()] = start_instr; - basic_ops.push_back(op); -} - bool Function::instr_starts_basic_op(int idx) { auto op = instruction_to_basic_op.find(idx); if (op != instruction_to_basic_op.end()) { @@ -693,10 +680,6 @@ bool Function::instr_starts_basic_op(int idx) { return false; } -std::shared_ptr Function::get_basic_op_at_instr(int idx) { - return basic_ops.at(instruction_to_basic_op.at(idx)); -} - bool Function::instr_starts_atomic_op(int idx) { auto op = ir2.atomic_ops->instruction_to_atomic_op.find(idx); if (op != ir2.atomic_ops->instruction_to_atomic_op.end()) { @@ -710,20 +693,6 @@ const AtomicOp& Function::get_atomic_op_at_instr(int idx) { return *ir2.atomic_ops->ops.at(ir2.atomic_ops->instruction_to_atomic_op.at(idx)); } -int Function::get_basic_op_count() { - return basic_ops.size(); -} - -int Function::get_failed_basic_op_count() { - int count = 0; - for (auto& x : basic_ops) { - if (dynamic_cast(x.get())) { - count++; - } - } - return count; -} - /*! * Topological sort of basic blocks. * Returns a valid ordering + a list of blocks that you can't reach and therefore diff --git a/decompiler/Function/Function.h b/decompiler/Function/Function.h index e9cc7bb75b..6d8f37f084 100644 --- a/decompiler/Function/Function.h +++ b/decompiler/Function/Function.h @@ -17,8 +17,6 @@ namespace decompiler { class DecompilerTypeSystem; -class IR_Atomic; -class IR; struct FunctionName { enum class FunctionKind { @@ -104,21 +102,14 @@ class Function { void find_global_function_defs(LinkedObjectFile& file, DecompilerTypeSystem& dts); void find_method_defs(LinkedObjectFile& file, DecompilerTypeSystem& dts); void find_type_defs(LinkedObjectFile& file, DecompilerTypeSystem& dts); - void add_basic_op(std::shared_ptr op, int start_instr, int end_instr); - bool has_basic_ops() { return !basic_ops.empty(); } bool instr_starts_basic_op(int idx); - std::shared_ptr get_basic_op_at_instr(int idx); bool instr_starts_atomic_op(int idx); const AtomicOp& get_atomic_op_at_instr(int idx); - int get_basic_op_count(); - int get_failed_basic_op_count(); BlockTopologicalSort bb_topo_sort(); std::string name() const; TypeSpec type; - std::shared_ptr ir = nullptr; - int segment = -1; int start_word = -1; int end_word = -1; // not inclusive, but does include padding. @@ -175,7 +166,6 @@ class Function { } prologue; bool uses_fp_register = false; - std::vector> basic_ops; struct { bool atomic_ops_attempted = false; diff --git a/decompiler/Function/TypeInspector.cpp b/decompiler/Function/TypeInspector.cpp deleted file mode 100644 index 14063623c2..0000000000 --- a/decompiler/Function/TypeInspector.cpp +++ /dev/null @@ -1,848 +0,0 @@ -#include "decompiler/config.h" -#include "decompiler/Disasm/InstructionMatching.h" -#include "TypeInspector.h" -#include "Function.h" -#include "decompiler/ObjectFile/LinkedObjectFile.h" -#include "third-party/fmt/core.h" -#include "decompiler/util/DecompilerTypeSystem.h" -#include "common/type_system/deftype.h" -#include "decompiler/IR/IR.h" - -namespace decompiler { -namespace { -struct FieldPrint { - char format = '\0'; - std::string field_name; - std::string field_type_name; - bool has_array = false; - int array_size = -1; -}; - -FieldPrint get_field_print(const std::string& str) { - int idx = 0; - auto next = [&]() { return str.at(idx++); }; - - auto peek = [&](int off) { return str.at(idx + off); }; - - FieldPrint field_print; - - // first is ~T - char c0 = next(); - ASSERT(c0 == '~'); - char c1 = next(); - ASSERT(c1 == 'T'); - - // next the name: - char name_char = next(); - while (name_char != ':' && name_char != '[') { - field_print.field_name.push_back(name_char); - name_char = next(); - } - - // possibly array thing - if (name_char == '[') { - int size = 0; - char num_char = next(); - while (num_char >= '0' && num_char <= '9') { - size = size * 10 + (num_char - '0'); - num_char = next(); - } - field_print.has_array = true; - field_print.array_size = size; - - ASSERT(num_char == ']'); - char c = next(); - ASSERT(c == ' '); - c = next(); - ASSERT(c == '@'); - c = next(); - ASSERT(c == ' '); - c = next(); - ASSERT(c == '#'); - c = next(); - ASSERT(c == 'x'); - } else { - // next a space - char space_char = next(); - ASSERT(space_char == ' '); - } - - // next the format - char fmt1 = next(); - if (fmt1 == '~' && peek(0) != '`') { // normal ~_~% - char fmt_code = next(); - field_print.format = fmt_code; - char end1 = next(); - ASSERT(end1 == '~'); - char end2 = next(); - ASSERT(end2 == '%'); - ASSERT(idx == (int)str.size()); - } else if (fmt1 == '#' && peek(0) == '<') { // struct #~% - next(); - char type_name_c = next(); - while (type_name_c != ' ') { - field_print.field_type_name += type_name_c; - type_name_c = next(); - } - - std::string expect_end = "@ #x~X>~%"; - for (char i : expect_end) { - char c = next(); - ASSERT(i == c); - } - field_print.format = 'X'; - - ASSERT(idx == (int)str.size()); - } else if (fmt1 == '#' && peek(0) == 'x') { // #x~X~% - next(); - std::string expect_end = "~X~%"; - for (char i : expect_end) { - char c = next(); - ASSERT(i == c); - } - field_print.format = 'X'; - } else if (fmt1 == '~' && peek(0) == '`') { // ~`my-type-with-overriden-print`P~% - next(); - char type_name_c = next(); - while (type_name_c != '`') { - field_print.field_type_name += type_name_c; - type_name_c = next(); - } - - std::string expect_end = "P~%"; - for (char i : expect_end) { - char c = next(); - ASSERT(i == c); - } - field_print.format = 'P'; - - ASSERT(idx == (int)str.size()); - } else if (str.substr(idx - 1) == "(meters ~m)~%") { - field_print.format = 'm'; - } else if (str.substr(idx - 1) == "(deg ~r)~%") { - field_print.format = 'r'; - } else if (str.substr(idx - 1) == "(seconds ~e)~%") { - field_print.format = 'e'; - } - - else { - throw std::runtime_error("other format nyi in get_field_print " + str.substr(idx)); - } - - return field_print; -} - -bool is_int(IR* ir, s64 value) { - auto as_int = dynamic_cast(ir); - return as_int && as_int->value == value; -} - -bool is_reg(IR* ir, Register reg) { - auto as_reg = dynamic_cast(ir); - return as_reg && as_reg->reg == reg; -} - -bool is_math_reg_constant(IR* ir, IR_IntMath2::Kind kind, Register src0, s64 src1) { - auto as_math = dynamic_cast(ir); - return as_math && as_math->kind == kind && is_reg(as_math->arg0.get(), src0) && - is_int(as_math->arg1.get(), src1); -} - -bool is_load_with_offset(IR* ir, IR_Load::Kind kind, int load_size, Register base, s64 offset) { - auto as_load = dynamic_cast(ir); - return as_load && as_load->kind == kind && as_load->size == load_size && - is_math_reg_constant(as_load->location.get(), IR_IntMath2::ADD, base, offset); -} - -bool is_get_load_with_offset(IR* ir, - Register dst, - IR_Load::Kind kind, - int load_size, - Register base, - s64 offset) { - auto as_set = dynamic_cast(ir); - return as_set && is_reg(as_set->dst.get(), dst) && - is_load_with_offset(as_set->src.get(), kind, load_size, base, offset); -} - -struct LoadInfo { - int offset = 0; - int size = 0; - IR_Load::Kind kind; -}; - -LoadInfo get_load_info_from_set(IR* load) { - auto as_set = dynamic_cast(load); - ASSERT(as_set); - auto as_load = dynamic_cast(as_set->src.get()); - ASSERT(as_load); - LoadInfo info; - info.kind = as_load->kind; - info.size = as_load->size; - if (dynamic_cast(as_load->location.get())) { - info.offset = 0; - return info; - } - - auto as_math = dynamic_cast(as_load->location.get()); - ASSERT(as_math); - ASSERT(as_math->kind == IR_IntMath2::ADD); - auto as_int = dynamic_cast(as_math->arg1.get()); - ASSERT(as_int); - info.offset = as_int->value; - return info; -} - -Register get_base_of_load(IR_Load* load) { - auto as_reg = dynamic_cast(load->location.get()); - if (as_reg) { - return as_reg->reg; - } - - auto as_math = dynamic_cast(load->location.get()); - ASSERT(as_math->kind == IR_IntMath2::ADD); - ASSERT(dynamic_cast(as_math->arg1.get())); - auto math_reg = dynamic_cast(as_math->arg0.get()); - if (math_reg) { - return math_reg->reg; - } else { - ASSERT(false); - } - return {}; -} - -bool is_load_with_base(IR* ir, Register base) { - auto as_load = dynamic_cast(ir); - return as_load && base == get_base_of_load(as_load); -} - -bool is_get_load(IR* ir, Register dst, Register base) { - auto as_set = dynamic_cast(ir); - return as_set && is_reg(as_set->dst.get(), dst) && is_load_with_base(as_set->src.get(), base); -} - -bool is_reg_reg_move(IR* ir, Register dst, Register src) { - auto as_set = dynamic_cast(ir); - return as_set && is_reg(as_set->dst.get(), dst) && is_reg(as_set->src.get(), src); -} - -bool is_sym_value(IR* ir, const std::string& sym_name) { - auto as_sym_value = dynamic_cast(ir); - return as_sym_value && as_sym_value->name == sym_name; -} - -bool is_sym(IR* ir, const std::string& sym_name) { - auto as_sym = dynamic_cast(ir); - return as_sym && as_sym->name == sym_name; -} - -bool is_get_sym_value(IR* ir, Register dst, const std::string& sym_name) { - auto as_set = dynamic_cast(ir); - return as_set && is_reg(as_set->dst.get(), dst) && is_sym_value(as_set->src.get(), sym_name); -} - -bool is_get_sym(IR* ir, Register dst, const std::string& sym_name) { - auto as_set = dynamic_cast(ir); - return as_set && is_reg(as_set->dst.get(), dst) && is_sym(as_set->src.get(), sym_name); -} - -bool is_label(IR* ir) { - return dynamic_cast(ir); -} - -bool is_get_label(IR* ir, Register dst) { - auto as_set = dynamic_cast(ir); - return as_set && is_reg(as_set->dst.get(), dst) && is_label(as_set->src.get()); -} - -int get_label_id_of_set(IR* ir) { - return dynamic_cast(dynamic_cast(ir)->src.get())->label_id; -} - -bool is_set_shift(IR* ir) { - auto as_set = dynamic_cast(ir); - if (as_set) { - auto as_math = dynamic_cast(as_set->src.get()); - if (as_math && (as_math->kind == IR_IntMath2::LEFT_SHIFT || - as_math->kind == IR_IntMath2::RIGHT_SHIFT_LOGIC || - as_math->kind == IR_IntMath2::RIGHT_SHIFT_ARITH)) { - return true; - } - } - - auto as_asm = dynamic_cast(ir); - return as_asm && as_asm->name == "sllv"; -} - -bool get_ptr_offset_constant_nonzero(IR_IntMath2* math, Register base, int* result) { - if (!is_reg(math->arg0.get(), base)) { - return false; - } - - auto as_int = dynamic_cast(math->arg1.get()); - if (!as_int) { - return false; - } - - *result = as_int->value; - return true; -} - -bool get_ptr_offset_zero(IR_IntMath2* math, Register base, int* result) { - if (!is_reg(math->arg0.get(), make_gpr(Reg::R0)) || !is_reg(math->arg1.get(), base)) { - return false; - } - *result = 0; - return true; -} - -bool get_ptr_offset(IR* ir, Register dst, Register base, int* result) { - auto as_set = dynamic_cast(ir); - if (!as_set) { - return false; - } - - if (!is_reg(as_set->dst.get(), dst)) { - return false; - } - - auto as_math = dynamic_cast(as_set->src.get()); - if (!as_math) { - return false; - } - return get_ptr_offset_constant_nonzero(as_math, base, result) || - get_ptr_offset_zero(as_math, base, result); -} - -int get_start_idx(Function& function, - LinkedObjectFile& file, - TypeInspectorResult* result, - const std::string& parent_type) { - if (function.basic_blocks.size() > 1) { - result->warnings += " too many basic blocks"; - return 0; - } - - /* - ;; for a basic - or gp, a0, r0 ;; (set! gp a0) - lw t9, format(s7) ;; (set! t9 format) - daddiu a0, s7, #t ;; (set! a0 '#t) - daddiu a1, fp, L362 ;; (set! a1 L362) "[~8x] ~A~%" - or a2, gp, r0 ;; (set! a2 gp) - lwu a3, -4(gp) ;; (set! a3 (l.wu (+.i gp -4))) - jalr ra, t9 ;; (call!) - sll v0, ra, 0 - ;; for a struct - or gp, a0, r0 ;; (set! gp a0) - lw t9, format(s7) ;; (set! t9 format) - daddiu a0, s7, #t ;; (set! a0 '#t) - daddiu a1, fp, L79 ;; (set! a1 L79) "[~8x] ~A~%" - or a2, gp, r0 ;; (set! a2 gp) - daddiu a3, s7, dead-pool-heap-rec;; (set! a3 'dead-pool-heap-rec) - jalr ra, t9 ;; (call!) - */ - - // check size - if (function.basic_ops.size() < 7) { - result->warnings += " not enough basic ops"; - return 0; - } - - auto& move_op = function.basic_ops.at(0); - if (!is_reg_reg_move(move_op.get(), make_gpr(Reg::GP), make_gpr(Reg::A0))) { - result->warnings += "bad first move"; - return 0; - } - - auto& get_format_op = function.basic_ops.at(1); - - if (is_get_sym_value(get_format_op.get(), make_gpr(Reg::T9), "format")) { - auto& get_true = function.basic_ops.at(2); - if (!is_get_sym(get_true.get(), make_gpr(Reg::A0), "#t")) { - result->warnings += "bad get true"; - return 0; - } - - auto& get_str = function.basic_ops.at(3); - if (!is_get_label(get_str.get(), make_gpr(Reg::A1))) { - result->warnings += "bad get label"; - return 0; - } - - auto str = file.get_goal_string_by_label(file.labels.at(get_label_id_of_set(get_str.get()))); - if (str != "[~8x] ~A~%") { - result->warnings += "bad type dec string: " + str; - return 0; - } - - auto& move2_op = function.basic_ops.at(4); - if (!is_reg_reg_move(move2_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP))) { - result->warnings += "bad second move"; - return 0; - } - - auto& load_op = function.basic_ops.at(5); - bool is_basic_load = is_get_load_with_offset(load_op.get(), make_gpr(Reg::A3), - IR_Load::UNSIGNED, 4, make_gpr(Reg::GP), -4); - result->is_basic = is_basic_load; - - bool is_struct_load = is_get_sym(load_op.get(), make_gpr(Reg::A3), function.method_of_type); - - if (!is_basic_load && !is_struct_load) { - result->warnings += "bad load"; - return 0; - } - - auto& call = function.basic_ops.at(6); - if (!dynamic_cast(call.get())) { - result->warnings += "bad call"; - return 0; - } - - // okay! - return 7; - } else { - if (is_get_sym_value(get_format_op.get(), make_gpr(Reg::V1), parent_type)) { - // now get the inspect method. - auto& get_method_op = function.basic_ops.at(2); - if (!is_get_load_with_offset(get_method_op.get(), make_gpr(Reg::T9), IR_Load::UNSIGNED, 4, - make_gpr(Reg::V1), 28)) { - result->warnings += "bad get method op " + get_method_op->print(file); - return 0; - } - - auto& move2_op = function.basic_ops.at(3); - if (!is_reg_reg_move(move2_op.get(), make_gpr(Reg::A0), make_gpr(Reg::GP))) { - result->warnings += "bad move2 op " + move2_op->print(file); - return 0; - } - - auto& call_op = function.basic_ops.at(4); - if (!dynamic_cast(call_op.get())) { - result->warnings += "bad call op " + call_op->print(file); - return 0; - } - - result->warnings += "inherited inpspect of " + parent_type; - result->is_basic = true; - return 5; - - } else { - result->warnings += - "unrecognized get op: " + get_format_op->print(file) + " parent was " + parent_type; - return 0; - } - } -} - -int identify_basic_field(int idx, - Function& function, - LinkedObjectFile& file, - TypeInspectorResult* result, - FieldPrint& print_info) { - (void)file; - auto load_info = get_load_info_from_set(function.basic_ops.at(idx++).get()); - ASSERT(load_info.size == 4); - ASSERT(load_info.kind == IR_Load::UNSIGNED || load_info.kind == IR_Load::SIGNED); - - if (load_info.kind == IR_Load::SIGNED) { - result->warnings += "field " + print_info.field_name + " is a basic loaded with a signed load "; - } - - int offset = load_info.offset; - if (result->is_basic) { - offset += BASIC_OFFSET; - } - - Field field(print_info.field_name, TypeSpec("basic"), offset); - result->fields_of_type.push_back(field); - return idx; -} - -int identify_pointer_field(int idx, - Function& function, - LinkedObjectFile& file, - TypeInspectorResult* result, - FieldPrint& print_info) { - (void)file; - auto load_info = get_load_info_from_set(function.basic_ops.at(idx++).get()); - ASSERT(load_info.size == 4); - ASSERT(load_info.kind == IR_Load::UNSIGNED); - - int offset = load_info.offset; - if (result->is_basic) { - offset += BASIC_OFFSET; - } - - Field field(print_info.field_name, TypeSpec("pointer"), offset); - result->fields_of_type.push_back(field); - return idx; -} - -int identify_array_field(int idx, - Function& function, - LinkedObjectFile& file, - TypeInspectorResult* result, - FieldPrint& print_info) { - auto& get_op = function.basic_ops.at(idx++); - int offset = 0; - if (!get_ptr_offset(get_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP), &offset)) { - printf("bad get ptr offset %s\n", get_op->print(file).c_str()); - ASSERT(false); - } - if (result->is_basic) { - offset += BASIC_OFFSET; - } - - Field field(print_info.field_name, TypeSpec("UNKNOWN"), offset); - if (print_info.array_size) { - field.set_array(print_info.array_size); - } else { - field.set_dynamic(); - } - result->fields_of_type.push_back(field); - return idx; -} - -int identify_float_field(int idx, - Function& function, - LinkedObjectFile& file, - TypeInspectorResult* result, - FieldPrint& print_info) { - auto load_info = get_load_info_from_set(function.basic_ops.at(idx++).get()); - ASSERT(load_info.size == 4); - ASSERT(load_info.kind == IR_Load::FLOAT); - - auto& float_move = function.basic_ops.at(idx++); - if (!is_reg_reg_move(float_move.get(), make_gpr(Reg::A2), make_fpr(0))) { - printf("bad float move: %s\n", float_move->print(file).c_str()); - ASSERT(false); - } - - std::string type; - switch (print_info.format) { - case 'f': - type = "float"; - break; - case 'm': - type = "meters"; - break; - case 'r': - type = "deg"; - break; - case 'X': - type = "float"; - result->warnings += "field " + print_info.field_name + " is a float printed as hex? "; - break; - default: - ASSERT(false); - } - int offset = load_info.offset; - if (result->is_basic) { - offset += BASIC_OFFSET; - } - - Field field(print_info.field_name, TypeSpec(type), offset); - result->fields_of_type.push_back(field); - return idx; -} - -int identify_struct_not_inline_field(int idx, - Function& function, - LinkedObjectFile& file, - TypeInspectorResult* result, - FieldPrint& print_info) { - (void)file; - auto load_info = get_load_info_from_set(function.basic_ops.at(idx++).get()); - - if (!(load_info.size == 4 && load_info.kind == IR_Load::UNSIGNED)) { - result->warnings += "field " + print_info.field_type_name + " is likely a value type"; - } - int offset = load_info.offset; - if (result->is_basic) { - offset += BASIC_OFFSET; - } - - Field field(print_info.field_name, TypeSpec(print_info.field_type_name), offset); - result->fields_of_type.push_back(field); - return idx; -} - -int identify_struct_inline_field(int idx, - Function& function, - LinkedObjectFile& file, - TypeInspectorResult* result, - FieldPrint& print_info) { - auto& get_op = function.basic_ops.at(idx++); - int offset = 0; - if (!get_ptr_offset(get_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP), &offset)) { - printf("bad get ptr offset %s\n", get_op->print(file).c_str()); - ASSERT(false); - } - if (result->is_basic) { - offset += BASIC_OFFSET; - } - - Field field(print_info.field_name, TypeSpec(print_info.field_type_name), offset); - field.set_inline(); - result->fields_of_type.push_back(field); - return idx; -} - -int identify_int_field(int idx, - Function& function, - LinkedObjectFile& file, - TypeInspectorResult* result, - FieldPrint& print_info) { - (void)file; - auto load_info = get_load_info_from_set(function.basic_ops.at(idx++).get()); - - std::string field_type_name; - if (load_info.kind == IR_Load::UNSIGNED) { - field_type_name += "u"; - } else if (load_info.kind == IR_Load::FLOAT) { - ASSERT(false); // ... - } - field_type_name += "int"; - - switch (load_info.size) { - case 1: - field_type_name += "8"; - break; - case 2: - field_type_name += "16"; - break; - case 4: - field_type_name += "32"; - break; - case 8: - field_type_name += "64"; - break; - case 16: - field_type_name += "128"; - break; - default: - throw std::runtime_error("unknown load op size in identify int field " + - std::to_string((int)load_info.size)); - } - - if (print_info.format == 'e') { - switch (load_info.kind) { - case IR_Load::SIGNED: - field_type_name = "sseconds"; - break; - case IR_Load::UNSIGNED: - field_type_name = "useconds"; - break; - default: - ASSERT(false); - } - ASSERT(load_info.size == 8); - } - - int offset = load_info.offset; - if (result->is_basic) { - offset += BASIC_OFFSET; - } - - Field field(print_info.field_name, TypeSpec(field_type_name), offset); - result->fields_of_type.push_back(field); - - return idx; -} - -int detect(int idx, Function& function, LinkedObjectFile& file, TypeInspectorResult* result) { - auto& get_format_op = function.basic_ops.at(idx++); - if (!is_get_sym_value(get_format_op.get(), make_gpr(Reg::T9), "format")) { - printf("bad get format"); - ASSERT(false); - } - - auto& get_true = function.basic_ops.at(idx++); - if (!is_get_sym(get_true.get(), make_gpr(Reg::A0), "#t")) { - printf("bad get true"); - ASSERT(false); - } - - auto& get_str = function.basic_ops.at(idx++); - if (!is_get_label(get_str.get(), make_gpr(Reg::A1))) { - result->warnings += "bad get label"; - return true; - } - - auto str = file.get_goal_string_by_label(file.labels.at(get_label_id_of_set(get_str.get()))); - auto info = get_field_print(str); - - auto& first_get_op = function.basic_ops.at(idx); - - if (is_get_load(first_get_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP)) && - (info.format == 'D' || info.format == 'X' || info.format == 'e') && !info.has_array && - info.field_type_name.empty()) { - idx = identify_int_field(idx, function, file, result, info); - // it's a load! - } else if (is_get_load(first_get_op.get(), make_fpr(0), make_gpr(Reg::GP)) && - (info.format == 'f' || info.format == 'm' || info.format == 'r' || - info.format == 'X') && - !info.has_array && info.field_type_name.empty()) { - idx = identify_float_field(idx, function, file, result, info); - } else if (is_get_load(first_get_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP)) && - info.format == 'A' && !info.has_array && info.field_type_name.empty()) { - idx = identify_basic_field(idx, function, file, result, info); - } else if (is_get_load(first_get_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP)) && - info.format == 'X' && !info.has_array && info.field_type_name.empty()) { - idx = identify_pointer_field(idx, function, file, result, info); - } else if (info.has_array && (info.format == 'X' || info.format == 'P') && - info.field_type_name.empty()) { - idx = identify_array_field(idx, function, file, result, info); - } else if (!info.has_array && (info.format == 'X' || info.format == 'P') && - !info.field_type_name.empty()) { - // structure. - if (is_get_load(first_get_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP))) { - // not inline - idx = identify_struct_not_inline_field(idx, function, file, result, info); - } else { - idx = identify_struct_inline_field(idx, function, file, result, info); - } - } - - else if (is_set_shift(first_get_op.get())) { - result->warnings += "likely a bitfield type"; - return -1; - } else { - printf("couldn't do %s, %s\n", str.c_str(), first_get_op->print(file).c_str()); - return -1; - } - - auto& call_op = function.basic_ops.at(idx++); - if (!dynamic_cast(call_op.get())) { - printf("bad call\n"); - ASSERT(false); - } - - return idx; -} -} // namespace - -TypeInspectorResult inspect_inspect_method(Function& inspect, - const std::string& type_name, - DecompilerTypeSystem& dts, - LinkedObjectFile& file, - bool skip_fields) { - TypeInspectorResult result; - TypeFlags flags; - flags.flag = 0; - dts.lookup_flags(type_name, &flags.flag); - result.type_name = type_name; - result.parent_type_name = dts.lookup_parent_from_inspects(type_name); - result.flags = flags.flag; - result.type_size = flags.size; - result.type_method_count = flags.methods; - result.type_heap_base = flags.heap_base; - ASSERT(flags.pad == 0); - - int idx = get_start_idx(inspect, file, &result, result.parent_type_name); - if (idx == 0 || skip_fields) { - // printf("was weird: %s\n", result.warnings.c_str()); - return result; - } - while (idx < int(inspect.basic_ops.size()) - 1 && idx != -1) { - idx = detect(idx, inspect, file, &result); - } - - // todo, continue to identify fields, then identify the return. - - result.success = true; - return result; -} - -std::string TypeInspectorResult::print_as_deftype() { - std::string result; - - result += fmt::format("(deftype {} ({})\n (", type_name, parent_type_name); - - int longest_field_name = 0; - int longest_type_name = 0; - int longest_mods = 0; - - std::string inline_string = ":inline"; - std::string dynamic_string = ":dynamic"; - - for (auto& field : fields_of_type) { - longest_field_name = std::max(longest_field_name, int(field.name().size())); - longest_type_name = std::max(longest_type_name, int(field.type().print().size())); - - int mods = 0; - // mods are array size, :inline, :dynamic - if (field.is_array() && !field.is_dynamic()) { - mods += std::to_string(field.array_size()).size(); - } - - if (field.is_inline()) { - if (mods) { - mods++; // space - } - mods += inline_string.size(); - } - - if (field.is_dynamic()) { - if (mods) { - mods++; // space - } - mods += dynamic_string.size(); - } - longest_mods = std::max(longest_mods, mods); - } - - for (auto& field : fields_of_type) { - result += "("; - result += field.name(); - result.append(1 + (longest_field_name - int(field.name().size())), ' '); - result += field.type().print(); - result.append(1 + (longest_type_name - int(field.type().print().size())), ' '); - - std::string mods; - if (field.is_array() && !field.is_dynamic()) { - mods += std::to_string(field.array_size()); - mods += " "; - } - - if (field.is_inline()) { - mods += inline_string; - mods += " "; - } - - if (field.is_dynamic()) { - mods += dynamic_string; - mods += " "; - } - result.append(mods); - result.append(longest_mods - int(mods.size() - 1), ' '); - - result.append(":offset-assert "); - result.append(std::to_string(field.offset())); - result.append(")\n "); - } - result.append(")\n"); - - result.append(fmt::format(" :method-count-assert {}\n", type_method_count)); - result.append(fmt::format(" :size-assert #x{:x}\n", type_size)); - result.append(fmt::format(" :flag-assert #x{:x}\n ", flags)); - if (!warnings.empty()) { - result.append(";; "); - result.append(warnings); - result.append("\n "); - } - - if (type_method_count > 9) { - result.append("(:methods\n "); - for (int i = 9; i < type_method_count; i++) { - result.append(fmt::format("(dummy-{} () none {})\n ", i, i)); - } - result.append(")\n "); - } - result.append(")\n"); - - return result; -} -} // namespace decompiler \ No newline at end of file diff --git a/decompiler/Function/TypeInspector.h b/decompiler/Function/TypeInspector.h deleted file mode 100644 index cb3bd3c855..0000000000 --- a/decompiler/Function/TypeInspector.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -/*! - * @file TypeInspector.h - * Analyze an auto-generated GOAL inspect method to determine the layout of a type in memory. - */ - -#include -#include "common/common_types.h" - -class Field; - -namespace decompiler { -class Function; -class DecompilerTypeSystem; -class LinkedObjectFile; - -struct TypeInspectorResult { - bool success = false; - int type_size = -1; - int type_method_count = -1; - int type_heap_base = -1; - - std::string warnings; - std::vector fields_of_type; - bool is_basic = false; - - std::string type_name; - std::string parent_type_name; - u64 flags = 0; - - std::string print_as_deftype(); -}; - -TypeInspectorResult inspect_inspect_method(Function& inspect, - const std::string& type_name, - DecompilerTypeSystem& dts, - LinkedObjectFile& file, - bool skip_fields); -} // namespace decompiler \ No newline at end of file diff --git a/decompiler/IR/BasicOpBuilder.cpp b/decompiler/IR/BasicOpBuilder.cpp deleted file mode 100644 index 3fec5e6f1a..0000000000 --- a/decompiler/IR/BasicOpBuilder.cpp +++ /dev/null @@ -1,2549 +0,0 @@ -/*! - * @file BasicOpBuilder.cpp - * Convert a basic block into a sequence of IR operations. - * Build up basic set instructions from GOAL code - * Recognize common GOAL compiler idioms - * Recognize branch delay slot use - * Recognize assembly ops and pass them through as IR_Asm - */ - -#include "BasicOpBuilder.h" -#include "decompiler/Function/Function.h" -#include "decompiler/Function/BasicBlocks.h" -#include "decompiler/Disasm/InstructionMatching.h" -#include "decompiler/ObjectFile/LinkedObjectFile.h" -#include "decompiler/IR/IR.h" -#include "common/symbols.h" - -namespace decompiler { -namespace { - -/////////////////////////////// -// Helpers -/////////////////////////////// - -/*! - * Create a GOAL "set!" form. - * These will later be compacted into more complicated nested expressions. - */ -std::shared_ptr make_set_atomic(IR_Set_Atomic::Kind kind, - const std::shared_ptr& dst, - const std::shared_ptr& src) { - return std::make_shared(kind, dst, src); -} - -/*! - * Create an IR representing a register at a certain point. Idx is the instruction index. - */ -std::shared_ptr make_reg(Register reg, int idx) { - return std::make_shared(reg, idx); -} - -/*! - * Create an IR representing a symbol. The symbol itself ('thing), not the value. - */ -std::shared_ptr make_sym(const std::string& name) { - return std::make_shared(name); -} - -/*! - * Create an IR representing the value of a symbol. Can be read/written. - */ -std::shared_ptr make_sym_value(const std::string& name) { - return std::make_shared(name); -} - -/*! - * Create an integer constant. - */ -std::shared_ptr make_int(int64_t x) { - return std::make_shared(x); -} - -/*! - * Create an assembly passthrough in the form op dst, src, src. Sets register info. - */ -std::shared_ptr to_asm_reg_reg_reg(const std::string& str, Instruction& instr, int idx) { - auto result = std::make_shared(str); - result->dst = make_reg(instr.get_dst(0).get_reg(), idx); - result->src0 = make_reg(instr.get_src(0).get_reg(), idx); - result->src1 = make_reg(instr.get_src(1).get_reg(), idx); - result->set_reg_info(); - return result; -} - -/*! - * Create an assembly passthrough for op src. Sets register info. - */ -std::shared_ptr to_asm_src_reg(const std::string& str, Instruction& instr, int idx) { - auto result = std::make_shared(str); - result->src0 = make_reg(instr.get_src(0).get_reg(), idx); - result->set_reg_info(); - return result; -} - -/*! - * Create an assembly passthrough for op dst src. Sets register info. - */ -std::shared_ptr to_asm_dst_reg_src_reg(const std::string& str, - Instruction& instr, - int idx) { - auto result = std::make_shared(str); - result->dst = make_reg(instr.get_dst(0).get_reg(), idx); - result->src0 = make_reg(instr.get_src(0).get_reg(), idx); - result->set_reg_info(); - return result; -} - -/*! - * Convert an instruction atom to IR. - */ -std::shared_ptr instr_atom_to_ir(const InstructionAtom& ia, int idx) { - switch (ia.kind) { - case InstructionAtom::REGISTER: - return make_reg(ia.get_reg(), idx); - case InstructionAtom::VU_Q: - return std::make_shared(IR_AsmReg::VU_Q); - case InstructionAtom::VU_ACC: - return std::make_shared(IR_AsmReg::VU_ACC); - case InstructionAtom::IMM: - return make_int(ia.get_imm()); - case InstructionAtom::VF_FIELD: - // not supported by IR1 - return std::make_shared(); - default: - ASSERT(false); - return nullptr; - } -} - -/////////////////////////////// -// Assembly -/////////////////////////////// - -/*! - * Convert an assembly operation to a IR. Sets register info. - */ -std::shared_ptr to_asm_automatic(const std::string& str, Instruction& instr, int idx) { - auto result = std::make_shared(str); - if (instr.n_src >= 4) { - // not supported by IR1 - return std::make_shared(); - } - ASSERT(instr.n_dst < 2); - ASSERT(instr.n_src < 4); - if (instr.n_dst >= 1) { - result->dst = instr_atom_to_ir(instr.get_dst(0), idx); - } - - if (instr.n_src >= 1) { - result->src0 = instr_atom_to_ir(instr.get_src(0), idx); - } - - if (instr.n_src >= 2) { - result->src1 = instr_atom_to_ir(instr.get_src(1), idx); - } - - if (instr.n_src >= 3) { - result->src2 = instr_atom_to_ir(instr.get_src(2), idx); - } - - result->set_reg_info(); - return result; -} - -/*! - * Convert subu instruction to assembly op. GOAL doesn't generate subu's without inline assembly. - */ -std::shared_ptr try_subu(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::SUBU, {}, {}, {})) { - return to_asm_reg_reg_reg("subu", instr, idx); - } - return nullptr; -} - -/*! - * Convert sllv instruction to assembly op. GOAL doesn't generate sllv's without inline assembly. - */ -std::shared_ptr try_sllv(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::SLLV, {}, {}, make_gpr(Reg::R0))) { - return to_asm_reg_reg_reg("sllv", instr, idx); - } - return nullptr; -} - -/////////////////////////////// -// Logical -/////////////////////////////// - -/*! - * OR (logical or of registers) is used three ways: - * 1. set a register to #f - * 2. set a register to the value of another register - * 3. logical OR - */ -std::shared_ptr try_or(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::OR, {}, make_gpr(Reg::S7), make_gpr(Reg::R0))) { - // set value to #f : or dest, s7, r0 - auto dest = instr.get_dst(0).get_reg(); - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(dest, idx), make_sym("#f")); - op->write_regs.push_back(dest); - op->reg_info_set = true; - return op; - } else if (is_gpr_3(instr, InstructionKind::OR, {}, make_gpr(Reg::R0), make_gpr(Reg::R0))) { - auto dest = instr.get_dst(0).get_reg(); - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(dest, idx), - std::make_shared(0)); - op->write_regs.push_back(dest); - op->reg_info_set = true; - return op; - } else if (is_gpr_3(instr, InstructionKind::OR, {}, {}, make_gpr(Reg::R0))) { - // set register from register : or dest, source, r0 - auto dest = instr.get_dst(0).get_reg(); - auto src = instr.get_src(0).get_reg(); - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(dest, idx), make_reg(src, idx)); - op->write_regs.push_back(dest); - op->read_regs.push_back(src); - op->reg_info_set = true; - return op; - } else { - // actually do a logical OR of two registers. - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::OR, make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 2, 0); - return op; - } - return nullptr; -} - -/*! - * ORI (logical OR of register and 16-bit immediate) is used two ways: - * 1. Set a register to a 16-bit constant - * 2. logical OR with constant - */ -std::shared_ptr try_ori(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::ORI && instr.get_src(0).is_reg(make_gpr(Reg::R0)) && - instr.get_src(1).is_imm()) { - // load a constant. - auto dst = instr.get_dst(0).get_reg(); - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(dst, idx), - make_int(instr.get_src(1).get_imm())); - op->write_regs.push_back(dst); - op->reg_info_set = true; - return op; - } else if (instr.kind == InstructionKind::ORI && instr.get_src(1).is_imm()) { - // do logical OR with a constant. - auto dst = instr.get_dst(0).get_reg(); - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(dst, idx), - std::make_shared(IR_IntMath2::OR, make_reg(instr.get_src(0).get_reg(), idx), - make_int(instr.get_src(1).get_imm()))); - op->write_regs.push_back(dst); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -/*! - * POR - recognize POR as a move between 128-bit registers. - */ -std::shared_ptr try_por(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::POR, {}, {}, make_gpr(Reg::R0))) { - // move a 128-bit integer. - auto dst = instr.get_dst(0).get_reg(); - auto src = instr.get_src(0).get_reg(); - auto op = make_set_atomic(IR_Set_Atomic::REG_I128, make_reg(dst, idx), make_reg(src, idx)); - op->write_regs.push_back(dst); - op->read_regs.push_back(src); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -/////////////////////////////// -// Moves -/////////////////////////////// - -/*! - * MTC1 (move to coprocessor 1) move from GPR to FPR. - */ -std::shared_ptr try_mtc1(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::MTC1) { - auto op = make_set_atomic(IR_Set_Atomic::GPR_TO_FPR, make_reg(instr.get_dst(0).get_reg(), idx), - make_reg(instr.get_src(0).get_reg(), idx)); - op->update_reginfo_regreg(); - return op; - } - return nullptr; -} - -/*! - * MFC1 (move from coprocessor 1) move from FPR to GPR. - */ -std::shared_ptr try_mfc1(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::MFC1) { - auto op = - make_set_atomic(IR_Set_Atomic::FPR_TO_GPR64, make_reg(instr.get_dst(0).get_reg(), idx), - make_reg(instr.get_src(0).get_reg(), idx)); - op->update_reginfo_regreg(); - return op; - } - return nullptr; -} - -/////////////////////////////// -// Loads -/////////////////////////////// - -/*! - * LWC1 : load value into FPR. - * 1. load static float (FP relative) - * 2. load from address - * 3. load at offset from address. - */ -std::shared_ptr try_lwc1(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::LWC1 && instr.get_dst(0).is_reg() && - instr.get_src(0).is_link_or_label() && instr.get_src(1).is_reg(make_gpr(Reg::FP))) { - // fp relative, use an IR_StaticAddress. - auto dst = instr.get_dst(0).get_reg(); - auto op = make_set_atomic( - IR_Set_Atomic::LOAD, make_reg(dst, idx), - std::make_shared( - IR_Load::FLOAT, 4, std::make_shared(instr.get_src(0).get_label()))); - op->write_regs.push_back(dst); - op->reg_info_set = true; - return op; - } else if (instr.kind == InstructionKind::LWC1 && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm() && instr.get_src(0).get_imm() == 0) { - // offset is zero, so eliminate it. - auto dst = instr.get_dst(0).get_reg(); - auto src = instr.get_src(1).get_reg(); - auto op = make_set_atomic(IR_Set_Atomic::LOAD, make_reg(dst, idx), - std::make_shared(IR_Load::FLOAT, 4, make_reg(src, idx))); - op->write_regs.push_back(dst); - op->read_regs.push_back(src); - op->reg_info_set = true; - return op; - } else if (instr.kind == InstructionKind::LWC1 && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm()) { - // nonzero offset, create compound expression to add the offset. - auto dst = instr.get_dst(0).get_reg(); - auto src = instr.get_src(1).get_reg(); - auto op = - make_set_atomic(IR_Set_Atomic::LOAD, make_reg(dst, idx), - std::make_shared( - IR_Load::FLOAT, 4, - std::make_shared( - IR_IntMath2::ADD, make_reg(src, idx), - std::make_shared(instr.get_src(0).get_imm())))); - op->write_regs.push_back(dst); - op->read_regs.push_back(src); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -std::shared_ptr try_lhu(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::LHU && instr.get_dst(0).is_reg() && - instr.get_src(0).is_link_or_label() && instr.get_src(1).is_reg(make_gpr(Reg::FP))) { - // static load - auto op = - make_set_atomic(IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::UNSIGNED, 2, - std::make_shared(instr.get_src(0).get_label()))); - op->update_reginfo_self(1, 0, 0); - return op; - } else if (instr.kind == InstructionKind::LHU && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm() && instr.get_src(0).get_imm() == 0) { - // no offset load - auto op = make_set_atomic( - IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_Load::UNSIGNED, 2, make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 1, 0); - return op; - } else if (instr.kind == InstructionKind::LHU && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm()) { - // load with offset - auto op = - make_set_atomic(IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::UNSIGNED, 2, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(1).get_reg(), idx), - std::make_shared(instr.get_src(0).get_imm())))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_lh(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::LH && instr.get_dst(0).is_reg() && - instr.get_src(0).is_link_or_label() && instr.get_src(1).is_reg(make_gpr(Reg::FP))) { - // static load - auto op = make_set_atomic( - IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::SIGNED, 2, std::make_shared(instr.get_src(0).get_label()))); - op->update_reginfo_self(1, 0, 0); - return op; - } else if (instr.kind == InstructionKind::LH && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm() && instr.get_src(0).get_imm() == 0) { - // no offset load - auto op = make_set_atomic( - IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_Load::SIGNED, 2, make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 1, 0); - return op; - } else if (instr.kind == InstructionKind::LH && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm()) { - // offset load - auto op = - make_set_atomic(IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::SIGNED, 2, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(1).get_reg(), idx), - std::make_shared(instr.get_src(0).get_imm())))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_lb(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::LB && instr.get_dst(0).is_reg() && - instr.get_src(0).is_link_or_label() && instr.get_src(1).is_reg(make_gpr(Reg::FP))) { - // static load - auto op = make_set_atomic( - IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::SIGNED, 1, std::make_shared(instr.get_src(0).get_label()))); - op->update_reginfo_self(1, 0, 0); - return op; - } else if (instr.kind == InstructionKind::LB && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm() && instr.get_src(0).get_imm() == 0) { - // no offset load - auto op = make_set_atomic( - IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_Load::SIGNED, 1, make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 1, 0); - return op; - } else if (instr.kind == InstructionKind::LB && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm()) { - // offset load - auto op = - make_set_atomic(IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::SIGNED, 1, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(1).get_reg(), idx), - std::make_shared(instr.get_src(0).get_imm())))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_lbu(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::LBU && instr.get_dst(0).is_reg() && - instr.get_src(0).is_link_or_label() && instr.get_src(1).is_reg(make_gpr(Reg::FP))) { - // static load - auto op = - make_set_atomic(IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::UNSIGNED, 1, - std::make_shared(instr.get_src(0).get_label()))); - op->update_reginfo_self(1, 0, 0); - return op; - } else if (instr.kind == InstructionKind::LBU && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm() && instr.get_src(0).get_imm() == 0) { - // no offset load - auto op = make_set_atomic( - IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_Load::UNSIGNED, 1, make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 1, 0); - return op; - } else if (instr.kind == InstructionKind::LBU && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm()) { - // offset load - auto op = - make_set_atomic(IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::UNSIGNED, 1, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(1).get_reg(), idx), - std::make_shared(instr.get_src(0).get_imm())))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_ld(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::LD && instr.get_dst(0).is_reg() && - instr.get_src(0).is_link_or_label() && instr.get_src(1).is_reg(make_gpr(Reg::FP))) { - // static load - auto op = - make_set_atomic(IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::UNSIGNED, 8, - std::make_shared(instr.get_src(0).get_label()))); - op->update_reginfo_self(1, 0, 0); - return op; - } else if (instr.kind == InstructionKind::LD && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm() && instr.get_src(0).get_imm() == 0) { - // no offset load - auto op = make_set_atomic( - IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_Load::UNSIGNED, 8, make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 1, 0); - return op; - } else if (instr.kind == InstructionKind::LD && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm()) { - // offset load - auto op = - make_set_atomic(IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::UNSIGNED, 8, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(1).get_reg(), idx), - std::make_shared(instr.get_src(0).get_imm())))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -// TODO SPECIAL -std::shared_ptr try_lw(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::LW && instr.get_dst(0).is_reg(make_gpr(Reg::R0)) && - instr.get_src(0).is_imm() && instr.get_src(0).get_imm() == 2 && - instr.get_src(1).is_reg(make_gpr(Reg::R0))) { - auto op = std::make_shared(); - op->reg_info_set = true; - return op; - } else if (instr.kind == InstructionKind::LW && instr.get_src(1).is_reg(make_gpr(Reg::S7)) && - instr.get_src(0).kind == InstructionAtom::IMM_SYM) { - // symbol load - auto dst = instr.get_dst(0).get_reg(); - auto op = make_set_atomic(IR_Set_Atomic::SYM_LOAD, make_reg(dst, idx), - make_sym_value(instr.get_src(0).get_sym())); - op->write_regs.push_back(dst); - op->reg_info_set = true; - return op; - } else if (instr.kind == InstructionKind::LW && instr.get_dst(0).is_reg() && - instr.get_src(0).is_link_or_label() && instr.get_src(1).is_reg(make_gpr(Reg::FP))) { - // static load - auto op = make_set_atomic( - IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::SIGNED, 4, std::make_shared(instr.get_src(0).get_label()))); - op->update_reginfo_self(1, 0, 0); - return op; - } else if (instr.kind == InstructionKind::LW && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm() && instr.get_src(0).get_imm() == 0) { - // no offset load - auto op = make_set_atomic( - IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_Load::SIGNED, 4, make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 1, 0); - return op; - } else if (instr.kind == InstructionKind::LW && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm()) { - // offset load - auto op = - make_set_atomic(IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::SIGNED, 4, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(1).get_reg(), idx), - std::make_shared(instr.get_src(0).get_imm())))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_lwu(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::LWU && instr.get_dst(0).is_reg() && - instr.get_src(0).is_link_or_label() && instr.get_src(1).is_reg(make_gpr(Reg::FP))) { - // static load - auto op = - make_set_atomic(IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::UNSIGNED, 4, - std::make_shared(instr.get_src(0).get_label()))); - op->update_reginfo_self(1, 0, 0); - return op; - } else if (instr.kind == InstructionKind::LWU && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm() && instr.get_src(0).get_imm() == 0) { - // no offset load - auto op = make_set_atomic( - IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_Load::UNSIGNED, 4, make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 1, 0); - return op; - } else if (instr.kind == InstructionKind::LWU && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm()) { - // offset load - auto op = - make_set_atomic(IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::UNSIGNED, 4, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(1).get_reg(), idx), - std::make_shared(instr.get_src(0).get_imm())))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_lq(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::LQ && instr.get_src(1).is_reg(make_gpr(Reg::S7)) && - instr.get_src(0).kind == InstructionAtom::IMM_SYM) { - ASSERT(false); - } else if (instr.kind == InstructionKind::LQ && instr.get_dst(0).is_reg() && - instr.get_src(0).is_link_or_label() && instr.get_src(1).is_reg(make_gpr(Reg::FP))) { - // static - auto op = - make_set_atomic(IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::UNSIGNED, 16, - std::make_shared(instr.get_src(0).get_label()))); - op->update_reginfo_self(1, 0, 0); - return op; - } else if (instr.kind == InstructionKind::LQ && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm() && instr.get_src(0).get_imm() == 0) { - // no offset - auto op = make_set_atomic(IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_Load::UNSIGNED, 16, - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 1, 0); - return op; - } else if (instr.kind == InstructionKind::LQ && instr.get_dst(0).is_reg() && - instr.get_src(0).is_imm()) { - // offset - auto op = - make_set_atomic(IR_Set_Atomic::LOAD, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared( - IR_Load::UNSIGNED, 16, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(1).get_reg(), idx), - std::make_shared(instr.get_src(0).get_imm())))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_dsll(Instruction& instr, int idx) { - if (is_gpr_2_imm_int(instr, InstructionKind::DSLL, {}, {}, {})) { - auto op = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::LEFT_SHIFT, - make_reg(instr.get_src(0).get_reg(), idx), - make_int(instr.get_src(1).get_imm()))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_dsll32(Instruction& instr, int idx) { - if (is_gpr_2_imm_int(instr, InstructionKind::DSLL32, {}, {}, {})) { - auto op = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::LEFT_SHIFT, - make_reg(instr.get_src(0).get_reg(), idx), - make_int(32 + instr.get_src(1).get_imm()))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_dsra(Instruction& instr, int idx) { - if (is_gpr_2_imm_int(instr, InstructionKind::DSRA, {}, {}, {})) { - auto op = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::RIGHT_SHIFT_ARITH, - make_reg(instr.get_src(0).get_reg(), idx), - make_int(instr.get_src(1).get_imm()))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_dsra32(Instruction& instr, int idx) { - if (is_gpr_2_imm_int(instr, InstructionKind::DSRA32, {}, {}, {})) { - auto op = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::RIGHT_SHIFT_ARITH, - make_reg(instr.get_src(0).get_reg(), idx), - make_int(32 + instr.get_src(1).get_imm()))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_dsrl(Instruction& instr, int idx) { - if (is_gpr_2_imm_int(instr, InstructionKind::DSRL, {}, {}, {})) { - auto op = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::RIGHT_SHIFT_LOGIC, - make_reg(instr.get_src(0).get_reg(), idx), - make_int(instr.get_src(1).get_imm()))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_dsrl32(Instruction& instr, int idx) { - if (is_gpr_2_imm_int(instr, InstructionKind::DSRL32, {}, {}, {})) { - auto op = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::RIGHT_SHIFT_LOGIC, - make_reg(instr.get_src(0).get_reg(), idx), - make_int(32 + instr.get_src(1).get_imm()))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_float_math_2(Instruction& instr, - int idx, - InstructionKind instr_kind, - IR_FloatMath2::Kind ir_kind) { - if (is_gpr_3(instr, instr_kind, {}, {}, {})) { - auto dst = instr.get_dst(0).get_reg(); - auto src0 = instr.get_src(0).get_reg(); - auto src1 = instr.get_src(1).get_reg(); - auto op = make_set_atomic( - IR_Set_Atomic::REG_FLT, make_reg(dst, idx), - std::make_shared(ir_kind, make_reg(src0, idx), make_reg(src1, idx))); - op->write_regs.push_back(dst); - op->read_regs.push_back(src0); - op->read_regs.push_back(src1); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -std::shared_ptr try_daddiu(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::DADDIU && instr.get_src(0).is_reg(make_gpr(Reg::S7)) && - instr.get_src(1).kind == InstructionAtom::IMM_SYM) { - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - make_sym(instr.get_src(1).get_sym())); - op->write_regs.push_back(instr.get_dst(0).get_reg()); - op->reg_info_set = true; - return op; - } else if (instr.kind == InstructionKind::DADDIU && instr.get_src(0).is_reg(make_gpr(Reg::S7)) && - instr.get_src(1).is_imm() && instr.get_src(1).get_imm() == -10) { - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared()); - op->write_regs.push_back(instr.get_dst(0).get_reg()); - op->reg_info_set = true; - return op; - } else if (instr.kind == InstructionKind::DADDIU && instr.get_src(0).is_reg(make_gpr(Reg::S7)) && - instr.get_src(1).is_imm() && instr.get_src(1).get_imm() == -32768) { - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared("__START-OF-TABLE__")); - op->write_regs.push_back(instr.get_dst(0).get_reg()); - op->reg_info_set = true; - return op; - } else if (instr.kind == InstructionKind::DADDIU && instr.get_src(0).is_reg(make_gpr(Reg::S7)) && - instr.get_src(1).is_imm() && instr.get_src(1).get_imm() == FIX_SYM_TRUE) { - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared("#t")); - op->write_regs.push_back(instr.get_dst(0).get_reg()); - op->reg_info_set = true; - return op; - } else if (instr.kind == InstructionKind::DADDIU && instr.get_src(0).is_reg(make_gpr(Reg::FP)) && - instr.get_src(1).kind == InstructionAtom::LABEL) { - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(instr.get_src(1).get_label())); - op->write_regs.push_back(instr.get_dst(0).get_reg()); - op->reg_info_set = true; - return op; - } else if (instr.kind == InstructionKind::DADDIU) { - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::ADD, make_reg(instr.get_src(0).get_reg(), idx), - make_int(instr.get_src(1).get_imm()))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_daddu(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::DADDU, {}, make_gpr(Reg::R0), {})) { - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::ADD, make_reg(instr.get_src(1).get_reg(), idx), - std::make_shared(0))); - op->update_reginfo_self(1, 1, 0); - return op; - } else if (is_gpr_3(instr, InstructionKind::DADDU, {}, {}, {}) && - !instr.get_src(0).is_reg(make_gpr(Reg::S7)) && - !instr.get_src(1).is_reg(make_gpr(Reg::S7))) { - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::ADD, make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 2, 0); - return op; - } - return to_asm_reg_reg_reg("daddu", instr, idx); -} - -std::shared_ptr try_dsubu(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::DSUBU, {}, make_gpr(Reg::R0), {}) && - !instr.get_src(0).is_reg(make_gpr(Reg::S7)) && !instr.get_src(1).is_reg(make_gpr(Reg::S7))) { - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath1::NEG, make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 1, 0); - return op; - } else if (is_gpr_3(instr, InstructionKind::DSUBU, {}, {}, {}) && - !instr.get_src(0).is_reg(make_gpr(Reg::S7)) && - !instr.get_src(1).is_reg(make_gpr(Reg::S7))) { - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::SUB, make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_mult3(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::MULT3, {}, {}, {}) && - !instr.get_src(0).is_reg(make_gpr(Reg::S7)) && !instr.get_src(1).is_reg(make_gpr(Reg::S7))) { - auto op = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::MUL_SIGNED, - make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_multu3(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::MULTU3, {}, {}, {}) && - !instr.get_src(0).is_reg(make_gpr(Reg::S7)) && !instr.get_src(1).is_reg(make_gpr(Reg::S7))) { - auto op = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::MUL_UNSIGNED, - make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_and(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::AND, {}, {}, {}) && - !instr.get_src(0).is_reg(make_gpr(Reg::S7)) && !instr.get_src(1).is_reg(make_gpr(Reg::S7))) { - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::AND, make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_andi(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::ANDI) { - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::AND, make_reg(instr.get_src(0).get_reg(), idx), - make_int(instr.get_src(1).get_imm()))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_xori(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::XORI) { - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::XOR, make_reg(instr.get_src(0).get_reg(), idx), - make_int(instr.get_src(1).get_imm()))); - op->update_reginfo_self(1, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_nor(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::NOR, {}, {}, {}) && - !instr.get_src(0).is_reg(make_gpr(Reg::S7)) && instr.get_src(1).is_reg(make_gpr(Reg::R0))) { - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath1::NOT, make_reg(instr.get_src(0).get_reg(), idx))); - op->update_reginfo_self(1, 1, 0); - return op; - } else if (is_gpr_3(instr, InstructionKind::NOR, {}, {}, {}) && - !instr.get_src(0).is_reg(make_gpr(Reg::S7)) && - !instr.get_src(1).is_reg(make_gpr(Reg::S7))) { - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::NOR, make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_xor(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::XOR, {}, {}, {}) && - !instr.get_src(0).is_reg(make_gpr(Reg::S7)) && !instr.get_src(1).is_reg(make_gpr(Reg::S7))) { - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::XOR, make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_addiu(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::ADDIU && instr.get_src(0).is_reg(make_gpr(Reg::R0))) { - auto dest = instr.get_dst(0).get_reg(); - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(dest, idx), - make_int(instr.get_src(1).get_imm())); - op->write_regs.push_back(dest); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -std::shared_ptr try_lui(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::LUI && instr.get_src(0).is_imm()) { - auto dest = instr.get_dst(0).get_reg(); - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(dest, idx), - make_int(instr.get_src(0).get_imm() << 16)); - op->write_regs.push_back(dest); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -std::shared_ptr try_sll(Instruction& instr, int idx) { - (void)idx; - if (is_nop(instr)) { - auto op = std::make_shared(); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -std::shared_ptr try_dsrav(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::DSRAV, {}, {}, {}) && - !instr.get_src(0).is_reg(make_gpr(Reg::S7)) && !instr.get_src(1).is_reg(make_gpr(Reg::S7))) { - auto op = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::RIGHT_SHIFT_ARITH, - make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_dsrlv(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::DSRLV, {}, {}, {}) && - !instr.get_src(0).is_reg(make_gpr(Reg::S7)) && !instr.get_src(1).is_reg(make_gpr(Reg::S7))) { - auto op = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::RIGHT_SHIFT_LOGIC, - make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_dsllv(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::DSLLV, {}, {}, {}) && - !instr.get_src(0).is_reg(make_gpr(Reg::S7)) && !instr.get_src(1).is_reg(make_gpr(Reg::S7))) { - auto op = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::LEFT_SHIFT, - make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_sw(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::SW && instr.get_src(1).is_sym() && - instr.get_src(2).is_reg(make_gpr(Reg::S7))) { - auto src = instr.get_src(0).get_reg(); - auto op = std::make_shared( - IR_Set_Atomic::SYM_STORE, make_sym_value(instr.get_src(1).get_sym()), make_reg(src, idx)); - op->read_regs.push_back(src); - op->reg_info_set = true; - return op; - } else if (instr.kind == InstructionKind::SW && instr.get_src(1).is_imm()) { - if (instr.get_src(1).get_imm() == 0) { - auto op = std::make_shared(IR_Store_Atomic::Kind::INTEGER, - make_reg(instr.get_src(2).get_reg(), idx), - make_reg(instr.get_src(0).get_reg(), idx), 4); - op->update_reginfo_self(0, 2, 0); - return op; - } else { - if (instr.get_src(0).is_reg(make_gpr(Reg::S7))) { - // store false - auto op = std::make_shared( - IR_Store_Atomic::Kind::INTEGER, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(2).get_reg(), idx), - std::make_shared(instr.get_src(1).get_imm())), - make_sym("#f"), 4); - op->update_reginfo_self(0, 1, 0); - return op; - } else { - auto op = std::make_shared( - IR_Store_Atomic::Kind::INTEGER, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(2).get_reg(), idx), - std::make_shared(instr.get_src(1).get_imm())), - make_reg(instr.get_src(0).get_reg(), idx), 4); - op->update_reginfo_self(0, 2, 0); - return op; - } - } - } - return nullptr; -} - -std::shared_ptr try_sb(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::SB && instr.get_src(1).is_imm()) { - if (instr.get_src(1).get_imm() == 0) { - if (instr.get_src(0).is_reg(make_gpr(Reg::R0))) { - auto op = std::make_shared(IR_Store_Atomic::Kind::INTEGER, - make_reg(instr.get_src(2).get_reg(), idx), - std::make_shared(0), 1); - op->update_reginfo_self(0, 1, 0); - return op; - } else { - auto op = std::make_shared(IR_Store_Atomic::Kind::INTEGER, - make_reg(instr.get_src(2).get_reg(), idx), - make_reg(instr.get_src(0).get_reg(), idx), 1); - op->update_reginfo_self(0, 2, 0); - return op; - } - - } else { - if (instr.get_src(0).is_reg(make_gpr(Reg::R0))) { - auto op = std::make_shared( - IR_Store_Atomic::Kind::INTEGER, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(2).get_reg(), idx), - std::make_shared(instr.get_src(1).get_imm())), - std::make_shared(0), 1); - op->update_reginfo_self(0, 1, 0); - return op; - } else { - auto op = std::make_shared( - IR_Store_Atomic::Kind::INTEGER, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(2).get_reg(), idx), - std::make_shared(instr.get_src(1).get_imm())), - make_reg(instr.get_src(0).get_reg(), idx), 1); - op->update_reginfo_self(0, 2, 0); - return op; - } - } - } - return nullptr; -} - -std::shared_ptr try_sh(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::SH && instr.get_src(1).is_imm()) { - auto op = std::make_shared( - IR_Store_Atomic::Kind::INTEGER, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(2).get_reg(), idx), - std::make_shared(instr.get_src(1).get_imm())), - make_reg(instr.get_src(0).get_reg(), idx), 2); - op->update_reginfo_self(0, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_sd(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::SD && instr.get_src(1).is_imm()) { - auto op = std::make_shared( - IR_Store_Atomic::Kind::INTEGER, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(2).get_reg(), idx), - std::make_shared(instr.get_src(1).get_imm())), - make_reg(instr.get_src(0).get_reg(), idx), 8); - op->update_reginfo_self(0, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_sq(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::SQ && instr.get_src(1).is_imm()) { - auto op = std::make_shared( - IR_Store_Atomic::Kind::INTEGER, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(2).get_reg(), idx), - std::make_shared(instr.get_src(1).get_imm())), - make_reg(instr.get_src(0).get_reg(), idx), 16); - op->update_reginfo_self(0, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_swc1(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::SWC1 && instr.get_src(1).is_imm()) { - auto op = std::make_shared( - IR_Store_Atomic::Kind::FLOAT, - std::make_shared( - IR_IntMath2::ADD, make_reg(instr.get_src(2).get_reg(), idx), - std::make_shared(instr.get_src(1).get_imm())), - make_reg(instr.get_src(0).get_reg(), idx), 4); - op->update_reginfo_self(0, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_cvtws(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::CVTWS) { - auto dst = instr.get_dst(0).get_reg(); - auto src = instr.get_src(0).get_reg(); - auto op = make_set_atomic( - IR_Set_Atomic::REG_FLT, make_reg(dst, idx), - std::make_shared(IR_FloatMath1::FLOAT_TO_INT, make_reg(src, idx))); - op->write_regs.push_back(dst); - op->read_regs.push_back(src); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -std::shared_ptr try_cvtsw(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::CVTSW) { - auto dst = instr.get_dst(0).get_reg(); - auto src = instr.get_src(0).get_reg(); - auto op = make_set_atomic( - IR_Set_Atomic::REG_FLT, make_reg(dst, idx), - std::make_shared(IR_FloatMath1::INT_TO_FLOAT, make_reg(src, idx))); - op->write_regs.push_back(dst); - op->read_regs.push_back(src); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -std::shared_ptr try_float_math_1(Instruction& instr, - int idx, - InstructionKind ikind, - IR_FloatMath1::Kind irkind) { - if (instr.kind == ikind) { - auto dst = instr.get_dst(0).get_reg(); - auto src = instr.get_src(0).get_reg(); - auto op = make_set_atomic(IR_Set_Atomic::REG_FLT, make_reg(dst, idx), - std::make_shared(irkind, make_reg(src, idx))); - op->write_regs.push_back(dst); - op->read_regs.push_back(src); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -std::shared_ptr try_movs(Instruction& instr, int idx) { - if (instr.kind == InstructionKind::MOVS) { - auto dst = instr.get_dst(0).get_reg(); - auto src = instr.get_src(0).get_reg(); - auto op = make_set_atomic(IR_Set_Atomic::REG_FLT, make_reg(dst, idx), make_reg(src, idx)); - op->write_regs.push_back(dst); - op->read_regs.push_back(src); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -std::shared_ptr try_movn(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::MOVN, {}, make_gpr(Reg::S7), {})) { - auto dst = instr.get_dst(0).get_reg(); - auto src = instr.get_src(1).get_reg(); - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(dst, idx), - std::make_shared(make_reg(src, idx), false)); - op->write_regs.push_back(dst); - op->read_regs.push_back(src); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -std::shared_ptr try_movz(Instruction& instr, int idx) { - if (is_gpr_3(instr, InstructionKind::MOVZ, {}, make_gpr(Reg::S7), {})) { - auto dst = instr.get_dst(0).get_reg(); - auto src = instr.get_src(1).get_reg(); - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(dst, idx), - std::make_shared(make_reg(src, idx), true)); - op->write_regs.push_back(dst); - op->read_regs.push_back(src); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -// TWO Instructions -std::shared_ptr try_div(Instruction& instr, Instruction& next_instr, int idx) { - if (instr.kind == InstructionKind::DIV && instr.get_src(0).is_reg() && - instr.get_src(1).is_reg() && next_instr.kind == InstructionKind::MFLO && - next_instr.get_dst(0).is_reg()) { - auto op = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(next_instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::DIV_SIGNED, - make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 2, 0); - return op; - } else if (instr.kind == InstructionKind::DIV && instr.get_src(0).is_reg() && - instr.get_src(1).is_reg() && next_instr.kind == InstructionKind::MFHI && - next_instr.get_dst(0).is_reg()) { - auto op = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(next_instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::MOD_SIGNED, - make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_divu(Instruction& instr, Instruction& next_instr, int idx) { - if (instr.kind == InstructionKind::DIVU && instr.get_src(0).is_reg() && - instr.get_src(1).is_reg() && next_instr.kind == InstructionKind::MFLO && - next_instr.get_dst(0).is_reg()) { - auto op = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(next_instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::DIV_UNSIGNED, - make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 2, 0); - return op; - } else if (instr.kind == InstructionKind::DIVU && instr.get_src(0).is_reg() && - instr.get_src(1).is_reg() && next_instr.kind == InstructionKind::MFHI && - next_instr.get_dst(0).is_reg()) { - auto op = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(next_instr.get_dst(0).get_reg(), idx), - std::make_shared(IR_IntMath2::MOD_UNSIGNED, - make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx))); - op->update_reginfo_self(1, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_jalr(Instruction& instr, Instruction& next_instr, int idx) { - (void)idx; - if (instr.kind == InstructionKind::JALR && instr.get_dst(0).is_reg(make_gpr(Reg::RA)) && - instr.get_src(0).is_reg(make_gpr(Reg::T9)) && - is_gpr_2_imm_int(next_instr, InstructionKind::SLL, make_gpr(Reg::V0), make_gpr(Reg::RA), 0)) { - auto op = std::make_shared(); - - // for now, we assume no arguments, but a return. - // todo - clobber fprs - auto temps = {Reg::V1, Reg::A0, Reg::A1, Reg::A2, Reg::A3, Reg::T0, Reg::T1, Reg::T2, - Reg::T3, Reg::T4, Reg::T5, Reg::T6, Reg::T7, Reg::T8, Reg::T9}; - for (auto& r : temps) { - op->clobber_regs.emplace_back(Reg::GPR, r); - } - - op->read_regs.emplace_back(Reg::GPR, Reg::T9); - op->write_regs.emplace_back(Reg::GPR, Reg::V0); // may "write" a none. - op->reg_info_set = true; - return op; - } - return nullptr; -} - -BranchDelay get_branch_delay(Instruction& i, int idx) { - if (is_nop(i)) { - // no read, write, clobber - return BranchDelay(BranchDelay::NOP); - } else if (is_gpr_3(i, InstructionKind::OR, {}, make_gpr(Reg::S7), make_gpr(Reg::R0))) { - BranchDelay b(BranchDelay::SET_REG_FALSE); - auto dst = i.get_dst(0).get_reg(); - b.destination = make_reg(dst, idx); - b.write_regs.push_back(dst); - return b; - } else if (is_gpr_3(i, InstructionKind::OR, {}, {}, make_gpr(Reg::R0))) { - BranchDelay b(BranchDelay::SET_REG_REG); - auto dst = i.get_dst(0).get_reg(); - auto src = i.get_src(0).get_reg(); - b.destination = make_reg(dst, idx); - b.source = make_reg(src, idx); - b.write_regs.push_back(dst); - b.read_regs.push_back(src); - return b; - } else if (i.kind == InstructionKind::DADDIU && i.get_src(0).is_reg(make_gpr(Reg::S7)) && - i.get_src(1).is_imm() && i.get_src(1).get_imm() == 8) { - BranchDelay b(BranchDelay::SET_REG_TRUE); - auto dst = i.get_dst(0).get_reg(); - b.destination = make_reg(dst, idx); - b.write_regs.push_back(dst); - return b; - } else if (i.kind == InstructionKind::LW && i.get_src(1).is_reg(make_gpr(Reg::S7)) && - i.get_src(0).is_sym()) { - if (i.get_src(0).get_sym() == "binteger") { - BranchDelay b(BranchDelay::SET_BINTEGER); - auto dst = i.get_dst(0).get_reg(); - b.destination = make_reg(dst, idx); - b.write_regs.push_back(dst); - return b; - } else if (i.get_src(0).get_sym() == "pair") { - BranchDelay b(BranchDelay::SET_PAIR); - auto dst = i.get_dst(0).get_reg(); - b.destination = make_reg(dst, idx); - b.write_regs.push_back(dst); - return b; - } else { - ASSERT(false); - } - } else if (i.kind == InstructionKind::DSLLV) { - // this is used for ash? - BranchDelay b(BranchDelay::DSLLV); - auto dst = i.get_dst(0).get_reg(); - auto src0 = i.get_src(0).get_reg(); - auto src2 = i.get_src(1).get_reg(); - b.destination = make_reg(dst, idx); - b.source = make_reg(src0, idx); - b.source2 = make_reg(src2, idx); - b.write_regs.push_back(dst); - b.read_regs.push_back(src0); - b.read_regs.push_back(src2); - return b; - } else if (is_gpr_3(i, InstructionKind::DSUBU, {}, make_gpr(Reg::R0), {})) { - // this is used for abs? - BranchDelay b(BranchDelay::NEGATE); - auto dst = i.get_dst(0).get_reg(); - auto src = i.get_src(1).get_reg(); - b.destination = make_reg(dst, idx); - b.source = make_reg(src, idx); - b.write_regs.push_back(dst); - b.read_regs.push_back(src); - return b; - } - BranchDelay b(BranchDelay::UNKNOWN); - return b; -} - -std::shared_ptr try_bne(Instruction& instr, Instruction& next_instr, int idx) { - if (instr.kind == InstructionKind::BNE && instr.get_src(1).is_reg(make_gpr(Reg::R0))) { - auto op = std::make_shared( - Condition(Condition::NONZERO, make_reg(instr.get_src(0).get_reg(), idx), nullptr, nullptr), - instr.get_src(2).get_label(), get_branch_delay(next_instr, idx), false); - op->update_reginfo_self(0, 1, 0); - return op; - } else if (instr.kind == InstructionKind::BNE && instr.get_src(0).is_reg(make_gpr(Reg::S7))) { - auto op = std::make_shared( - Condition(Condition::TRUTHY, make_reg(instr.get_src(1).get_reg(), idx), nullptr, nullptr), - instr.get_src(2).get_label(), get_branch_delay(next_instr, idx), false); - op->update_reginfo_self(0, 1, 0); - return op; - } else if (instr.kind == InstructionKind::BNE) { - auto op = std::make_shared( - Condition(Condition::NOT_EQUAL, make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx), nullptr), - instr.get_src(2).get_label(), get_branch_delay(next_instr, idx), false); - op->update_reginfo_self(0, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_bnel(Instruction& instr, Instruction& next_instr, int idx) { - if (instr.kind == InstructionKind::BNEL && instr.get_src(0).is_reg(make_gpr(Reg::S7))) { - auto op = std::make_shared( - Condition(Condition::TRUTHY, make_reg(instr.get_src(1).get_reg(), idx), nullptr, nullptr), - instr.get_src(2).get_label(), get_branch_delay(next_instr, idx), true); - op->update_reginfo_self(0, 1, 0); - return op; - } else if (instr.kind == InstructionKind::BNEL && instr.get_src(1).is_reg(make_gpr(Reg::R0))) { - auto op = std::make_shared( - Condition(Condition::NONZERO, make_reg(instr.get_src(0).get_reg(), idx), nullptr, nullptr), - instr.get_src(2).get_label(), get_branch_delay(next_instr, idx), true); - op->update_reginfo_self(0, 1, 0); - return op; - } else if (instr.kind == InstructionKind::BNEL) { - // return std::make_shared(IR_Branch2::NOT_EQUAL, instr.get_src(2).get_label(), - // make_reg(instr.get_src(0).get_reg(), idx), - // make_reg(instr.get_src(1).get_reg(), idx), - // get_branch_delay(next_instr, idx), true); - } - return nullptr; -} - -std::shared_ptr try_beql(Instruction& instr, Instruction& next_instr, int idx) { - if (instr.kind == InstructionKind::BEQL && instr.get_src(0).is_reg(make_gpr(Reg::S7))) { - auto op = std::make_shared( - Condition(Condition::FALSE, make_reg(instr.get_src(1).get_reg(), idx), nullptr, nullptr), - instr.get_src(2).get_label(), get_branch_delay(next_instr, idx), true); - op->update_reginfo_self(0, 1, 0); - return op; - } else if (instr.kind == InstructionKind::BEQL && instr.get_src(1).is_reg(make_gpr(Reg::R0))) { - auto op = std::make_shared( - Condition(Condition::ZERO, make_reg(instr.get_src(0).get_reg(), idx), nullptr, nullptr), - instr.get_src(2).get_label(), get_branch_delay(next_instr, idx), true); - op->update_reginfo_self(0, 1, 0); - return op; - } else if (instr.kind == InstructionKind::BEQL) { - auto op = std::make_shared( - Condition(Condition::EQUAL, make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx), nullptr), - instr.get_src(2).get_label(), get_branch_delay(next_instr, idx), true); - op->update_reginfo_self(0, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_beq(Instruction& instr, Instruction& next_instr, int idx) { - if (instr.kind == InstructionKind::BEQ && instr.get_src(0).is_reg(make_gpr(Reg::R0)) && - instr.get_src(1).is_reg(make_gpr(Reg::R0))) { - auto op = std::make_shared( - Condition(Condition::ALWAYS, nullptr, nullptr, nullptr), instr.get_src(2).get_label(), - get_branch_delay(next_instr, idx), false); - op->update_reginfo_self(0, 0, 0); - return op; - } else if (instr.kind == InstructionKind::BEQ && instr.get_src(0).is_reg(make_gpr(Reg::S7))) { - auto op = std::make_shared( - Condition(Condition::FALSE, make_reg(instr.get_src(1).get_reg(), idx), nullptr, nullptr), - instr.get_src(2).get_label(), get_branch_delay(next_instr, idx), false); - op->update_reginfo_self(0, 1, 0); - return op; - } else if (instr.kind == InstructionKind::BEQ && instr.get_src(1).is_reg(make_gpr(Reg::R0))) { - auto op = std::make_shared( - Condition(Condition::ZERO, make_reg(instr.get_src(0).get_reg(), idx), nullptr, nullptr), - instr.get_src(2).get_label(), get_branch_delay(next_instr, idx), false); - op->update_reginfo_self(0, 1, 0); - return op; - } else if (instr.kind == InstructionKind::BEQ) { - auto op = std::make_shared( - Condition(Condition::EQUAL, make_reg(instr.get_src(0).get_reg(), idx), - make_reg(instr.get_src(1).get_reg(), idx), nullptr), - instr.get_src(2).get_label(), get_branch_delay(next_instr, idx), false); - op->update_reginfo_self(0, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_bgtzl(Instruction& instr, Instruction& next_instr, int idx) { - if (instr.kind == InstructionKind::BGTZL) { - auto op = std::make_shared( - Condition(Condition::GREATER_THAN_ZERO_SIGNED, make_reg(instr.get_src(0).get_reg(), idx), - nullptr, nullptr), - instr.get_src(1).get_label(), get_branch_delay(next_instr, idx), true); - op->update_reginfo_self(0, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_bgezl(Instruction& instr, Instruction& next_instr, int idx) { - if (instr.kind == InstructionKind::BGEZL) { - auto op = std::make_shared( - Condition(Condition::GEQ_ZERO_SIGNED, make_reg(instr.get_src(0).get_reg(), idx), nullptr, - nullptr), - instr.get_src(1).get_label(), get_branch_delay(next_instr, idx), true); - op->update_reginfo_self(0, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_bltzl(Instruction& instr, Instruction& next_instr, int idx) { - if (instr.kind == InstructionKind::BLTZL) { - auto op = std::make_shared( - Condition(Condition::LESS_THAN_ZERO, make_reg(instr.get_src(0).get_reg(), idx), nullptr, - nullptr), - instr.get_src(1).get_label(), get_branch_delay(next_instr, idx), true); - op->update_reginfo_self(0, 1, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_daddiu(Instruction& i0, Instruction& i1, int idx) { - if (i0.kind == InstructionKind::DADDIU && i1.kind == InstructionKind::MOVN && - i0.get_src(0).get_reg() == make_gpr(Reg::S7)) { - auto dst_reg = i0.get_dst(0).get_reg(); - auto src_reg = i1.get_src(1).get_reg(); - ASSERT(i0.get_src(0).get_reg() == make_gpr(Reg::S7)); - ASSERT(i0.get_src(1).get_imm() == 8); - ASSERT(i1.get_dst(0).get_reg() == dst_reg); - ASSERT(i1.get_src(0).get_reg() == make_gpr(Reg::S7)); - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(dst_reg, idx), - std::make_shared( - Condition(Condition::ZERO, make_reg(src_reg, idx), nullptr, nullptr), nullptr)); - op->write_regs.push_back(dst_reg); - op->read_regs.push_back(src_reg); - op->reg_info_set = true; - return op; - } else if (i0.kind == InstructionKind::DADDIU && i1.kind == InstructionKind::MOVZ && - i0.get_src(0).get_reg() == make_gpr(Reg::S7)) { - auto dst_reg = i0.get_dst(0).get_reg(); - auto src_reg = i1.get_src(1).get_reg(); - ASSERT(i0.get_src(0).get_reg() == make_gpr(Reg::S7)); - ASSERT(i0.get_src(1).get_imm() == 8); - ASSERT(i1.get_dst(0).get_reg() == dst_reg); - ASSERT(i1.get_src(0).get_reg() == make_gpr(Reg::S7)); - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(dst_reg, idx), - std::make_shared( - Condition(Condition::NONZERO, make_reg(src_reg, idx), nullptr, nullptr), nullptr)); - op->write_regs.push_back(dst_reg); - op->read_regs.push_back(src_reg); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -std::shared_ptr try_lui(Instruction& i0, Instruction& i1, int idx) { - if (i0.kind == InstructionKind::LUI && i1.kind == InstructionKind::ORI && - i0.get_src(0).is_label() && i1.get_src(1).is_label()) { - ASSERT(i0.get_dst(0).get_reg() == i1.get_src(0).get_reg()); - ASSERT(i0.get_src(0).get_label() == i1.get_src(1).get_label()); - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(i1.get_dst(0).get_reg(), idx), - std::make_shared(i0.get_src(0).get_label())); - if (i0.get_dst(0).get_reg() != i1.get_dst(0).get_reg()) { - op->clobber = make_reg(i0.get_dst(0).get_reg(), idx); - op->clobber_regs.push_back(i0.get_dst(0).get_reg()); - } - op->write_regs.push_back(i1.get_dst(0).get_reg()); - op->reg_info_set = true; - return op; - } else if (i0.kind == InstructionKind::LUI && i1.kind == InstructionKind::ORI && - i0.get_src(0).is_imm() && i1.get_src(1).is_imm() && - i0.get_dst(0).get_reg() == i1.get_src(0).get_reg()) { - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(i1.get_dst(0).get_reg(), idx), - make_int((int64_t(i1.get_src(1).get_imm()) + int64_t(i0.get_src(0).get_imm() << 16)))); - if (i0.get_dst(0).get_reg() != i1.get_dst(0).get_reg()) { - op->clobber = make_reg(i0.get_dst(0).get_reg(), idx); - op->clobber_regs.push_back(i0.get_dst(0).get_reg()); - } - op->write_regs.push_back(i1.get_dst(0).get_reg()); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -// note - this one is a little bit strange in how it's colored. -std::shared_ptr try_slt(Instruction& i0, Instruction& i1, int idx) { - if (is_gpr_3(i0, InstructionKind::SLT, {}, {}, {})) { - auto temp = i0.get_dst(0).get_reg(); - auto left = i0.get_src(0).get_reg(); - auto right = i0.get_src(1).get_reg(); - if (is_gpr_3(i1, InstructionKind::MOVZ, left, right, temp)) { - // success! - auto result = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(left, idx), - std::make_shared(IR_IntMath2::MIN_SIGNED, - make_reg(left, idx), make_reg(right, idx))); - result->clobber = make_reg(temp, idx); - result->clobber_regs.push_back(temp); - result->write_regs.push_back(left); - result->read_regs.push_back(right); - result->read_regs.push_back(left); - result->reg_info_set = true; - return result; - } - - if (is_gpr_3(i1, InstructionKind::MOVN, left, right, temp)) { - // success! - auto result = - make_set_atomic(IR_Set_Atomic::REG_64, make_reg(left, idx), - std::make_shared(IR_IntMath2::MAX_SIGNED, - make_reg(left, idx), make_reg(right, idx))); - result->clobber = make_reg(temp, idx); - result->clobber_regs.push_back(temp); - result->write_regs.push_back(left); - result->read_regs.push_back(right); - result->read_regs.push_back(left); - result->reg_info_set = true; - return result; - } - } - return nullptr; -} - -// THREE OP -std::shared_ptr try_lui(Instruction& i0, Instruction& i1, Instruction& i2, int idx) { - if (i0.kind == InstructionKind::LUI && i1.kind == InstructionKind::ORI && - i0.get_src(0).is_label() && i1.get_src(1).is_label() && - is_gpr_3(i2, InstructionKind::ADDU, {}, make_gpr(Reg::FP), {})) { - ASSERT(i0.get_dst(0).get_reg() == i1.get_src(0).get_reg()); - ASSERT(i0.get_src(0).get_label() == i1.get_src(1).get_label()); - ASSERT(i2.get_dst(0).get_reg() == i2.get_src(1).get_reg()); - ASSERT(i2.get_dst(0).get_reg() == i1.get_dst(0).get_reg()); - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(i1.get_dst(0).get_reg(), idx), - std::make_shared(i0.get_src(0).get_label())); - if (i0.get_dst(0).get_reg() != i1.get_dst(0).get_reg()) { - op->clobber = make_reg(i0.get_dst(0).get_reg(), idx); - op->clobber_regs.push_back(i0.get_dst(0).get_reg()); - } - op->write_regs.push_back(i1.get_dst(0).get_reg()); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -std::shared_ptr try_dsubu(Instruction& i0, Instruction& i1, Instruction& i2, int idx) { - if (i0.kind == InstructionKind::DSUBU && i1.kind == InstructionKind::DADDIU && - i2.kind == InstructionKind::MOVN) { - // check for equality - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - auto src1_reg = i0.get_src(1).get_reg(); - auto dst_reg = i1.get_dst(0).get_reg(); - ASSERT(i1.get_src(0).get_reg() == make_gpr(Reg::S7)); - ASSERT(i1.get_src(1).get_imm() == 8); - ASSERT(i2.get_dst(0).get_reg() == dst_reg); - ASSERT(i2.get_src(0).get_reg() == make_gpr(Reg::S7)); - ASSERT(i2.get_src(1).get_reg() == clobber_reg); - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(dst_reg, idx), - std::make_shared(Condition(Condition::EQUAL, make_reg(src0_reg, idx), - make_reg(src1_reg, idx), make_reg(clobber_reg, idx)), - nullptr)); - op->update_reginfo_self(1, 2, 1); - return op; - } else if (i0.kind == InstructionKind::DSUBU && i1.kind == InstructionKind::DADDIU && - i2.kind == InstructionKind::MOVZ) { - // check for equality - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - auto src1_reg = i0.get_src(1).get_reg(); - auto dst_reg = i1.get_dst(0).get_reg(); - ASSERT(i1.get_src(0).get_reg() == make_gpr(Reg::S7)); - ASSERT(i1.get_src(1).get_imm() == 8); - ASSERT(i2.get_dst(0).get_reg() == dst_reg); - ASSERT(i2.get_src(0).get_reg() == make_gpr(Reg::S7)); - if (i2.get_src(1).get_reg() != clobber_reg) { - return nullptr; // TODO! - } - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(dst_reg, idx), - std::make_shared(Condition(Condition::NOT_EQUAL, make_reg(src0_reg, idx), - make_reg(src1_reg, idx), make_reg(clobber_reg, idx)), - nullptr)); - op->update_reginfo_self(1, 2, 1); - return op; - } - return nullptr; -} - -std::shared_ptr try_slt(Instruction& i0, Instruction& i1, Instruction& i2, int idx) { - if (i0.kind == InstructionKind::SLT && i1.kind == InstructionKind::BNE) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - auto src1_reg = i0.get_src(1).get_reg(); - ASSERT(i1.get_src(0).get_reg() == clobber_reg); - ASSERT(i1.get_src(1).get_reg() == make_gpr(Reg::R0)); - auto op = std::make_shared( - Condition(Condition::LESS_THAN_SIGNED, make_reg(src0_reg, idx), make_reg(src1_reg, idx), - make_reg(clobber_reg, idx)), - i1.get_src(2).get_label(), get_branch_delay(i2, idx), false); - op->update_reginfo_self(0, 2, 1); - return op; - } else if (i0.kind == InstructionKind::SLT && i1.kind == InstructionKind::DADDIU && - i2.kind == InstructionKind::MOVZ) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - auto src1_reg = i0.get_src(1).get_reg(); - auto dst_reg = i1.get_dst(0).get_reg(); - ASSERT(i1.get_src(0).is_reg(make_gpr(Reg::S7))); - ASSERT(i1.get_src(1).get_imm() == 8); - ASSERT(i2.get_dst(0).get_reg() == dst_reg); - ASSERT(i2.get_src(0).get_reg() == make_gpr(Reg::S7)); - if (i2.get_src(1).get_reg() != clobber_reg) { - return nullptr; // TODO! - } - if (src1_reg == make_gpr(Reg::R0)) { - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(dst_reg, idx), - std::make_shared(Condition(Condition::LESS_THAN_ZERO, make_reg(src0_reg, idx), - nullptr, make_reg(clobber_reg, idx)), - nullptr)); - op->update_reginfo_self(1, 1, 1); - return op; - } else { - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(dst_reg, idx), - std::make_shared( - Condition(Condition::LESS_THAN_SIGNED, make_reg(src0_reg, idx), - make_reg(src1_reg, idx), make_reg(clobber_reg, idx)), - nullptr)); - op->update_reginfo_self(1, 2, 1); - return op; - } - - } else if (i0.kind == InstructionKind::SLT && i1.kind == InstructionKind::BEQ) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - auto src1_reg = i0.get_src(1).get_reg(); - ASSERT(i1.get_src(0).get_reg() == clobber_reg); - ASSERT(i1.get_src(1).get_reg() == make_gpr(Reg::R0)); - auto op = std::make_shared( - Condition(Condition::GEQ_SIGNED, make_reg(src0_reg, idx), make_reg(src1_reg, idx), - make_reg(clobber_reg, idx)), - i1.get_src(2).get_label(), get_branch_delay(i2, idx), false); - op->update_reginfo_self(0, 2, 1); - return op; - } else if (i0.kind == InstructionKind::SLT && i1.kind == InstructionKind::DADDIU && - i2.kind == InstructionKind::MOVN) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - auto src1_reg = i0.get_src(1).get_reg(); - auto dst_reg = i1.get_dst(0).get_reg(); - ASSERT(i1.get_src(0).is_reg(make_gpr(Reg::S7))); - ASSERT(i1.get_src(1).get_imm() == 8); - ASSERT(i2.get_dst(0).get_reg() == dst_reg); - ASSERT(i2.get_src(0).get_reg() == make_gpr(Reg::S7)); - if (i2.get_src(1).get_reg() != clobber_reg) { - return nullptr; // TODO! - } - if (src1_reg == make_gpr(Reg::R0)) { - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(dst_reg, idx), - std::make_shared( - Condition(Condition::GEQ_ZERO_SIGNED, make_reg(src0_reg, idx), - nullptr, make_reg(clobber_reg, idx)), - nullptr)); - op->update_reginfo_self(1, 1, 1); - return op; - } else { - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(dst_reg, idx), - std::make_shared( - Condition(Condition::GEQ_SIGNED, make_reg(src0_reg, idx), - make_reg(src1_reg, idx), make_reg(clobber_reg, idx)), - nullptr)); - op->update_reginfo_self(1, 2, 1); - return op; - } - } - return nullptr; -} - -std::shared_ptr try_slti(Instruction& i0, Instruction& i1, Instruction& i2, int idx) { - auto src1 = make_int(i0.get_src(1).get_imm()); - if (i0.kind == InstructionKind::SLTI && i1.kind == InstructionKind::BNE) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - ASSERT(i1.get_src(0).get_reg() == clobber_reg); - ASSERT(i1.get_src(1).get_reg() == make_gpr(Reg::R0)); - auto op = std::make_shared( - Condition(Condition::LESS_THAN_SIGNED, make_reg(src0_reg, idx), src1, - make_reg(clobber_reg, idx)), - i1.get_src(2).get_label(), get_branch_delay(i2, idx), false); - op->update_reginfo_self(0, 1, 1); - return op; - } else if (i0.kind == InstructionKind::SLTI && i1.kind == InstructionKind::DADDIU && - i2.kind == InstructionKind::MOVZ) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - auto dst_reg = i1.get_dst(0).get_reg(); - ASSERT(i1.get_src(0).is_reg(make_gpr(Reg::S7))); - ASSERT(i1.get_src(1).get_imm() == 8); - ASSERT(i2.get_dst(0).get_reg() == dst_reg); - ASSERT(i2.get_src(0).get_reg() == make_gpr(Reg::S7)); - if (i2.get_src(1).get_reg() != clobber_reg) { - return nullptr; // TODO! - } - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(dst_reg, idx), - std::make_shared(Condition(Condition::LESS_THAN_SIGNED, make_reg(src0_reg, idx), - src1, make_reg(clobber_reg, idx)), - nullptr)); - op->update_reginfo_self(1, 1, 1); - return op; - } else if (i0.kind == InstructionKind::SLTI && i1.kind == InstructionKind::BEQ) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - ASSERT(i1.get_src(0).get_reg() == clobber_reg); - ASSERT(i1.get_src(1).get_reg() == make_gpr(Reg::R0)); - auto op = std::make_shared( - Condition(Condition::GEQ_SIGNED, make_reg(src0_reg, idx), src1, make_reg(clobber_reg, idx)), - i1.get_src(2).get_label(), get_branch_delay(i2, idx), false); - op->update_reginfo_self(0, 1, 1); - return op; - } else if (i0.kind == InstructionKind::SLTI && i1.kind == InstructionKind::DADDIU && - i2.kind == InstructionKind::MOVN) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - auto dst_reg = i1.get_dst(0).get_reg(); - ASSERT(i1.get_src(0).is_reg(make_gpr(Reg::S7))); - ASSERT(i1.get_src(1).get_imm() == 8); - ASSERT(i2.get_dst(0).get_reg() == dst_reg); - ASSERT(i2.get_src(0).get_reg() == make_gpr(Reg::S7)); - if (i2.get_src(1).get_reg() != clobber_reg) { - return nullptr; // TODO! - } - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(dst_reg, idx), - std::make_shared(Condition(Condition::GEQ_SIGNED, make_reg(src0_reg, idx), src1, - make_reg(clobber_reg, idx)), - nullptr)); - op->update_reginfo_self(1, 1, 1); - return op; - } - return nullptr; -} - -std::shared_ptr try_sltiu(Instruction& i0, Instruction& i1, Instruction& i2, int idx) { - auto src1 = make_int(i0.get_src(1).get_imm()); - if (i0.kind == InstructionKind::SLTIU && i1.kind == InstructionKind::BNE) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - ASSERT(i1.get_src(0).get_reg() == clobber_reg); - ASSERT(i1.get_src(1).get_reg() == make_gpr(Reg::R0)); - auto op = std::make_shared( - Condition(Condition::LESS_THAN_UNSIGNED, make_reg(src0_reg, idx), src1, - make_reg(clobber_reg, idx)), - i1.get_src(2).get_label(), get_branch_delay(i2, idx), false); - op->update_reginfo_self(0, 1, 1); - return op; - } else if (i0.kind == InstructionKind::SLTIU && i1.kind == InstructionKind::DADDIU && - i2.kind == InstructionKind::MOVZ) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - auto dst_reg = i1.get_dst(0).get_reg(); - ASSERT(i1.get_src(0).is_reg(make_gpr(Reg::S7))); - ASSERT(i1.get_src(1).get_imm() == 8); - ASSERT(i2.get_dst(0).get_reg() == dst_reg); - ASSERT(i2.get_src(0).get_reg() == make_gpr(Reg::S7)); - if (i2.get_src(1).get_reg() != clobber_reg) { - return nullptr; // TODO! - } - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(dst_reg, idx), - std::make_shared( - Condition(Condition::LESS_THAN_UNSIGNED, make_reg(src0_reg, idx), - src1, make_reg(clobber_reg, idx)), - nullptr)); - op->update_reginfo_self(1, 1, 1); - return op; - } else if (i0.kind == InstructionKind::SLTIU && i1.kind == InstructionKind::BEQ) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - ASSERT(i1.get_src(0).get_reg() == clobber_reg); - ASSERT(i1.get_src(1).get_reg() == make_gpr(Reg::R0)); - auto op = std::make_shared( - Condition(Condition::GEQ_UNSIGNED, make_reg(src0_reg, idx), src1, - make_reg(clobber_reg, idx)), - i1.get_src(2).get_label(), get_branch_delay(i2, idx), false); - op->update_reginfo_self(0, 1, 1); - return op; - } else if (i0.kind == InstructionKind::SLTIU && i1.kind == InstructionKind::DADDIU && - i2.kind == InstructionKind::MOVN) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - auto dst_reg = i1.get_dst(0).get_reg(); - ASSERT(i1.get_src(0).is_reg(make_gpr(Reg::S7))); - ASSERT(i1.get_src(1).get_imm() == 8); - ASSERT(i2.get_dst(0).get_reg() == dst_reg); - ASSERT(i2.get_src(0).get_reg() == make_gpr(Reg::S7)); - if (i2.get_src(1).get_reg() != clobber_reg) { - return nullptr; // TODO! - } - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(dst_reg, idx), - std::make_shared(Condition(Condition::GEQ_UNSIGNED, make_reg(src0_reg, idx), - src1, make_reg(clobber_reg, idx)), - nullptr)); - op->update_reginfo_self(1, 1, 1); - return op; - } - return nullptr; -} - -std::shared_ptr try_ceqs(Instruction& i0, Instruction& i1, Instruction& i2, int idx) { - if (i0.kind == InstructionKind::CEQS && i1.kind == InstructionKind::BC1T) { - auto op = std::make_shared( - Condition(Condition::FLOAT_EQUAL, make_reg(i0.get_src(0).get_reg(), idx), - make_reg(i0.get_src(1).get_reg(), idx), nullptr), - i1.get_src(0).get_label(), get_branch_delay(i2, idx), false); - op->update_reginfo_self(0, 2, 0); - return op; - } else if (i0.kind == InstructionKind::CEQS && i1.kind == InstructionKind::BC1F) { - auto op = std::make_shared( - Condition(Condition::FLOAT_NOT_EQUAL, make_reg(i0.get_src(0).get_reg(), idx), - make_reg(i0.get_src(1).get_reg(), idx), nullptr), - i1.get_src(0).get_label(), get_branch_delay(i2, idx), false); - op->update_reginfo_self(0, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_clts(Instruction& i0, Instruction& i1, Instruction& i2, int idx) { - if (i0.kind == InstructionKind::CLTS && i1.kind == InstructionKind::BC1T) { - auto op = std::make_shared( - Condition(Condition::FLOAT_LESS_THAN, make_reg(i0.get_src(0).get_reg(), idx), - make_reg(i0.get_src(1).get_reg(), idx), nullptr), - i1.get_src(0).get_label(), get_branch_delay(i2, idx), false); - op->update_reginfo_self(0, 2, 0); - return op; - } else if (i0.kind == InstructionKind::CLTS && i1.kind == InstructionKind::BC1F) { - auto op = std::make_shared( - Condition(Condition::FLOAT_GEQ, make_reg(i0.get_src(0).get_reg(), idx), - make_reg(i0.get_src(1).get_reg(), idx), nullptr), - i1.get_src(0).get_label(), get_branch_delay(i2, idx), false); - op->update_reginfo_self(0, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_cles(Instruction& i0, Instruction& i1, Instruction& i2, int idx) { - if (i0.kind == InstructionKind::CLES && i1.kind == InstructionKind::BC1T) { - auto op = std::make_shared( - Condition(Condition::FLOAT_LEQ, make_reg(i0.get_src(0).get_reg(), idx), - make_reg(i0.get_src(1).get_reg(), idx), nullptr), - i1.get_src(0).get_label(), get_branch_delay(i2, idx), false); - op->update_reginfo_self(0, 2, 0); - return op; - } else if (i0.kind == InstructionKind::CLES && i1.kind == InstructionKind::BC1F) { - auto op = std::make_shared( - Condition(Condition::FLOAT_GREATER_THAN, make_reg(i0.get_src(0).get_reg(), idx), - make_reg(i0.get_src(1).get_reg(), idx), nullptr), - i1.get_src(0).get_label(), get_branch_delay(i2, idx), false); - op->update_reginfo_self(0, 2, 0); - return op; - } - return nullptr; -} - -std::shared_ptr try_sltu(Instruction& i0, Instruction& i1, Instruction& i2, int idx) { - if (i0.kind == InstructionKind::SLTU && i1.kind == InstructionKind::BNE) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - auto src1_reg = i0.get_src(1).get_reg(); - ASSERT(i1.get_src(0).get_reg() == clobber_reg); - ASSERT(i1.get_src(1).get_reg() == make_gpr(Reg::R0)); - auto op = std::make_shared( - Condition(Condition::LESS_THAN_UNSIGNED, make_reg(src0_reg, idx), make_reg(src1_reg, idx), - make_reg(clobber_reg, idx)), - i1.get_src(2).get_label(), get_branch_delay(i2, idx), false); - op->update_reginfo_self(0, 2, 1); - return op; - } else if (i0.kind == InstructionKind::SLTU && i1.kind == InstructionKind::DADDIU && - i2.kind == InstructionKind::MOVZ) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - auto src1_reg = i0.get_src(1).get_reg(); - auto dst_reg = i1.get_dst(0).get_reg(); - ASSERT(i1.get_src(0).is_reg(make_gpr(Reg::S7))); - ASSERT(i1.get_src(1).get_imm() == 8); - ASSERT(i2.get_dst(0).get_reg() == dst_reg); - ASSERT(i2.get_src(0).get_reg() == make_gpr(Reg::S7)); - if (i2.get_src(1).get_reg() != clobber_reg) { - return nullptr; // TODO! - } - auto op = make_set_atomic(IR_Set_Atomic::REG_64, make_reg(dst_reg, idx), - std::make_shared( - Condition(Condition::LESS_THAN_UNSIGNED, make_reg(src0_reg, idx), - make_reg(src1_reg, idx), make_reg(clobber_reg, idx)), - nullptr)); - op->update_reginfo_self(1, 2, 1); - return op; - } else if (i0.kind == InstructionKind::SLTU && i1.kind == InstructionKind::BEQ) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - auto src1_reg = i0.get_src(1).get_reg(); - ASSERT(i1.get_src(0).get_reg() == clobber_reg); - ASSERT(i1.get_src(1).get_reg() == make_gpr(Reg::R0)); - auto op = std::make_shared( - Condition(Condition::GEQ_UNSIGNED, make_reg(src0_reg, idx), make_reg(src1_reg, idx), - make_reg(clobber_reg, idx)), - i1.get_src(2).get_label(), get_branch_delay(i2, idx), false); - op->update_reginfo_self(0, 2, 1); - return op; - } else if (i0.kind == InstructionKind::SLTU && i1.kind == InstructionKind::DADDIU && - i2.kind == InstructionKind::MOVN) { - auto clobber_reg = i0.get_dst(0).get_reg(); - auto src0_reg = i0.get_src(0).get_reg(); - auto src1_reg = i0.get_src(1).get_reg(); - auto dst_reg = i1.get_dst(0).get_reg(); - ASSERT(i1.get_src(0).is_reg(make_gpr(Reg::S7))); - ASSERT(i1.get_src(1).get_imm() == 8); - ASSERT(i2.get_dst(0).get_reg() == dst_reg); - ASSERT(i2.get_src(0).get_reg() == make_gpr(Reg::S7)); - if (i2.get_src(1).get_reg() != clobber_reg) { - return nullptr; // TODO! - } - auto op = make_set_atomic( - IR_Set_Atomic::REG_64, make_reg(dst_reg, idx), - std::make_shared(Condition(Condition::GEQ_UNSIGNED, make_reg(src0_reg, idx), - make_reg(src1_reg, idx), make_reg(clobber_reg, idx)), - nullptr)); - op->update_reginfo_self(1, 2, 1); - return op; - } - return nullptr; -} - -// five op -std::shared_ptr try_lwu(Instruction& i0, - Instruction& i1, - Instruction& i2, - Instruction& i3, - Instruction& i4, - int idx) { - (void)idx; - auto s6 = make_gpr(Reg::S6); - if (i0.kind == InstructionKind::LWU && i0.get_dst(0).is_reg(s6) && - i0.get_src(0).get_imm() == 44 && i0.get_src(1).is_reg(s6) && - i1.kind == InstructionKind::MTLO1 && i1.get_src(0).is_reg(s6) && - i2.kind == InstructionKind::LWU && i2.get_dst(0).is_reg(s6) && - i2.get_src(0).get_imm() == 12 && i2.get_src(1).is_reg(s6) && - i3.kind == InstructionKind::JALR && i3.get_dst(0).is_reg(make_gpr(Reg::RA)) && - i3.get_src(0).is_reg(s6) && i4.kind == InstructionKind::MFLO1 && i4.get_dst(0).is_reg(s6)) { - auto op = std::make_shared(); - op->reg_info_set = true; - return op; - } - return nullptr; -} - -} // namespace - -void add_basic_ops_to_block(Function* func, const BasicBlock& block, LinkedObjectFile* file) { - (void)file; - for (int instr = block.start_word; instr < block.end_word; instr++) { - auto& i = func->instructions.at(instr); - - int length = 0; - - std::shared_ptr result = nullptr; - if (instr + 4 < block.end_word) { - auto& i1 = func->instructions.at(instr + 1); - auto& i2 = func->instructions.at(instr + 2); - auto& i3 = func->instructions.at(instr + 3); - auto& i4 = func->instructions.at(instr + 4); - switch (i.kind) { - case InstructionKind::LWU: - result = try_lwu(i, i1, i2, i3, i4, instr); - break; - default: - result = nullptr; - } - if (result) { - length = 5; - } - } - - if (!result && instr + 2 < block.end_word) { - auto& next = func->instructions.at(instr + 1); - auto& next_next = func->instructions.at(instr + 2); - switch (i.kind) { - case InstructionKind::DSUBU: - result = try_dsubu(i, next, next_next, instr); - break; - case InstructionKind::SLT: - result = try_slt(i, next, next_next, instr); - break; - case InstructionKind::SLTI: - result = try_slti(i, next, next_next, instr); - break; - case InstructionKind::SLTU: - result = try_sltu(i, next, next_next, instr); - break; - case InstructionKind::SLTIU: - result = try_sltiu(i, next, next_next, instr); - break; - case InstructionKind::CEQS: - result = try_ceqs(i, next, next_next, instr); - break; - case InstructionKind::CLTS: - result = try_clts(i, next, next_next, instr); - break; - case InstructionKind::CLES: - result = try_cles(i, next, next_next, instr); - break; - case InstructionKind::LUI: - result = try_lui(i, next, next_next, instr); - break; - default: - result = nullptr; - } - - if (result) { - length = 3; - } - } - - if (!result && instr + 1 < block.end_word) { - auto& next = func->instructions.at(instr + 1); - // single op failed, try double - switch (i.kind) { - case InstructionKind::DIV: - result = try_div(i, next, instr); - break; - case InstructionKind::DIVU: - result = try_divu(i, next, instr); - break; - case InstructionKind::JALR: - result = try_jalr(i, next, instr); - break; - case InstructionKind::BNE: - result = try_bne(i, next, instr); - break; - case InstructionKind::BNEL: - result = try_bnel(i, next, instr); - break; - case InstructionKind::BEQ: - result = try_beq(i, next, instr); - break; - case InstructionKind::BGTZL: - result = try_bgtzl(i, next, instr); - break; - case InstructionKind::BGEZL: - result = try_bgezl(i, next, instr); - break; - case InstructionKind::BLTZL: - result = try_bltzl(i, next, instr); - break; - case InstructionKind::BEQL: - result = try_beql(i, next, instr); - break; - case InstructionKind::DADDIU: - result = try_daddiu(i, next, instr); - break; - case InstructionKind::LUI: - result = try_lui(i, next, instr); - break; - case InstructionKind::SLT: - result = try_slt(i, next, instr); - break; - default: - result = nullptr; - } - - if (result) { - length = 2; - } - } - - if (!result) { - switch (i.kind) { - case InstructionKind::OR: - result = try_or(i, instr); - break; - case InstructionKind::ORI: - result = try_ori(i, instr); - break; - case InstructionKind::DADDIU: - result = try_daddiu(i, instr); - break; - case InstructionKind::AND: - result = try_and(i, instr); - break; - case InstructionKind::ANDI: - result = try_andi(i, instr); - break; - case InstructionKind::XORI: - result = try_xori(i, instr); - break; - case InstructionKind::NOR: - result = try_nor(i, instr); - break; - case InstructionKind::XOR: - result = try_xor(i, instr); - break; - case InstructionKind::LWC1: - result = try_lwc1(i, instr); - break; - case InstructionKind::MTC1: - result = try_mtc1(i, instr); - break; - case InstructionKind::DIVS: - result = try_float_math_2(i, instr, InstructionKind::DIVS, IR_FloatMath2::DIV); - break; - case InstructionKind::SUBS: - result = try_float_math_2(i, instr, InstructionKind::SUBS, IR_FloatMath2::SUB); - break; - case InstructionKind::ADDS: - result = try_float_math_2(i, instr, InstructionKind::ADDS, IR_FloatMath2::ADD); - break; - case InstructionKind::MULS: - result = try_float_math_2(i, instr, InstructionKind::MULS, IR_FloatMath2::MUL); - break; - case InstructionKind::ABSS: - result = try_float_math_1(i, instr, InstructionKind::ABSS, IR_FloatMath1::ABS); - break; - case InstructionKind::NEGS: - result = try_float_math_1(i, instr, InstructionKind::NEGS, IR_FloatMath1::NEG); - break; - case InstructionKind::SQRTS: - result = try_float_math_1(i, instr, InstructionKind::SQRTS, IR_FloatMath1::SQRT); - break; - case InstructionKind::MINS: - result = try_float_math_2(i, instr, InstructionKind::MINS, IR_FloatMath2::MIN); - break; - case InstructionKind::MAXS: - result = try_float_math_2(i, instr, InstructionKind::MAXS, IR_FloatMath2::MAX); - break; - case InstructionKind::MOVS: - result = try_movs(i, instr); - break; - case InstructionKind::MFC1: - result = try_mfc1(i, instr); - break; - case InstructionKind::DADDU: - result = try_daddu(i, instr); - break; - case InstructionKind::DSUBU: - result = try_dsubu(i, instr); - if (!result) { - // fails if it uses s7 register. - result = to_asm_automatic(i.op_name_to_string(), i, instr); - } - break; - case InstructionKind::MULT3: - result = try_mult3(i, instr); - break; - case InstructionKind::MULTU3: - result = try_multu3(i, instr); - break; - case InstructionKind::POR: - result = try_por(i, instr); - if (!result) { - result = to_asm_automatic(i.op_name_to_string(), i, instr); - } - break; - case InstructionKind::LBU: - result = try_lbu(i, instr); - break; - case InstructionKind::LHU: - result = try_lhu(i, instr); - break; - case InstructionKind::LB: - result = try_lb(i, instr); - break; - case InstructionKind::LH: - result = try_lh(i, instr); - break; - case InstructionKind::LW: - result = try_lw(i, instr); - break; - case InstructionKind::LWU: - result = try_lwu(i, instr); - break; - case InstructionKind::LD: - result = try_ld(i, instr); - break; - case InstructionKind::LQ: - result = try_lq(i, instr); - break; - case InstructionKind::DSRA: - result = try_dsra(i, instr); - break; - case InstructionKind::DSRA32: - result = try_dsra32(i, instr); - break; - case InstructionKind::DSRL: - result = try_dsrl(i, instr); - break; - case InstructionKind::DSRL32: - result = try_dsrl32(i, instr); - break; - case InstructionKind::DSLL: - result = try_dsll(i, instr); - break; - case InstructionKind::DSLL32: - result = try_dsll32(i, instr); - break; - case InstructionKind::ADDIU: - result = try_addiu(i, instr); - if (!result) { - result = to_asm_automatic(i.op_name_to_string(), i, instr); - } - break; - case InstructionKind::LUI: - result = try_lui(i, instr); - break; - case InstructionKind::SLL: - result = try_sll(i, instr); - if (!result) { - result = to_asm_automatic(i.op_name_to_string(), i, instr); - } - break; - case InstructionKind::SB: - result = try_sb(i, instr); - break; - case InstructionKind::SH: - result = try_sh(i, instr); - break; - case InstructionKind::SW: - result = try_sw(i, instr); - break; - case InstructionKind::SD: - result = try_sd(i, instr); - break; - case InstructionKind::SQ: - result = try_sq(i, instr); - break; - case InstructionKind::SWC1: - result = try_swc1(i, instr); - break; - case InstructionKind::CVTWS: - result = try_cvtws(i, instr); - break; - case InstructionKind::CVTSW: - result = try_cvtsw(i, instr); - break; - case InstructionKind::DSRAV: - result = try_dsrav(i, instr); - break; - case InstructionKind::DSRLV: - result = try_dsrlv(i, instr); - break; - case InstructionKind::DSLLV: - result = try_dsllv(i, instr); - break; - case InstructionKind::SUBU: - result = try_subu(i, instr); - break; - case InstructionKind::SLLV: - result = try_sllv(i, instr); - break; - case InstructionKind::MOVN: - result = try_movn(i, instr); - if (!result) { - result = to_asm_automatic(i.op_name_to_string(), i, instr); - } - break; - case InstructionKind::MOVZ: - result = try_movz(i, instr); - if (!result) { - result = to_asm_automatic(i.op_name_to_string(), i, instr); - } - break; - - // Everything below here is an "asm passthrough". - case InstructionKind::JR: - result = to_asm_src_reg("jr", i, instr); - break; - - // reg reg - case InstructionKind::QMFC2: - result = to_asm_dst_reg_src_reg(i.op_name_to_string(), i, instr); - break; - - // VU/COP2 - case InstructionKind::VMOVE: - case InstructionKind::VFTOI0: - case InstructionKind::VFTOI4: - case InstructionKind::VFTOI12: - case InstructionKind::VITOF0: - case InstructionKind::VITOF12: - case InstructionKind::VITOF15: - case InstructionKind::VABS: - case InstructionKind::VADD: - case InstructionKind::VSUB: - case InstructionKind::VMUL: - case InstructionKind::VMINI: - case InstructionKind::VMAX: - case InstructionKind::VOPMSUB: - case InstructionKind::VMADD: - case InstructionKind::VMSUB: - case InstructionKind::VADD_BC: - case InstructionKind::VSUB_BC: - case InstructionKind::VMUL_BC: - case InstructionKind::VMULA_BC: - case InstructionKind::VMADD_BC: - case InstructionKind::VADDA_BC: - case InstructionKind::VMADDA_BC: - case InstructionKind::VMSUBA_BC: - case InstructionKind::VMSUB_BC: - case InstructionKind::VMINI_BC: - case InstructionKind::VMAX_BC: - case InstructionKind::VADDQ: - case InstructionKind::VSUBQ: - case InstructionKind::VMULQ: - case InstructionKind::VMSUBQ: - case InstructionKind::VMULA: - case InstructionKind::VADDA: - case InstructionKind::VMADDA: - case InstructionKind::VOPMULA: - case InstructionKind::VDIV: - case InstructionKind::VCLIP: - case InstructionKind::VMULAQ: - case InstructionKind::VMTIR: - case InstructionKind::VIAND: - case InstructionKind::VLQI: - case InstructionKind::VIADDI: - case InstructionKind::VSQI: - case InstructionKind::VRGET: - case InstructionKind::VSQRT: - case InstructionKind::VRSQRT: - case InstructionKind::VRXOR: - case InstructionKind::VRNEXT: - case InstructionKind::VNOP: - case InstructionKind::VWAITQ: - case InstructionKind::VCALLMS: - - // FPU/COP1 - case InstructionKind::MULAS: - case InstructionKind::MADDAS: - case InstructionKind::MADDS: - case InstructionKind::ADDAS: - - // Moves / Loads / Stores - case InstructionKind::CTC2: - case InstructionKind::CFC2: - case InstructionKind::SQC2: - case InstructionKind::LQC2: - case InstructionKind::LDR: - case InstructionKind::LDL: - case InstructionKind::QMTC2: - case InstructionKind::MFC0: - case InstructionKind::MTC0: - case InstructionKind::SYNCL: - case InstructionKind::SYNCP: - case InstructionKind::SYSCALL: - case InstructionKind::CACHE_DXWBIN: - case InstructionKind::MTPC: - case InstructionKind::MFPC: - - // random math - case InstructionKind::ADDU: - case InstructionKind::SRL: // maybe bitfield ops use this? - case InstructionKind::SRA: - case InstructionKind::SLT: - case InstructionKind::SLTI: - - // MMI - case InstructionKind::PSLLW: - case InstructionKind::PSRAW: - case InstructionKind::PSRAH: - case InstructionKind::PLZCW: - case InstructionKind::PMFHL_UW: - case InstructionKind::PMFHL_LW: - case InstructionKind::PMFHL_LH: - case InstructionKind::PSLLH: - case InstructionKind::PSRLH: - case InstructionKind::PEXTLW: - case InstructionKind::PPACH: - case InstructionKind::PSUBW: - case InstructionKind::PCGTW: - case InstructionKind::PEXTLH: - case InstructionKind::PEXTLB: - case InstructionKind::PMAXH: - case InstructionKind::PPACB: - case InstructionKind::PADDW: - case InstructionKind::PADDH: - case InstructionKind::PMAXW: - case InstructionKind::PPACW: - case InstructionKind::PCEQW: - case InstructionKind::PEXTUW: - case InstructionKind::PMINH: - case InstructionKind::PEXTUH: - case InstructionKind::PEXTUB: - case InstructionKind::PCEQB: - case InstructionKind::PMINW: - case InstructionKind::PABSW: - case InstructionKind::PCPYLD: - case InstructionKind::PROT3W: - case InstructionKind::PAND: - case InstructionKind::PMADDH: - case InstructionKind::PMULTH: - case InstructionKind::PEXEW: - case InstructionKind::PCPYUD: - case InstructionKind::PNOR: - case InstructionKind::PCPYH: - case InstructionKind::PINTEH: - - case InstructionKind::MTDAB: - case InstructionKind::MTDABM: - - // 128 bit integer - // case InstructionKind::LQ: - // case InstructionKind::SQ: - - result = to_asm_automatic(i.op_name_to_string(), i, instr); - break; - default: - result = nullptr; - } - - if (result) { - length = 1; - } - } - - // everything failed - if (!result) { - // temp hack for debug: - lg::error("Instruction -> BasicOp failed on {}", i.to_string(file->labels)); - func->add_basic_op(std::make_shared(), instr, instr + 1); - } else { - if (!func->contains_asm_ops && dynamic_cast(result.get())) { - func->warnings.info("Contains asm ops"); - func->contains_asm_ops = true; - } - - if (!result->reg_info_set) { - printf("Failed reg info %s\n", result->print(*file).c_str()); - } - func->add_basic_op(result, instr, instr + length); - instr += (length - 1); - } - } -} -} // namespace decompiler \ No newline at end of file diff --git a/decompiler/IR/BasicOpBuilder.h b/decompiler/IR/BasicOpBuilder.h deleted file mode 100644 index d20b06c850..0000000000 --- a/decompiler/IR/BasicOpBuilder.h +++ /dev/null @@ -1,15 +0,0 @@ -/*! - * @file BasicOpBuilder.h - * Analyzes a basic block and converts instructions to BasicOps. - * These will be used later to convert the Cfg into the nested IR format. - */ - -#pragma once - -namespace decompiler { -class Function; -struct BasicBlock; -class LinkedObjectFile; - -void add_basic_ops_to_block(Function* func, const BasicBlock& block, LinkedObjectFile* file); -} // namespace decompiler \ No newline at end of file diff --git a/decompiler/IR/IR.cpp b/decompiler/IR/IR.cpp deleted file mode 100644 index ea53180f71..0000000000 --- a/decompiler/IR/IR.cpp +++ /dev/null @@ -1,1006 +0,0 @@ -#include "IR.h" -#include "decompiler/ObjectFile/LinkedObjectFile.h" -#include "common/goos/PrettyPrinter.h" -#include "third-party/fmt/core.h" - -namespace decompiler { -// hack to print out reverse deref paths on loads to help with debugging load stuff. -bool enable_hack_load_path_print = false; -// hack to print (begin x) as x to make debug output easier to read. -bool inline_single_begins = true; - -std::vector> IR::get_all_ir(LinkedObjectFile& file) const { - (void)file; - std::vector> result; - get_children(&result); - size_t last_checked = 0; - size_t last_last_checked = -1; - - while (last_checked != last_last_checked) { - last_last_checked = last_checked; - auto end_of_check = result.size(); - for (size_t i = last_checked; i < end_of_check; i++) { - auto it = result.at(i).get(); - ASSERT(it); - it->get_children(&result); - } - last_checked = end_of_check; - } - - return result; -} - -std::string IR::print(const LinkedObjectFile& file) const { - return pretty_print::to_string(to_form(file)); -} - -namespace { -template -void add_regs_to_str(const T& regs, std::string& str) { - bool first = true; - for (auto& reg : regs) { - if (first) { - first = false; - } else { - str.push_back(' '); - } - str.append(reg.to_charp()); - } -} -} // namespace - -goos::Object IR_Failed::to_form(const LinkedObjectFile& file) const { - (void)file; - return pretty_print::build_list("INVALID-OPERATION"); -} - -void IR_Failed::get_children(std::vector>* output) const { - (void)output; -} - -goos::Object IR_Register::to_form(const LinkedObjectFile& file) const { - (void)file; - return pretty_print::to_symbol(reg.to_charp()); -} - -void IR_Register::get_children(std::vector>* output) const { - (void)output; -} - -goos::Object IR_Set::to_form(const LinkedObjectFile& file) const { - return pretty_print::build_list(pretty_print::to_symbol("set!"), dst->to_form(file), - src->to_form(file)); -} - -void IR_Set::get_children(std::vector>* output) const { - // note that we are not returning clobber here because it shouldn't contain anything that - // the IR simplification code should touch. - output->push_back(dst); - output->push_back(src); -} - -template <> -void IR_Set_Atomic::update_reginfo_self(int n_dest, int n_src, int n_clobber) { - auto dst_as_reg = dynamic_cast(dst.get()); - if (dst_as_reg) { - write_regs.push_back(dst_as_reg->reg); - } - - auto src_as = dynamic_cast(src.get()); - ASSERT(src_as); - - for (auto& x : {src_as->arg0, src_as->arg1}) { - auto reg = dynamic_cast(x.get()); - if (reg) { - read_regs.push_back(reg->reg); - } - } - - ASSERT(int(write_regs.size()) == n_dest); - ASSERT(int(read_regs.size()) == n_src); - ASSERT(int(clobber_regs.size()) == n_clobber); - reg_info_set = true; -} - -template <> -void IR_Set_Atomic::update_reginfo_self(int n_dest, int n_src, int n_clobber) { - auto dst_as_reg = dynamic_cast(dst.get()); - if (dst_as_reg) { - write_regs.push_back(dst_as_reg->reg); - } - - auto src_as = dynamic_cast(src.get()); - ASSERT(src_as); - - auto reg = dynamic_cast(src_as->arg.get()); - if (reg) { - read_regs.push_back(reg->reg); - } - - ASSERT(int(write_regs.size()) == n_dest); - ASSERT(int(read_regs.size()) == n_src); - ASSERT(int(clobber_regs.size()) == n_clobber); - reg_info_set = true; -} - -template <> -void IR_Set_Atomic::update_reginfo_self(int n_dest, int n_src, int n_clobber) { - auto dst_as_reg = dynamic_cast(dst.get()); - if (dst_as_reg) { - write_regs.push_back(dst_as_reg->reg); - } - - auto src_as = dynamic_cast(src.get()); - ASSERT(src_as); - - // try to get the source as a register - auto reg = dynamic_cast(src_as->location.get()); - if (reg) { - read_regs.push_back(reg->reg); - } - - // or as math with a register - auto math = dynamic_cast(src_as->location.get()); - if (math) { - for (auto& x : {math->arg0, math->arg1}) { - auto math_reg = dynamic_cast(x.get()); - if (math_reg) { - read_regs.push_back(math_reg->reg); - } - } - } - - ASSERT(int(write_regs.size()) == n_dest); - ASSERT(int(read_regs.size()) == n_src); - ASSERT(int(clobber_regs.size()) == n_clobber); - reg_info_set = true; -} - -template <> -void IR_Set_Atomic::update_reginfo_self(int n_dest, int n_src, int n_clobber) { - auto dst_as_reg = dynamic_cast(dst.get()); - if (dst_as_reg) { - write_regs.push_back(dst_as_reg->reg); - } - - auto src_as_cmp = dynamic_cast(src.get()); - ASSERT(src_as_cmp); - for (auto& x : {src_as_cmp->condition.src0, src_as_cmp->condition.src1}) { - auto as_reg = dynamic_cast(x.get()); - if (as_reg) { - read_regs.push_back(as_reg->reg); - } - } - - auto as_reg = dynamic_cast(src_as_cmp->condition.clobber.get()); - if (as_reg) { - clobber_regs.push_back(as_reg->reg); - } - - ASSERT(int(write_regs.size()) == n_dest); - ASSERT(int(read_regs.size()) == n_src); - ASSERT(int(clobber_regs.size()) == n_clobber); - reg_info_set = true; -} - -/*! - * Set the register info, assuming this is a register to register set. - */ -void IR_Set_Atomic::update_reginfo_regreg() { - auto dst_as_reg = dynamic_cast(dst.get()); - if (dst_as_reg) { - write_regs.push_back(dst_as_reg->reg); - } - - auto src_as = dynamic_cast(src.get()); - - if (src_as) { - read_regs.push_back(src_as->reg); - } - - ASSERT(int(write_regs.size()) == 1); - ASSERT(int(read_regs.size()) == 1); - ASSERT(int(clobber_regs.size()) == 0); - reg_info_set = true; -} - -goos::Object IR_Store::to_form(const LinkedObjectFile& file) const { - std::string store_operator; - switch (kind) { - case Kind::FLOAT: - store_operator = "s.f"; - break; - case Kind::INTEGER: - switch (size) { - case 1: - store_operator = "s.b"; - break; - case 2: - store_operator = "s.h"; - break; - case 4: - store_operator = "s.w"; - break; - case 8: - store_operator = "s.d"; - break; - case 16: - store_operator = "s.q"; - break; - default: - ASSERT(false); - } - break; - default: - ASSERT(false); - } - - return pretty_print::build_list(pretty_print::to_symbol(store_operator), dst->to_form(file), - src->to_form(file)); -} - -goos::Object IR_Store_Atomic::to_form(const LinkedObjectFile& file) const { - std::string store_operator; - switch (kind) { - case Kind::FLOAT: - store_operator = "s.f"; - break; - case Kind::INTEGER: - switch (size) { - case 1: - store_operator = "s.b"; - break; - case 2: - store_operator = "s.h"; - break; - case 4: - store_operator = "s.w"; - break; - case 8: - store_operator = "s.d"; - break; - case 16: - store_operator = "s.q"; - break; - default: - ASSERT(false); - } - break; - default: - ASSERT(false); - } - - return pretty_print::build_list(pretty_print::to_symbol(store_operator), dst->to_form(file), - src->to_form(file)); -} - -void IR_Store_Atomic::update_reginfo_self(int n_dest, int n_src, int n_clobber) { - auto src_reg = dynamic_cast(src.get()); - if (src_reg) { - read_regs.push_back(src_reg->reg); - } - - auto dst_reg = dynamic_cast(dst.get()); - if (dst_reg) { - read_regs.push_back(dst_reg->reg); - } - - // or as math with a register - auto math = dynamic_cast(dst.get()); - if (math) { - for (auto& x : {math->arg0, math->arg1}) { - auto math_reg = dynamic_cast(x.get()); - if (math_reg) { - read_regs.push_back(math_reg->reg); - } - } - } - - ASSERT(int(write_regs.size()) == n_dest); - ASSERT(int(read_regs.size()) == n_src); - ASSERT(int(clobber_regs.size()) == n_clobber); - reg_info_set = true; -} - -goos::Object IR_Symbol::to_form(const LinkedObjectFile& file) const { - (void)file; - return pretty_print::to_symbol("'" + name); -} - -void IR_Symbol::get_children(std::vector>* output) const { - (void)output; -} - -goos::Object IR_SymbolValue::to_form(const LinkedObjectFile& file) const { - (void)file; - return pretty_print::to_symbol(name); -} - -void IR_SymbolValue::get_children(std::vector>* output) const { - (void)output; -} - -goos::Object IR_EmptyPair::to_form(const LinkedObjectFile& file) const { - (void)file; - return pretty_print::to_symbol("'()"); -} - -void IR_EmptyPair::get_children(std::vector>* output) const { - (void)output; -} - -goos::Object IR_StaticAddress::to_form(const LinkedObjectFile& file) const { - // return pretty_print::build_list(pretty_print::to_symbol("&"), file.get_label_name(label_id)); - return pretty_print::to_symbol(file.get_label_name(label_id)); -} - -void IR_StaticAddress::get_children(std::vector>* output) const { - (void)output; -} - -goos::Object IR_Load::to_form(const LinkedObjectFile& file) const { - if (load_path_set && enable_hack_load_path_print) { - std::vector list; - if (load_path_addr_of) { - list.push_back(pretty_print::to_symbol("&->")); - } else { - list.push_back(pretty_print::to_symbol("->")); - } - list.push_back(load_path_base->to_form(file)); - for (auto& x : load_path) { - list.push_back(pretty_print::to_symbol(x)); - } - return pretty_print::build_list(list); - } - std::string load_operator; - switch (kind) { - case FLOAT: - load_operator = "l.f"; - break; - case UNSIGNED: - switch (size) { - case 1: - load_operator = "l.bu"; - break; - case 2: - load_operator = "l.hu"; - break; - case 4: - load_operator = "l.wu"; - break; - case 8: - load_operator = "l.d"; - break; - case 16: - load_operator = "l.q"; - break; - default: - ASSERT(false); - } - break; - case SIGNED: - switch (size) { - case 1: - load_operator = "l.bs"; - break; - case 2: - load_operator = "l.hs"; - break; - case 4: - load_operator = "l.ws"; - break; - default: - ASSERT(false); - } - break; - default: - ASSERT(false); - } - return pretty_print::build_list(pretty_print::to_symbol(load_operator), location->to_form(file)); -} - -void IR_Load::get_children(std::vector>* output) const { - output->push_back(location); -} - -goos::Object IR_FloatMath2::to_form(const LinkedObjectFile& file) const { - std::string math_operator; - switch (kind) { - case DIV: - math_operator = "/.f"; - break; - case MUL: - math_operator = "*.f"; - break; - case ADD: - math_operator = "+.f"; - break; - case SUB: - math_operator = "-.f"; - break; - case MIN: - math_operator = "min.f"; - break; - case MAX: - math_operator = "max.f"; - break; - default: - ASSERT(false); - } - - return pretty_print::build_list(pretty_print::to_symbol(math_operator), arg0->to_form(file), - arg1->to_form(file)); -} - -void IR_FloatMath2::get_children(std::vector>* output) const { - output->push_back(arg0); - output->push_back(arg1); -} - -void IR_FloatMath1::get_children(std::vector>* output) const { - output->push_back(arg); -} - -goos::Object IR_IntMath2::to_form(const LinkedObjectFile& file) const { - std::string math_operator; - switch (kind) { - case ADD: - math_operator = "+.i"; - break; - case SUB: - math_operator = "-.i"; - break; - case MUL_SIGNED: - math_operator = "*.si"; - break; - case MUL_UNSIGNED: - math_operator = "*.ui"; - break; - case DIV_SIGNED: - math_operator = "/.si"; - break; - case MOD_SIGNED: - math_operator = "mod.si"; - break; - case DIV_UNSIGNED: - math_operator = "/.ui"; - break; - case MOD_UNSIGNED: - math_operator = "mod.ui"; - break; - case OR: - math_operator = "logior"; - break; - case AND: - math_operator = "logand"; - break; - case NOR: - math_operator = "lognor"; - break; - case XOR: - math_operator = "logxor"; - break; - case LEFT_SHIFT: - math_operator = "shl"; - break; - case RIGHT_SHIFT_ARITH: - math_operator = "sar"; - break; - case RIGHT_SHIFT_LOGIC: - math_operator = "shr"; - break; - case MIN_SIGNED: - math_operator = "min.si"; - break; - case MAX_SIGNED: - math_operator = "max.si"; - break; - default: - ASSERT(false); - } - return pretty_print::build_list(pretty_print::to_symbol(math_operator), arg0->to_form(file), - arg1->to_form(file)); -} - -void IR_IntMath2::get_children(std::vector>* output) const { - output->push_back(arg0); - output->push_back(arg1); -} - -goos::Object IR_IntMath1::to_form(const LinkedObjectFile& file) const { - std::string math_operator; - switch (kind) { - case NOT: - math_operator = "lognot"; - break; - case ABS: - math_operator = "abs.si"; - break; - case NEG: - math_operator = "-.i"; - break; - default: - ASSERT(false); - } - return pretty_print::build_list(pretty_print::to_symbol(math_operator), arg->to_form(file)); -} - -void IR_IntMath1::get_children(std::vector>* output) const { - output->push_back(arg); -} - -goos::Object IR_FloatMath1::to_form(const LinkedObjectFile& file) const { - std::string math_operator; - switch (kind) { - case FLOAT_TO_INT: - math_operator = "int<-float"; - break; - case INT_TO_FLOAT: - math_operator = "float<-int"; - break; - case ABS: - math_operator = "abs.f"; - break; - case NEG: - math_operator = "neg.f"; - break; - case SQRT: - math_operator = "sqrt.f"; - break; - default: - ASSERT(false); - } - return pretty_print::build_list(pretty_print::to_symbol(math_operator), arg->to_form(file)); -} - -goos::Object IR_Call::to_form(const LinkedObjectFile& file) const { - (void)file; - std::vector result; - result.push_back(pretty_print::to_symbol("call!")); - - if (call_type_set) { - result.push_back(pretty_print::to_symbol(":arg-count")); - result.push_back(pretty_print::to_symbol(std::to_string(call_type.arg_count() - 1))); - } - - for (auto& x : args) { - result.push_back(x->to_form(file)); - } - return pretty_print::build_list(result); -} - -void IR_Call::get_children(std::vector>* output) const { - (void)output; -} - -goos::Object IR_IntegerConstant::to_form(const LinkedObjectFile& file) const { - (void)file; - return pretty_print::to_symbol(std::to_string(value)); -} - -void IR_IntegerConstant::get_children(std::vector>* output) const { - (void)output; -} - -goos::Object BranchDelay::to_form(const LinkedObjectFile& file) const { - (void)file; - switch (kind) { - case NOP: - return pretty_print::build_list("nop"); - case SET_REG_FALSE: - return pretty_print::build_list(pretty_print::to_symbol("set!"), destination->to_form(file), - "'#f"); - case SET_REG_TRUE: - return pretty_print::build_list(pretty_print::to_symbol("set!"), destination->to_form(file), - "'#t"); - case SET_REG_REG: - return pretty_print::build_list(pretty_print::to_symbol("set!"), destination->to_form(file), - source->to_form(file)); - case SET_BINTEGER: - return pretty_print::build_list(pretty_print::to_symbol("set!"), destination->to_form(file), - "binteger"); - case SET_PAIR: - return pretty_print::build_list(pretty_print::to_symbol("set!"), destination->to_form(file), - "pair"); - case DSLLV: - return pretty_print::build_list( - pretty_print::to_symbol("set!"), destination->to_form(file), - pretty_print::build_list(pretty_print::to_symbol("shl"), source->to_form(file), - source2->to_form(file))); - case NEGATE: - return pretty_print::build_list(pretty_print::to_symbol("set!"), destination->to_form(file), - pretty_print::build_list("-", source->to_form(file))); - case UNKNOWN: - return pretty_print::build_list("unknown-branch-delay"); - default: - ASSERT(false); - return {}; - } -} - -void BranchDelay::get_children(std::vector>* output) const { - if (destination) { - output->push_back(destination); - } - - if (source) { - output->push_back(source); - } - - if (source2) { - output->push_back(source2); - } -} - -goos::Object IR_Nop::to_form(const LinkedObjectFile& file) const { - (void)file; - return pretty_print::build_list("nop!"); -} - -int Condition::num_args() const { - switch (kind) { - case NOT_EQUAL: - case EQUAL: - case LESS_THAN_SIGNED: - case LESS_THAN_UNSIGNED: - case GREATER_THAN_SIGNED: - case GREATER_THAN_UNSIGNED: - case LEQ_SIGNED: - case GEQ_SIGNED: - case LEQ_UNSIGNED: - case GEQ_UNSIGNED: - case FLOAT_EQUAL: - case FLOAT_NOT_EQUAL: - case FLOAT_LESS_THAN: - case FLOAT_GEQ: - case FLOAT_GREATER_THAN: - case FLOAT_LEQ: - return 2; - case ZERO: - case NONZERO: - case FALSE: - case TRUTHY: - case GREATER_THAN_ZERO_SIGNED: - case GEQ_ZERO_SIGNED: - case LESS_THAN_ZERO: - case LEQ_ZERO_SIGNED: - return 1; - case ALWAYS: - case NEVER: - return 0; - default: - ASSERT(false); - return -1; - } -} - -void Condition::get_children(std::vector>* output) const { - if (src0) { - output->push_back(src0); - } - - if (src1) { - output->push_back(src1); - } -} - -void Condition::invert() { - switch (kind) { - case NOT_EQUAL: - kind = EQUAL; - break; - case EQUAL: - kind = NOT_EQUAL; - break; - case LESS_THAN_SIGNED: - kind = GEQ_SIGNED; - break; - case GREATER_THAN_SIGNED: - kind = LEQ_SIGNED; - break; - case LEQ_SIGNED: - kind = GREATER_THAN_SIGNED; - break; - case GEQ_SIGNED: - kind = LESS_THAN_SIGNED; - break; - case GREATER_THAN_ZERO_SIGNED: - kind = LEQ_ZERO_SIGNED; - break; - case LEQ_ZERO_SIGNED: - kind = GREATER_THAN_ZERO_SIGNED; - break; - case LESS_THAN_ZERO: - kind = GEQ_ZERO_SIGNED; - break; - case GEQ_ZERO_SIGNED: - kind = LESS_THAN_ZERO; - break; - case LESS_THAN_UNSIGNED: - kind = GEQ_UNSIGNED; - break; - case GREATER_THAN_UNSIGNED: - kind = LEQ_UNSIGNED; - break; - case LEQ_UNSIGNED: - kind = GREATER_THAN_UNSIGNED; - break; - case GEQ_UNSIGNED: - kind = LESS_THAN_UNSIGNED; - break; - case ZERO: - kind = NONZERO; - break; - case NONZERO: - kind = ZERO; - break; - case FALSE: - kind = TRUTHY; - break; - case TRUTHY: - kind = FALSE; - break; - case ALWAYS: - kind = NEVER; - break; - case NEVER: - kind = ALWAYS; - break; - case FLOAT_EQUAL: - kind = FLOAT_NOT_EQUAL; - break; - case FLOAT_NOT_EQUAL: - kind = FLOAT_EQUAL; - break; - case FLOAT_LESS_THAN: - kind = FLOAT_GEQ; - break; - case FLOAT_GEQ: - kind = FLOAT_LESS_THAN; - break; - case FLOAT_GREATER_THAN: - kind = FLOAT_LEQ; - break; - case FLOAT_LEQ: - kind = FLOAT_GREATER_THAN; - break; - default: - ASSERT(false); - } -} - -goos::Object Condition::to_form(const LinkedObjectFile& file) const { - int nargs = num_args(); - std::string condtion_operator; - switch (kind) { - case NOT_EQUAL: - condtion_operator = "!="; - break; - case EQUAL: - condtion_operator = "="; - break; - case LESS_THAN_SIGNED: - condtion_operator = "<.si"; - break; - case LESS_THAN_UNSIGNED: - condtion_operator = "<.ui"; - break; - case GREATER_THAN_SIGNED: - condtion_operator = ">.si"; - break; - case GREATER_THAN_UNSIGNED: - condtion_operator = ">.ui"; - break; - case LEQ_SIGNED: - condtion_operator = "<=.si"; - break; - case GEQ_SIGNED: - condtion_operator = ">=.si"; - break; - case LEQ_UNSIGNED: - condtion_operator = "<=.ui"; - break; - case GEQ_UNSIGNED: - condtion_operator = ">=.ui"; - break; - case ZERO: - condtion_operator = "zero?"; - break; - case NONZERO: - condtion_operator = "nonzero?"; - break; - case FALSE: - condtion_operator = "not"; - break; - case TRUTHY: - condtion_operator = ""; - break; - case ALWAYS: - condtion_operator = "'#t"; - break; - case NEVER: - condtion_operator = "'#f"; - break; - case FLOAT_EQUAL: - condtion_operator = "=.f"; - break; - case FLOAT_NOT_EQUAL: - condtion_operator = "!=.f"; - break; - case FLOAT_LESS_THAN: - condtion_operator = "<.f"; - break; - case FLOAT_GEQ: - condtion_operator = ">=.f"; - break; - case FLOAT_GREATER_THAN: - condtion_operator = ">.f"; - break; - case FLOAT_LEQ: - condtion_operator = "<=.f"; - break; - case GREATER_THAN_ZERO_SIGNED: - condtion_operator = ">0.si"; - break; - case GEQ_ZERO_SIGNED: - condtion_operator = ">=0.si"; - break; - case LESS_THAN_ZERO: - condtion_operator = "<0.si"; - break; - case LEQ_ZERO_SIGNED: - condtion_operator = "<=0.si"; - break; - default: - ASSERT(false); - } - - if (nargs == 2) { - return pretty_print::build_list(pretty_print::to_symbol(condtion_operator), src0->to_form(file), - src1->to_form(file)); - } else if (nargs == 1) { - if (condtion_operator.empty()) { - return src0->to_form(file); - } else { - return pretty_print::build_list(pretty_print::to_symbol(condtion_operator), - src0->to_form(file)); - } - } else if (nargs == 0) { - return pretty_print::to_symbol(condtion_operator); - } else { - ASSERT(false); - return {}; - } -} - -goos::Object IR_Branch::to_form(const LinkedObjectFile& file) const { - return pretty_print::build_list( - pretty_print::to_symbol(likely ? "bl!" : "b!"), condition.to_form(file), - pretty_print::to_symbol(file.get_label_name(dest_label_idx)), branch_delay.to_form(file)); -} - -void IR_Branch::get_children(std::vector>* output) const { - condition.get_children(output); - branch_delay.get_children(output); -} - -void IR_Branch_Atomic::update_reginfo_self(int n_dest, int n_src, int n_clobber) { - // first, grab from condition - for (auto& x : {condition.src0, condition.src1}) { - auto as_reg = dynamic_cast(x.get()); - if (as_reg) { - read_regs.push_back(as_reg->reg); - } - } - - auto as_reg = dynamic_cast(condition.clobber.get()); - if (as_reg) { - clobber_regs.push_back(as_reg->reg); - } - ASSERT(int(write_regs.size()) == n_dest); - ASSERT(int(read_regs.size()) == n_src); - ASSERT(int(clobber_regs.size()) == n_clobber); - - // copy from branch delay - read_regs.insert(read_regs.end(), branch_delay.read_regs.begin(), branch_delay.read_regs.end()); - write_regs.insert(write_regs.end(), branch_delay.write_regs.begin(), - branch_delay.write_regs.end()); - clobber_regs.insert(clobber_regs.end(), branch_delay.clobber_regs.begin(), - branch_delay.clobber_regs.end()); - - reg_info_set = true; -} - -goos::Object IR_Compare::to_form(const LinkedObjectFile& file) const { - return condition.to_form(file); -} - -void IR_Compare::get_children(std::vector>* output) const { - condition.get_children(output); -} - -goos::Object IR_Suspend_Atomic::to_form(const LinkedObjectFile& file) const { - (void)file; - return pretty_print::build_list("suspend!"); -} - -void IR_Nop::get_children(std::vector>* output) const { - (void)output; -} - -void IR_Suspend_Atomic::get_children(std::vector>* output) const { - (void)output; -} - -goos::Object IR_Breakpoint_Atomic::to_form(const LinkedObjectFile& file) const { - (void)file; - return pretty_print::build_list("breakpoint!"); -} - -void IR_Breakpoint_Atomic::get_children(std::vector>* output) const { - (void)output; -} - -goos::Object IR_AsmOp::to_form(const LinkedObjectFile& file) const { - std::vector forms; - forms.push_back(pretty_print::to_symbol(name)); - for (auto& x : {dst, src0, src1, src2}) { - if (x) { - forms.push_back(x->to_form(file)); - } - } - return pretty_print::build_list(forms); -} - -void IR_AsmOp::get_children(std::vector>* output) const { - for (auto& x : {dst, src0, src1}) { - if (x) { - output->push_back(x); - } - } -} - -void IR_AsmOp_Atomic::set_reg_info() { - auto dst_as_reg = dynamic_cast(dst.get()); - if (dst_as_reg) { - write_regs.push_back(dst_as_reg->reg); - } - - for (auto& x : {src0, src1, src2}) { - auto src_as_reg = dynamic_cast(x.get()); - if (src_as_reg) { - read_regs.push_back(src_as_reg->reg); - } - } - - reg_info_set = true; -} - -goos::Object IR_CMoveF::to_form(const LinkedObjectFile& file) const { - return pretty_print::build_list( - pretty_print::to_symbol(on_zero ? "cmove-false-on-zero" : "cmove-false-on-nonzero"), - src->to_form(file)); -} - -void IR_CMoveF::get_children(std::vector>* output) const { - output->push_back(src); -} - -goos::Object IR_AsmReg::to_form(const LinkedObjectFile& file) const { - (void)file; - switch (kind) { - case VU_Q: - return pretty_print::to_symbol("Q"); - case VU_ACC: - return pretty_print::to_symbol("ACC"); - default: - ASSERT(false); - return {}; - } -} - -void IR_AsmReg::get_children(std::vector>* output) const { - (void)output; -} - -} // namespace decompiler \ No newline at end of file diff --git a/decompiler/IR/IR.h b/decompiler/IR/IR.h deleted file mode 100644 index a6c30be9d2..0000000000 --- a/decompiler/IR/IR.h +++ /dev/null @@ -1,454 +0,0 @@ -#pragma once - -#ifndef JAK_IR_H -#define JAK_IR_H - -#include -#include -#include -#include -#include "decompiler/Disasm/Register.h" -#include "common/type_system/TypeSpec.h" -#include "decompiler/util/DecompilerTypeSystem.h" -#include "decompiler/util/TP_Type.h" -#include "common/util/Assert.h" - -namespace goos { -class Object; -} - -namespace decompiler { -class LinkedObjectFile; -class DecompilerTypeSystem; -class ExpressionStack; - -class IR { - public: - virtual goos::Object to_form(const LinkedObjectFile& file) const = 0; - std::vector> get_all_ir(LinkedObjectFile& file) const; - std::string print(const LinkedObjectFile& file) const; - virtual void get_children(std::vector>* output) const = 0; - bool is_basic_op = false; - virtual ~IR() = default; -}; - -class IR_Atomic : public virtual IR { - public: - std::vector read_regs, write_regs, clobber_regs; - std::unordered_set consumed, written_and_unused; - bool reg_info_set = false; - - TypeState end_types; // types at the end of this instruction - std::vector warnings; - void warn(const std::string& str) { warnings.emplace_back(str); } -}; - -class IR_Failed : public virtual IR { - public: - IR_Failed() = default; - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -class IR_Failed_Atomic : public IR_Failed, public IR_Atomic { - public: - IR_Failed_Atomic() = default; -}; - -class IR_Register : public virtual IR { - public: - IR_Register(Register _reg, int _instr_idx) : reg(_reg), instr_idx(_instr_idx) {} - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; - Register reg; - int instr_idx = -1; -}; - -class IR_Set : public virtual IR { - public: - enum Kind { - REG_64, - LOAD, - STORE, - SYM_LOAD, - SYM_STORE, - FPR_TO_GPR64, - GPR_TO_FPR, - REG_FLT, - REG_I128, - EXPR - } kind; - IR_Set(Kind _kind, std::shared_ptr _dst, std::shared_ptr _src) - : kind(_kind), dst(std::move(_dst)), src(std::move(_src)) {} - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; - - std::shared_ptr dst, src; - std::shared_ptr clobber = nullptr; -}; - -// todo -class IR_Set_Atomic : public IR_Set, public IR_Atomic { - public: - IR_Set_Atomic(IR_Set::Kind _kind, std::shared_ptr _dst, std::shared_ptr _src) - : IR_Set(_kind, std::move(_dst), std::move(_src)) {} - - template - void update_reginfo_self(int n_dest, int n_src, int n_clobber); - void update_reginfo_regreg(); -}; - -class IR_IntMath2; -template <> -void IR_Set_Atomic::update_reginfo_self(int n_dest, int n_src, int n_clobber); - -class IR_Store : public virtual IR_Set { - public: - enum class Kind { INTEGER, FLOAT } kind; - IR_Store(Kind _kind, std::shared_ptr _dst, std::shared_ptr _src, int _size) - : IR_Set(IR_Set::STORE, std::move(_dst), std::move(_src)), kind(_kind), size(_size) {} - int size; - goos::Object to_form(const LinkedObjectFile& file) const override; -}; - -/*! - * Note, IR_Store_Atomic does not appear as a IR_Set_Atomic. - * This is to avoid the "diamond problem". - */ -class IR_Store_Atomic : public IR_Set_Atomic { - public: - enum class Kind { INTEGER, FLOAT } kind; - IR_Store_Atomic(Kind _kind, std::shared_ptr _dst, std::shared_ptr _src, int _size) - : IR_Set_Atomic(IR_Set::STORE, std::move(_dst), std::move(_src)), kind(_kind), size(_size) {} - int size; - goos::Object to_form(const LinkedObjectFile& file) const override; - void update_reginfo_self(int n_dest, int n_src, int n_clobber); -}; - -class IR_Symbol : public virtual IR { - public: - explicit IR_Symbol(std::string _name) : name(std::move(_name)) {} - std::string name; - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -class IR_SymbolValue : public virtual IR { - public: - explicit IR_SymbolValue(std::string _name) : name(std::move(_name)) {} - std::string name; - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -class IR_EmptyPair : public virtual IR { - public: - explicit IR_EmptyPair() = default; - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -class IR_StaticAddress : public virtual IR { - public: - explicit IR_StaticAddress(int _label_id) : label_id(_label_id) {} - int label_id = -1; - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -class IR_Load : public virtual IR { - public: - enum Kind { UNSIGNED, SIGNED, FLOAT } kind; - - IR_Load(Kind _kind, int _size, std::shared_ptr _location) - : kind(_kind), size(_size), location(std::move(_location)) {} - int size; - std::shared_ptr location; - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; - - // this load_path stuff is just for debugging and shouldn't be used as part of the real - // decompilation. - void clear_load_path() { - load_path_set = false; - load_path_addr_of = false; - load_path.clear(); - load_path_base = nullptr; - } - std::shared_ptr load_path_base = nullptr; - bool load_path_set = false; - bool load_path_addr_of = false; - std::vector load_path; -}; - -class IR_FloatMath2 : public virtual IR { - public: - enum Kind { DIV, MUL, ADD, SUB, MIN, MAX } kind; - IR_FloatMath2(Kind _kind, std::shared_ptr _arg0, std::shared_ptr _arg1) - : kind(_kind), arg0(std::move(_arg0)), arg1(std::move(_arg1)) {} - std::shared_ptr arg0, arg1; - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -class IR_FloatMath1 : public virtual IR { - public: - enum Kind { FLOAT_TO_INT, INT_TO_FLOAT, ABS, NEG, SQRT } kind; - IR_FloatMath1(Kind _kind, std::shared_ptr _arg) : kind(_kind), arg(std::move(_arg)) {} - std::shared_ptr arg; - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -class IR_IntMath2 : public virtual IR { - public: - enum Kind { - ADD, - SUB, - MUL_SIGNED, - DIV_SIGNED, - MOD_SIGNED, - DIV_UNSIGNED, - MOD_UNSIGNED, - OR, - AND, - NOR, - XOR, - LEFT_SHIFT, - RIGHT_SHIFT_ARITH, - RIGHT_SHIFT_LOGIC, - MUL_UNSIGNED, - MIN_SIGNED, - MAX_SIGNED - } kind; - IR_IntMath2(Kind _kind, std::shared_ptr _arg0, std::shared_ptr _arg1) - : kind(_kind), arg0(std::move(_arg0)), arg1(std::move(_arg1)) {} - std::shared_ptr arg0, arg1; - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -class IR_IntMath1 : public virtual IR { - public: - enum Kind { NOT, ABS, NEG } kind; - IR_IntMath1(Kind _kind, std::shared_ptr _arg) : kind(_kind), arg(std::move(_arg)) {} - IR_IntMath1(Kind _kind, std::shared_ptr _arg, std::shared_ptr _abs_op) - : kind(_kind), arg(std::move(_arg)), abs_op(std::move(_abs_op)) { - ASSERT(abs_op); - } - std::shared_ptr arg; - std::shared_ptr abs_op = nullptr; - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -class IR_Call : public virtual IR { - public: - IR_Call() = default; - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; - std::vector> args; - TypeSpec call_type; - bool call_type_set = false; -}; - -// todo -class IR_Call_Atomic : public virtual IR_Call, public IR_Atomic { - public: - IR_Call_Atomic() = default; -}; - -class IR_IntegerConstant : public virtual IR { - public: - int64_t value; - explicit IR_IntegerConstant(int64_t _value) : value(_value) {} - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -struct BranchDelay { - enum Kind { - NOP, - SET_REG_FALSE, - SET_REG_TRUE, - SET_REG_REG, - SET_BINTEGER, - SET_PAIR, - DSLLV, - NEGATE, - UNKNOWN - } kind; - std::shared_ptr destination = nullptr, source = nullptr, source2 = nullptr; - explicit BranchDelay(Kind _kind) : kind(_kind) {} - goos::Object to_form(const LinkedObjectFile& file) const; - void get_children(std::vector>* output) const; - - std::vector read_regs; - std::vector write_regs; - std::vector clobber_regs; - - void type_prop(TypeState& output, const LinkedObjectFile& file, DecompilerTypeSystem& dts); -}; - -struct Condition { - enum Kind { - NOT_EQUAL, - EQUAL, - LESS_THAN_SIGNED, - GREATER_THAN_SIGNED, - LEQ_SIGNED, - GEQ_SIGNED, - GREATER_THAN_ZERO_SIGNED, - LEQ_ZERO_SIGNED, - LESS_THAN_ZERO, - GEQ_ZERO_SIGNED, - LESS_THAN_UNSIGNED, - GREATER_THAN_UNSIGNED, - LEQ_UNSIGNED, - GEQ_UNSIGNED, - ZERO, - NONZERO, - FALSE, - TRUTHY, - ALWAYS, - NEVER, - FLOAT_EQUAL, - FLOAT_NOT_EQUAL, - FLOAT_LESS_THAN, - FLOAT_GEQ, - FLOAT_LEQ, - FLOAT_GREATER_THAN, - } kind; - - Condition(Kind _kind, - std::shared_ptr _src0, - std::shared_ptr _src1, - std::shared_ptr _clobber) - : kind(_kind), src0(std::move(_src0)), src1(std::move(_src1)), clobber(std::move(_clobber)) { - int nargs = num_args(); - if (nargs == 2) { - ASSERT(src0 && src1); - } else if (nargs == 1) { - ASSERT(src0 && !src1); - } else if (nargs == 0) { - ASSERT(!src0 && !src1); - } - } - - int num_args() const; - goos::Object to_form(const LinkedObjectFile& file) const; - std::shared_ptr src0, src1, clobber; - void get_children(std::vector>* output) const; - void invert(); -}; - -class IR_Branch : public virtual IR { - public: - IR_Branch(Condition _condition, int _dest_label_idx, BranchDelay _branch_delay, bool _likely) - : condition(std::move(_condition)), - dest_label_idx(_dest_label_idx), - branch_delay(std::move(_branch_delay)), - likely(_likely) {} - - Condition condition; - int dest_label_idx; - BranchDelay branch_delay; - bool likely; - - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -// todo -class IR_Branch_Atomic : public virtual IR_Branch, public IR_Atomic { - public: - IR_Branch_Atomic(Condition _condition, - int _dest_label_idx, - BranchDelay _branch_delay, - bool _likely) - : IR_Branch(std::move(_condition), _dest_label_idx, std::move(_branch_delay), _likely) {} - // note - counts only for the condition. - void update_reginfo_self(int n_dst, int n_src, int n_clobber); -}; - -class IR_Compare : public virtual IR { - public: - explicit IR_Compare(Condition _condition, IR_Atomic* _root_op) - : condition(std::move(_condition)), root_op(_root_op) {} - - Condition condition; - - // the basic op that the comparison comes from. If the condition is "ALWAYS", this may be null. - // if this is the source of an IR_Set_Atomic, this may also be null. This should only be used - // from IR_Compare's expression_stack, when the IR_Compare is being used as a branch condition, - // and not as a literal #f/#t that's being assigned. - IR_Atomic* root_op = nullptr; - - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -class IR_Nop : public virtual IR { - public: - IR_Nop() = default; - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -class IR_Nop_Atomic : public IR_Nop, public IR_Atomic { - public: - IR_Nop_Atomic() = default; -}; - -class IR_Suspend_Atomic : public virtual IR, public IR_Atomic { - public: - IR_Suspend_Atomic() = default; - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -class IR_Breakpoint_Atomic : public virtual IR_Atomic { - public: - IR_Breakpoint_Atomic() = default; - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -class IR_AsmOp : public virtual IR { - public: - std::shared_ptr dst = nullptr; - std::shared_ptr src0 = nullptr; - std::shared_ptr src1 = nullptr; - std::shared_ptr src2 = nullptr; - std::string name; - IR_AsmOp(std::string _name) : name(std::move(_name)) {} - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -class IR_AsmOp_Atomic : public virtual IR_AsmOp, public IR_Atomic { - public: - IR_AsmOp_Atomic(std::string _name) : IR_AsmOp(std::move(_name)) {} - void set_reg_info(); -}; - -class IR_CMoveF : public virtual IR { - public: - std::shared_ptr src = nullptr; - bool on_zero = false; - explicit IR_CMoveF(std::shared_ptr _src, bool _on_zero) - : src(std::move(_src)), on_zero(_on_zero) {} - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -class IR_AsmReg : public virtual IR { - public: - enum Kind { VU_Q, VU_ACC } kind; - explicit IR_AsmReg(Kind _kind) : kind(_kind) {} - goos::Object to_form(const LinkedObjectFile& file) const override; - void get_children(std::vector>* output) const override; -}; - -} // namespace decompiler -#endif // JAK_IR_H diff --git a/decompiler/ObjectFile/LinkedObjectFile.cpp b/decompiler/ObjectFile/LinkedObjectFile.cpp index 486fc366a6..ccd043958b 100644 --- a/decompiler/ObjectFile/LinkedObjectFile.cpp +++ b/decompiler/ObjectFile/LinkedObjectFile.cpp @@ -6,7 +6,6 @@ #include #include #include -#include "decompiler/IR/IR.h" #include "third-party/fmt/core.h" #include "LinkedObjectFile.h" #include "decompiler/Disasm/InstructionDecode.h" @@ -583,23 +582,6 @@ std::string LinkedObjectFile::print_function_disassembly(Function& func, result += " ;;"; auto& word = words_by_seg[seg].at(func.start_word + i); append_word_to_string(result, word); - } else { - // print basic op stuff - if (func.has_basic_ops() && func.instr_starts_basic_op(i)) { - if (line.length() < 30) { - line.append(30 - line.length(), ' '); - } - line += ";; " + func.get_basic_op_at_instr(i)->print(*this); - for (int iidx = 0; iidx < instr.n_src; iidx++) { - if (instr.get_src(iidx).is_label()) { - auto lab = labels.at(instr.get_src(iidx).get_label()); - if (is_string(lab.target_segment, lab.offset)) { - line += " " + get_goal_string(lab.target_segment, lab.offset / 4 - 1); - } - } - } - } - result += line + "\n"; } if (in_delay_slot) { @@ -659,11 +641,6 @@ std::string LinkedObjectFile::print_function_disassembly(Function& func, */ } - if (func.ir) { - result += ";; ir\n"; - result += func.ir->print(*this); - } - result += "\n\n\n"; return result; } diff --git a/decompiler/ObjectFile/ObjectFileDB.cpp b/decompiler/ObjectFile/ObjectFileDB.cpp index a25cc16040..9ed02e414a 100644 --- a/decompiler/ObjectFile/ObjectFileDB.cpp +++ b/decompiler/ObjectFile/ObjectFileDB.cpp @@ -24,8 +24,6 @@ #include "common/util/Timer.h" #include "common/util/FileUtil.h" #include "decompiler/Function/BasicBlocks.h" -#include "decompiler/IR/BasicOpBuilder.h" -#include "decompiler/Function/TypeInspector.h" #include "common/log/log.h" #include "common/util/json_util.h" @@ -134,7 +132,7 @@ ObjectFileDB::ObjectFileDB(const std::vector& _dgos, try { get_objs_from_dgo(dgo, config); } catch (std::runtime_error& e) { - lg::warn("Error when reading DGOs: {}", e.what()); + lg::warn("Error when reading DGOs: {} on {}", e.what(), dgo); } } @@ -735,8 +733,6 @@ void ObjectFileDB::analyze_functions_ir1(const Config& config) { int total_trivial_cfg_functions = 0; int total_named_functions = 0; - int total_basic_ops = 0; - int total_failed_basic_ops = 0; int asm_funcs = 0; @@ -774,24 +770,8 @@ void ObjectFileDB::analyze_functions_ir1(const Config& config) { if (label_id != -1) { block.label_name = data.linked_data.get_label_name(label_id); } - - block.start_basic_op = func.basic_ops.size(); - add_basic_ops_to_block(&func, block, &data.linked_data); - block.end_basic_op = func.basic_ops.size(); } } - total_basic_ops += func.get_basic_op_count(); - total_failed_basic_ops += func.get_failed_basic_op_count(); - - // if we got an inspect method, inspect it. - if (func.is_inspect_method) { - auto result = inspect_inspect_method( - func, func.method_of_type, dts, data.linked_data, - config.hacks.types_with_bad_inspect_methods.find(func.method_of_type) != - config.hacks.types_with_bad_inspect_methods.end()); - all_type_defs += ";; " + data.to_unique_name() + "\n"; - all_type_defs += result.print_as_deftype() + "\n"; - } } else { asm_funcs++; } @@ -802,10 +782,6 @@ void ObjectFileDB::analyze_functions_ir1(const Config& config) { lg::info("Named {}/{} functions ({:.3f}%)", total_named_functions, total_functions, 100.f * float(total_named_functions) / float(total_functions)); lg::info("Excluding {} asm functions", asm_funcs); - lg::info("Found {} basic blocks in {:.3f} ms", total_basic_blocks, timer.getMs()); - int successful_basic_ops = total_basic_ops - total_failed_basic_ops; - lg::info(" {}/{} basic ops converted successfully ({:.3f}%)", successful_basic_ops, - total_basic_ops, 100.f * float(successful_basic_ops) / float(total_basic_ops)); } void ObjectFileDB::dump_raw_objects(const std::string& output_dir) { diff --git a/decompiler/ObjectFile/ObjectFileDB.h b/decompiler/ObjectFile/ObjectFileDB.h index a9851fb6e1..51a2e5f5ec 100644 --- a/decompiler/ObjectFile/ObjectFileDB.h +++ b/decompiler/ObjectFile/ObjectFileDB.h @@ -103,7 +103,6 @@ class ObjectFileDB { ObjectFileData& lookup_record(const ObjectFileRecord& rec); DecompilerTypeSystem dts; - std::string all_type_defs; bool lookup_function_type(const FunctionName& name, const std::string& obj_name, diff --git a/decompiler/ObjectFile/ObjectFileDB_IR2.cpp b/decompiler/ObjectFile/ObjectFileDB_IR2.cpp index 6605c74a7a..e45cc63132 100644 --- a/decompiler/ObjectFile/ObjectFileDB_IR2.cpp +++ b/decompiler/ObjectFile/ObjectFileDB_IR2.cpp @@ -8,7 +8,6 @@ #include "common/log/log.h" #include "common/util/Timer.h" #include "common/util/FileUtil.h" -#include "decompiler/Function/TypeInspector.h" #include "decompiler/analysis/type_analysis.h" #include "decompiler/analysis/reg_usage.h" #include "decompiler/analysis/insert_lets.h" diff --git a/decompiler/config.cpp b/decompiler/config.cpp index 183b88dd38..c5b6b724a6 100644 --- a/decompiler/config.cpp +++ b/decompiler/config.cpp @@ -54,7 +54,6 @@ Config read_config_file(const std::string& path_to_config_file, } config.disassemble_code = cfg.at("disassemble_code").get(); config.decompile_code = cfg.at("decompile_code").get(); - config.regenerate_all_types = cfg.at("regenerate_all_types").get(); config.write_hex_near_instructions = cfg.at("write_hex_near_instructions").get(); config.write_scripts = cfg.at("write_scripts").get(); config.disassemble_data = cfg.at("disassemble_data").get(); diff --git a/decompiler/config.h b/decompiler/config.h index 40c62f6ed1..9cf1eb26f5 100644 --- a/decompiler/config.h +++ b/decompiler/config.h @@ -101,7 +101,6 @@ struct Config { bool process_game_count = false; bool rip_levels = false; - bool regenerate_all_types = false; bool write_hex_near_instructions = false; bool hexdump_code = false; bool hexdump_data = false; diff --git a/decompiler/config/jak1_ntsc_black_label.jsonc b/decompiler/config/jak1_ntsc_black_label.jsonc index d35033104a..5682405412 100644 --- a/decompiler/config/jak1_ntsc_black_label.jsonc +++ b/decompiler/config/jak1_ntsc_black_label.jsonc @@ -42,9 +42,6 @@ // these options are used rarely and should usually be left at false - // output a file type_defs.gc which is used for the types part of all-types.gc - "regenerate_all_types": false, - // generate the symbol_map.json file. // this is a guess at where each symbol is first defined/used. "generate_symbol_definition_map": false, diff --git a/decompiler/main.cpp b/decompiler/main.cpp index 46240f0129..67d1c144be 100644 --- a/decompiler/main.cpp +++ b/decompiler/main.cpp @@ -155,13 +155,6 @@ int main(int argc, char** argv) { config.write_hex_near_instructions); } - // regenerate all-types if needed - if (config.regenerate_all_types) { - db.analyze_functions_ir1(config); - file_util::write_text_file(file_util::combine_path(out_folder, "type_defs.gc"), - db.all_type_defs); - } - // main decompile. if (config.decompile_code) { db.analyze_functions_ir2(out_folder, config, {}); diff --git a/test/offline/offline_test_main.cpp b/test/offline/offline_test_main.cpp index 2641731d2f..27bb5e5e61 100644 --- a/test/offline/offline_test_main.cpp +++ b/test/offline/offline_test_main.cpp @@ -199,7 +199,7 @@ Decompiler setup_decompiler(const std::vector& files, std::vector dgo_paths; if (args.iso_data_path.empty()) { for (auto& x : offline_config.dgos) { - dgo_paths.push_back((file_util::get_jak_project_dir() / "iso_data" / "jak1").string()); + dgo_paths.push_back((file_util::get_jak_project_dir() / "iso_data" / "jak1" / x).string()); } } else { for (auto& x : offline_config.dgos) { From e0be847b8a41af44e94aed37fdace3344e4fa8a8 Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Sun, 10 Apr 2022 12:25:35 -0400 Subject: [PATCH 015/172] fix (#1291) --- game/graphics/opengl_renderer/Loader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/game/graphics/opengl_renderer/Loader.cpp b/game/graphics/opengl_renderer/Loader.cpp index 0f20a805cf..71b99cdc8a 100644 --- a/game/graphics/opengl_renderer/Loader.cpp +++ b/game/graphics/opengl_renderer/Loader.cpp @@ -463,6 +463,7 @@ bool Loader::init_tie(Timer& timer, LevelData& data) { abort = true; } } + data.tie_next_tree = 0; } data.tie_wind_indices_done = true; From 8696eeb39ee91fb4670fce84e0c740a07786d77c Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Sun, 10 Apr 2022 18:37:57 -0400 Subject: [PATCH 016/172] fix decomp (#1293) --- .../jak1_ntsc_black_label/type_casts.jsonc | 4 +++ goal_src/engine/game/effect-control.gc | 28 ++++--------------- .../engine/game/effect-control_REF.gc | 28 ++++--------------- 3 files changed, 16 insertions(+), 44 deletions(-) diff --git a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc index 4eea47e2b7..2b01113675 100644 --- a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc @@ -7775,5 +7775,9 @@ [[33, 41], "a0", "dma-packet"], [[47, 55], "a0", "dma-packet"] ], + + "(method 12 effect-control)": [ + ["_stack_", 112, "res-tag"] + ], "placeholder-do-not-add-below": [] } diff --git a/goal_src/engine/game/effect-control.gc b/goal_src/engine/game/effect-control.gc index 535905d644..efaf7a3532 100644 --- a/goal_src/engine/game/effect-control.gc +++ b/goal_src/engine/game/effect-control.gc @@ -1064,14 +1064,7 @@ ) (defmethod dummy-12 effect-control ((obj effect-control) (arg0 symbol) (arg1 float) (arg2 int) (arg3 basic) (arg4 sound-name)) - (local-vars - (r0-0 uint128) - (v1-10 uint128) - (sv-112 int) - (sv-128 sound-name) - (sv-144 basic) - (sv-160 (function vector vector float)) - ) + (local-vars (sv-112 res-tag) (sv-128 sound-name) (sv-144 basic) (sv-160 (function vector vector float))) (set! sv-144 arg3) (let ((s0-0 arg4) (gp-0 (new 'stack 'sound-spec)) @@ -1086,28 +1079,19 @@ (set! (-> gp-0 volume) 1024) (logior! (-> gp-0 mask) 4) (set! (-> gp-0 bend) (the int (* 327.66998 (rand-vu-float-range -100.0 100.0)))) - (set! sv-112 0) + (set! sv-112 (new 'static 'res-tag)) (let* ((t9-3 (method-of-type res-lump get-property-data)) (a1-6 'effect-param) (a2-1 'exact) (a3-1 arg1) (t0-1 #f) - (t1-1 (the-as (pointer int) (& sv-112))) + (t1-1 (the-as (pointer res-tag) (& sv-112))) (t2-0 *res-static-buf*) - (a1-7 - (t9-3 (the-as res-lump sv-144) a1-6 a2-1 a3-1 (the-as pointer t0-1) (the-as (pointer res-tag) t1-1) t2-0) - ) + (a1-7 (t9-3 (the-as res-lump sv-144) a1-6 a2-1 a3-1 (the-as pointer t0-1) t1-1 t2-0)) ) - (when a1-7 - (let ((t9-4 effect-param->sound-spec) - (a0-5 gp-0) - ) - (let ((v1-9 (the-as uint128 sv-112))) - (.pcpyud v1-10 v1-9 r0-0) - ) - (t9-4 a0-5 (the-as (pointer float) a1-7) (shr (* (the-as int v1-10) 2) 49)) + (if a1-7 + (effect-param->sound-spec gp-0 (the-as (pointer float) a1-7) (the-as int (-> sv-112 elt-count))) ) - ) ) (if (and (nonzero? (-> gp-0 fo-max)) (let ((f30-1 (* 4096.0 (the float (-> gp-0 fo-max))))) (set! sv-160 vector-vector-distance) diff --git a/test/decompiler/reference/engine/game/effect-control_REF.gc b/test/decompiler/reference/engine/game/effect-control_REF.gc index faecadbfd4..63bba2302e 100644 --- a/test/decompiler/reference/engine/game/effect-control_REF.gc +++ b/test/decompiler/reference/engine/game/effect-control_REF.gc @@ -1079,14 +1079,7 @@ ;; definition for method 12 of type effect-control ;; Used lq/sq (defmethod dummy-12 effect-control ((obj effect-control) (arg0 symbol) (arg1 float) (arg2 int) (arg3 basic) (arg4 sound-name)) - (local-vars - (r0-0 uint128) - (v1-10 uint128) - (sv-112 int) - (sv-128 sound-name) - (sv-144 basic) - (sv-160 (function vector vector float)) - ) + (local-vars (sv-112 res-tag) (sv-128 sound-name) (sv-144 basic) (sv-160 (function vector vector float))) (set! sv-144 arg3) (let ((s0-0 arg4) (gp-0 (new 'stack 'sound-spec)) @@ -1101,28 +1094,19 @@ (set! (-> gp-0 volume) 1024) (logior! (-> gp-0 mask) 4) (set! (-> gp-0 bend) (the int (* 327.66998 (rand-vu-float-range -100.0 100.0)))) - (set! sv-112 0) + (set! sv-112 (new 'static 'res-tag)) (let* ((t9-3 (method-of-type res-lump get-property-data)) (a1-6 'effect-param) (a2-1 'exact) (a3-1 arg1) (t0-1 #f) - (t1-1 (the-as (pointer int) (& sv-112))) + (t1-1 (the-as (pointer res-tag) (& sv-112))) (t2-0 *res-static-buf*) - (a1-7 - (t9-3 (the-as res-lump sv-144) a1-6 a2-1 a3-1 (the-as pointer t0-1) (the-as (pointer res-tag) t1-1) t2-0) - ) + (a1-7 (t9-3 (the-as res-lump sv-144) a1-6 a2-1 a3-1 (the-as pointer t0-1) t1-1 t2-0)) ) - (when a1-7 - (let ((t9-4 effect-param->sound-spec) - (a0-5 gp-0) - ) - (let ((v1-9 (the-as uint128 sv-112))) - (.pcpyud v1-10 v1-9 r0-0) - ) - (t9-4 a0-5 (the-as (pointer float) a1-7) (shr (* (the-as int v1-10) 2) 49)) + (if a1-7 + (effect-param->sound-spec gp-0 (the-as (pointer float) a1-7) (the-as int (-> sv-112 elt-count))) ) - ) ) (if (and (nonzero? (-> gp-0 fo-max)) (let ((f30-1 (* 4096.0 (the float (-> gp-0 fo-max))))) (set! sv-160 vector-vector-distance) From b408c786981ed37ca57f5d8d747efbf532d0277b Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Sun, 10 Apr 2022 21:57:00 -0400 Subject: [PATCH 017/172] skip creating trees that are never setup (#1294) --- game/graphics/opengl_renderer/background/Tfrag3.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/game/graphics/opengl_renderer/background/Tfrag3.cpp b/game/graphics/opengl_renderer/background/Tfrag3.cpp index 01906e2156..25fc0cf4db 100644 --- a/game/graphics/opengl_renderer/background/Tfrag3.cpp +++ b/game/graphics/opengl_renderer/background/Tfrag3.cpp @@ -56,10 +56,9 @@ void Tfrag3::update_load(const std::vector& tree_kind for (size_t tree_idx = 0; tree_idx < lev_data->tfrag_trees[geom].size(); tree_idx++) { const auto& tree = lev_data->tfrag_trees[geom][tree_idx]; - auto& tree_cache = m_cached_trees[geom].emplace_back(); - - tree_cache.kind = tree.kind; if (std::find(tree_kinds.begin(), tree_kinds.end(), tree.kind) != tree_kinds.end()) { + auto& tree_cache = m_cached_trees[geom].emplace_back(); + tree_cache.kind = tree.kind; max_draws = std::max(tree.draws.size(), max_draws); size_t num_grps = 0; for (auto& draw : tree.draws) { From a7eee4fdc91faf91d83dad9277b421e9b142d38d Mon Sep 17 00:00:00 2001 From: ManDude <7569514+ManDude@users.noreply.github.com> Date: Mon, 11 Apr 2022 23:38:54 +0100 Subject: [PATCH 018/172] [game] pc port progress menu (#1281) * fix typo * more typo * shorten discord rpc text * allow expanding enums after the fact (untested) * make `game_text` work similar to subtitles * update progress decomp * update some types + `do-not-decompile` in bitfield * fixes and fall back to original progress code * update `progress` decomp with new enums * update config files * fix enums and debug menu * always allocate (but not use) a lot of particles * small rework to display mode options * revert resolution/aspect-ratio symbol mess * begin the override stuff * make `progress-draw` more readable * more fixes * codacy good boy points * first step overriding code * finish progress overrides, game options menu fully functional! * minor fixes * Update game.gp * Update sparticle-launcher.gc * clang * change camera controls text * oops * some cleanup * derp * nice job * implement menu scrolling lol * make scrollable menus less cramped, fix arrows * make some carousell things i guess * add msaa carousell to test * oops * Update progress-pc.gc * make `pc-get-screen-size` (untested) * resolution menu * input fixes * return when selecting resolution * scroll fixes * Update progress-pc.gc * add "fit to screen" button * bug * complete resolutions menu * aspect ratio menu * subtitles language * subtitle speaker * final adjustments * ref test * fix tests * fix ref! * reduce redundancy a bit * fix mem leaks? * save settings on progress exit * fix init reorder * remove unused code * rename goal project-like files to the project extension * sha display toggle * aspect ratio settings fixes * dont store text db's in compiler * properly save+load native aspect stuff --- common/cross_os_debug/xdbg.cpp | 4 +- common/goos/PrettyPrinter2.cpp | 11 +- common/type_system/Type.cpp | 15 +- common/type_system/Type.h | 4 +- common/type_system/TypeSystem.cpp | 5 +- common/type_system/TypeSystem.h | 3 +- common/type_system/defenum.cpp | 4 +- common/type_system/deftype.cpp | 6 +- decompiler/IR2/AtomicOpForm.cpp | 4 +- decompiler/config.cpp | 12 - decompiler/config.h | 3 - decompiler/config/all-types.gc | 294 +- decompiler/config/jak1_ntsc_black_label.jsonc | 1 - .../config/jak1_ntsc_black_label/hacks.jsonc | 3 +- .../config/jak1_ntsc_black_label/inputs.jsonc | 9 +- .../jak1_ntsc_black_label/label_types.jsonc | 24 +- .../jak1_ntsc_black_label/new_strings.jsonc | 57 - .../jak1_ntsc_black_label/type_casts.jsonc | 1 + decompiler/data/game_text.cpp | 28 +- decompiler/util/data_decompile.cpp | 3 +- .../{game_subtitle.txt => game_subtitle.gp} | 4 +- game/assets/game_text.gp | 11 + .../subtitle}/game_subtitle_en.txt | 0 .../subtitle}/game_subtitle_es.txt | 0 game/assets/jak1/text/game_text_en.txt | 143 + game/graphics/display.cpp | 10 +- game/graphics/display.h | 20 +- game/graphics/gfx.cpp | 16 +- game/graphics/gfx.h | 7 +- game/graphics/opengl_renderer/Profiler.cpp | 4 +- game/graphics/pipelines/opengl.cpp | 42 +- game/kernel/kmachine.cpp | 61 +- game/system/Deci2Server.cpp | 4 +- goal_src/dgos/engine.gd | 1 + goal_src/dgos/game.gd | 1 + goal_src/engine/collide/collide-cache-h.gc | 6 +- goal_src/engine/collide/collide-cache.gc | 17 +- goal_src/engine/collide/collide-shape-h.gc | 17 +- goal_src/engine/collide/collide-shape.gc | 2 +- goal_src/engine/debug/default-menu.gc | 6 +- goal_src/engine/draw/drawable.gc | 2 +- goal_src/engine/game/collectables.gc | 6 +- goal_src/engine/game/game-save.gc | 8 +- goal_src/engine/game/main.gc | 15 +- goal_src/engine/game/projectiles.gc | 2 +- goal_src/engine/gfx/shadow/shadow-h.gc | 13 +- goal_src/engine/gfx/shadow/shadow.gc | 21 +- goal_src/engine/gfx/sprite/sprite.gc | 12 +- goal_src/engine/nav/navigate-h.gc | 38 +- goal_src/engine/nav/navigate.gc | 62 +- goal_src/engine/ps2/pad.gc | 2 +- .../engine/sparticle/sparticle-launcher.gc | 10 +- goal_src/engine/sparticle/sparticle.gc | 6 +- goal_src/engine/target/target-death.gc | 2 +- goal_src/engine/target/target-part.gc | 2 +- goal_src/engine/ui/progress-h.gc | 249 +- goal_src/engine/ui/progress/progress-draw.gc | 508 +-- goal_src/engine/ui/progress/progress-part.gc | 8 +- .../engine/ui/progress/progress-static.gc | 202 +- goal_src/engine/ui/progress/progress.gc | 772 +++-- goal_src/engine/ui/text-h.gc | 64 +- goal_src/engine/ui/text.gc | 3 + goal_src/game.gp | 15 +- goal_src/goal-lib.gc | 2 +- goal_src/goos-lib.gs | 2 +- goal_src/kernel-defs.gc | 4 +- goal_src/levels/beach/lurkercrab.gc | 38 +- goal_src/levels/beach/lurkerpuppy.gc | 24 +- goal_src/levels/citadel/citb-bunny.gc | 2 +- goal_src/levels/common/babak.gc | 10 +- goal_src/levels/common/battlecontroller.gc | 6 +- goal_src/levels/common/joint-exploder.gc | 2 +- goal_src/levels/common/nav-enemy-h.gc | 141 +- goal_src/levels/common/nav-enemy.gc | 190 +- goal_src/levels/common/sharkey.gc | 10 +- goal_src/levels/finalboss/green-eco-lurker.gc | 88 +- goal_src/levels/finalboss/robotboss.gc | 4 +- goal_src/levels/jungle/hopper.gc | 41 +- goal_src/levels/jungle/junglefish.gc | 2 +- goal_src/levels/jungleb/aphid.gc | 20 +- goal_src/levels/maincave/baby-spider.gc | 12 +- goal_src/levels/maincave/mother-spider-egg.gc | 15 +- .../levels/maincave/mother-spider-proj.gc | 2 +- goal_src/levels/maincave/mother-spider.gc | 6 +- goal_src/levels/misty/babak-with-cannon.gc | 16 +- goal_src/levels/misty/bonelurker.gc | 45 +- goal_src/levels/misty/mistycannon.gc | 2 +- goal_src/levels/misty/muse.gc | 8 +- goal_src/levels/misty/quicksandlurker.gc | 4 +- goal_src/levels/ogre/ogreboss.gc | 4 +- goal_src/levels/racer_common/racer-states.gc | 2 +- goal_src/levels/robocave/cave-trap.gc | 4 +- .../levels/rolling/rolling-lightning-mole.gc | 8 +- goal_src/levels/snow/ice-cube.gc | 20 +- goal_src/levels/snow/snow-bunny.gc | 36 +- goal_src/levels/snow/snow-ram-boss.gc | 34 +- goal_src/levels/snow/yeti.gc | 16 +- goal_src/levels/sunken/bully.gc | 2 +- goal_src/levels/sunken/double-lurker.gc | 18 +- goal_src/levels/sunken/orbit-plat.gc | 12 +- goal_src/levels/sunken/puffer.gc | 7 +- goal_src/levels/swamp/billy.gc | 8 +- goal_src/levels/swamp/kermit.gc | 10 +- goal_src/levels/swamp/swamp-rat-nest.gc | 2 +- goal_src/levels/swamp/swamp-rat.gc | 8 +- goal_src/levels/village1/village-obs.gc | 4 +- goal_src/levels/village1/yakow.gc | 12 +- goal_src/pc/engine/ui/progress-h.gc | 271 -- .../pc/engine/ui/progress/progress-draw.gc | 2157 ------------- .../pc/engine/ui/progress/progress-static.gc | 1498 --------- goal_src/pc/engine/ui/progress/progress.gc | 2762 ---------------- goal_src/pc/engine/ui/text-h.gc | 562 ---- goal_src/pc/pckernel-h.gc | 56 +- goal_src/pc/pckernel.gc | 220 +- goal_src/pc/progress-pc.gc | 1549 +++++++++ goal_src/pc/subtitle.gc | 12 +- goalc/compiler/Compiler.cpp | 1 - goalc/compiler/Compiler.h | 3 +- .../compiler/compilation/CompilerControl.cpp | 17 +- goalc/data_compiler/game_subtitle.cpp | 18 +- goalc/data_compiler/game_subtitle.h | 21 +- goalc/data_compiler/game_text.cpp | 152 +- goalc/data_compiler/game_text.h | 60 +- goalc/make/MakeSystem.cpp | 5 +- goalc/make/Tools.cpp | 34 +- goalc/make/Tools.h | 6 +- .../engine/collide/collide-cache-h_REF.gc | 6 +- .../engine/collide/collide-shape-h_REF.gc | 8 +- .../reference/engine/draw/drawable_REF.gc | 2 +- .../reference/engine/game/collectables_REF.gc | 4 +- .../reference/engine/game/game-save_REF.gc | 8 +- .../reference/engine/game/projectiles_REF.gc | 2 +- .../reference/engine/gfx/shadow/shadow_REF.gc | 21 +- .../reference/engine/nav/navigate-h_REF.gc | 2 +- .../reference/engine/nav/navigate_REF.gc | 62 +- .../engine/target/target-death_REF.gc | 2 +- .../engine/target/target-part_REF.gc | 2 +- .../reference/engine/ui/progress-h_REF.gc | 40 +- .../engine/ui/progress/progress-draw_REF.gc | 420 +-- .../engine/ui/progress/progress-static_REF.gc | 2781 +++++++++-------- .../engine/ui/progress/progress_REF.gc | 278 +- .../reference/levels/beach/lurkercrab_REF.gc | 38 +- .../reference/levels/beach/lurkerpuppy_REF.gc | 24 +- .../levels/citadel/citb-bunny_REF.gc | 2 +- .../reference/levels/common/babak_REF.gc | 10 +- .../levels/common/battlecontroller_REF.gc | 6 +- .../levels/common/joint-exploder_REF.gc | 2 +- .../levels/common/nav-enemy-h_REF.gc | 104 +- .../reference/levels/common/nav-enemy_REF.gc | 190 +- .../reference/levels/common/sharkey_REF.gc | 10 +- .../levels/finalboss/green-eco-lurker_REF.gc | 35 +- .../levels/finalboss/robotboss_REF.gc | 4 +- .../reference/levels/jungle/hopper_REF.gc | 39 +- .../reference/levels/jungle/junglefish_REF.gc | 2 +- .../reference/levels/jungleb/aphid_REF.gc | 20 +- .../levels/maincave/baby-spider_REF.gc | 12 +- .../levels/maincave/mother-spider-egg_REF.gc | 10 +- .../levels/maincave/mother-spider-proj_REF.gc | 2 +- .../levels/maincave/mother-spider_REF.gc | 6 +- .../levels/misty/babak-with-cannon_REF.gc | 16 +- .../reference/levels/misty/bonelurker_REF.gc | 45 +- .../reference/levels/misty/mistycannon_REF.gc | 2 +- .../reference/levels/misty/muse_REF.gc | 8 +- .../levels/misty/quicksandlurker_REF.gc | 4 +- .../reference/levels/ogre/ogreboss_REF.gc | 2 +- .../levels/racer_common/racer-states_REF.gc | 2 +- .../levels/robocave/cave-trap_REF.gc | 4 +- .../rolling/rolling-lightning-mole_REF.gc | 8 +- .../reference/levels/snow/ice-cube_REF.gc | 22 +- .../reference/levels/snow/snow-bunny_REF.gc | 36 +- .../levels/snow/snow-ram-boss_REF.gc | 34 +- .../reference/levels/snow/yeti_REF.gc | 16 +- .../reference/levels/sunken/bully_REF.gc | 2 +- .../levels/sunken/double-lurker_REF.gc | 20 +- .../reference/levels/sunken/orbit-plat_REF.gc | 12 +- .../reference/levels/sunken/puffer_REF.gc | 2 +- .../reference/levels/swamp/billy_REF.gc | 8 +- .../reference/levels/swamp/kermit_REF.gc | 10 +- .../levels/swamp/swamp-rat-nest_REF.gc | 2 +- .../reference/levels/swamp/swamp-rat_REF.gc | 8 +- .../levels/village1/village-obs_REF.gc | 4 +- .../reference/levels/village1/yakow_REF.gc | 12 +- test/goalc/test_with_game.cpp | 2 +- test/test_data/test_game_text.txt | 2 +- test/test_reader.cpp | 8 +- 185 files changed, 6172 insertions(+), 11465 deletions(-) delete mode 100644 decompiler/config/jak1_ntsc_black_label/new_strings.jsonc rename game/assets/{game_subtitle.txt => game_subtitle.gp} (66%) create mode 100644 game/assets/game_text.gp rename game/assets/{subtitle/jak1 => jak1/subtitle}/game_subtitle_en.txt (100%) rename game/assets/{subtitle/jak1 => jak1/subtitle}/game_subtitle_es.txt (100%) create mode 100644 game/assets/jak1/text/game_text_en.txt delete mode 100644 goal_src/pc/engine/ui/progress-h.gc delete mode 100644 goal_src/pc/engine/ui/progress/progress-draw.gc delete mode 100644 goal_src/pc/engine/ui/progress/progress-static.gc delete mode 100644 goal_src/pc/engine/ui/progress/progress.gc delete mode 100644 goal_src/pc/engine/ui/text-h.gc create mode 100644 goal_src/pc/progress-pc.gc diff --git a/common/cross_os_debug/xdbg.cpp b/common/cross_os_debug/xdbg.cpp index c3179cad15..f8989b13a1 100644 --- a/common/cross_os_debug/xdbg.cpp +++ b/common/cross_os_debug/xdbg.cpp @@ -38,9 +38,7 @@ ThreadID::ThreadID(pid_t _id) : id(_id) {} /*! * In Linux, the string representation of a ThreadID is just the number printed in base 10 */ -ThreadID::ThreadID(const std::string& str) { - id = std::stoi(str); -} +ThreadID::ThreadID(const std::string& str) : id(std::stoi(str)) {} std::string ThreadID::to_string() const { return std::to_string(id); diff --git a/common/goos/PrettyPrinter2.cpp b/common/goos/PrettyPrinter2.cpp index e0f64641f7..a3e06fc1aa 100644 --- a/common/goos/PrettyPrinter2.cpp +++ b/common/goos/PrettyPrinter2.cpp @@ -17,15 +17,10 @@ namespace v2 { struct Node { Node() = default; - Node(const std::string& str) { - kind = Kind::ATOM; - atom_str = str; - } + Node(const std::string& str) : kind(Kind::ATOM), atom_str(str) {} - Node(std::vector&& list, bool is_list) { - kind = is_list ? Kind::LIST : Kind::IMPROPER_LIST; - child_nodes = std::move(list); - } + Node(std::vector&& list, bool is_list) + : kind(is_list ? Kind::LIST : Kind::IMPROPER_LIST), child_nodes(std::move(list)) {} enum class Kind : u8 { ATOM, LIST, IMPROPER_LIST, INVALID } kind = Kind::INVALID; std::vector child_nodes; diff --git a/common/type_system/Type.cpp b/common/type_system/Type.cpp index d7e0366040..29282a5daa 100644 --- a/common/type_system/Type.cpp +++ b/common/type_system/Type.cpp @@ -936,12 +936,16 @@ std::string BasicType::diff_impl(const Type& other_) const { // Bitfield ///////////////// -BitField::BitField(TypeSpec type, std::string name, int offset, int size) - : m_type(std::move(type)), m_name(std::move(name)), m_offset(offset), m_size(size) {} +BitField::BitField(TypeSpec type, std::string name, int offset, int size, bool skip_in_decomp) + : m_type(std::move(type)), + m_name(std::move(name)), + m_offset(offset), + m_size(size), + m_skip_in_static_decomp(skip_in_decomp) {} bool BitField::operator==(const BitField& other) const { return m_type == other.m_type && m_name == other.m_name && m_offset == other.m_offset && - other.m_size == m_size; + m_size == other.m_size; } std::string BitField::diff(const BitField& other) const { @@ -963,6 +967,11 @@ std::string BitField::diff(const BitField& other) const { result += fmt::format("size: {} vs. {}\n", m_size, other.m_size); } + if (m_skip_in_static_decomp != other.m_skip_in_static_decomp) { + result += fmt::format("skip_in_static_decomp: {} vs. {}\n", m_skip_in_static_decomp, + other.m_skip_in_static_decomp); + } + return result; } diff --git a/common/type_system/Type.h b/common/type_system/Type.h index cb101a5bb5..02a544bbe1 100644 --- a/common/type_system/Type.h +++ b/common/type_system/Type.h @@ -325,11 +325,12 @@ class BasicType : public StructureType { class BitField { public: BitField() = default; - BitField(TypeSpec type, std::string name, int offset, int size); + BitField(TypeSpec type, std::string name, int offset, int size, bool skip_in_decomp); const std::string name() const { return m_name; } int offset() const { return m_offset; } int size() const { return m_size; } const TypeSpec& type() const { return m_type; } + bool skip_in_decomp() const { return m_skip_in_static_decomp; } bool operator==(const BitField& other) const; bool operator!=(const BitField& other) const { return !((*this) == other); } std::string diff(const BitField& other) const; @@ -340,6 +341,7 @@ class BitField { std::string m_name; int m_offset = -1; // in bits int m_size = -1; // in bits. + bool m_skip_in_static_decomp = false; }; class BitFieldType : public ValueType { diff --git a/common/type_system/TypeSystem.cpp b/common/type_system/TypeSystem.cpp index 17dfc90c7e..4493324bd7 100644 --- a/common/type_system/TypeSystem.cpp +++ b/common/type_system/TypeSystem.cpp @@ -1588,7 +1588,8 @@ void TypeSystem::add_field_to_bitfield(BitFieldType* type, const std::string& field_name, const TypeSpec& field_type, int offset, - int field_size) { + int field_size, + bool skip_in_decomp) { // in bits auto load_size = lookup_type(field_type)->get_load_size() * 8; if (field_size == -1) { @@ -1616,7 +1617,7 @@ void TypeSystem::add_field_to_bitfield(BitFieldType* type, type->get_name(), field_name, offset, offset + field_size); } - BitField field(field_type, field_name, offset, field_size); + BitField field(field_type, field_name, offset, field_size, skip_in_decomp); type->m_fields.push_back(field); } diff --git a/common/type_system/TypeSystem.h b/common/type_system/TypeSystem.h index b47f90b726..8943d6548f 100644 --- a/common/type_system/TypeSystem.h +++ b/common/type_system/TypeSystem.h @@ -222,7 +222,8 @@ class TypeSystem { const std::string& field_name, const TypeSpec& field_type, int offset, - int field_size); + int field_size, + bool skip_in_decomp); bool should_use_virtual_methods(const Type* type, int method_id) const; bool should_use_virtual_methods(const TypeSpec& type, int method_id) const; diff --git a/common/type_system/defenum.cpp b/common/type_system/defenum.cpp index 268ada104d..c0a83c3e14 100644 --- a/common/type_system/defenum.cpp +++ b/common/type_system/defenum.cpp @@ -60,7 +60,7 @@ EnumType* parse_defenum(const goos::Object& defenum, TypeSystem* ts) { while (current.is_symbol() && symbol_string(current).at(0) == ':') { auto option_name = symbol_string(current); iter = cdr(iter); - auto option_value = car(iter); + auto& option_value = car(iter); iter = cdr(iter); if (option_name == ":type") { @@ -82,7 +82,7 @@ EnumType* parse_defenum(const goos::Object& defenum, TypeSystem* ts) { } for (auto& e : other_info->entries()) { if (entries.find(e.first) != entries.end()) { - throw std::runtime_error(fmt::format("Entry {} appears multiple times.", e.first)); + throw std::runtime_error(fmt::format("Entry {} appears multiple times", e.first)); } entries[e.first] = e.second; } diff --git a/common/type_system/deftype.cpp b/common/type_system/deftype.cpp index b3dc903103..075a2077ec 100644 --- a/common/type_system/deftype.cpp +++ b/common/type_system/deftype.cpp @@ -163,6 +163,7 @@ void add_bitfield(BitFieldType* bitfield_type, TypeSystem* ts, const goos::Objec int offset_override = -1; int size_override = -1; + bool skip_in_decomp = false; if (!rest->is_empty_list()) { while (!rest->is_empty_list()) { @@ -175,6 +176,8 @@ void add_bitfield(BitFieldType* bitfield_type, TypeSystem* ts, const goos::Objec } else if (opt_name == ":size") { size_override = get_int(car(rest)); rest = cdr(rest); + } else if (opt_name == ":do-not-decompile") { + skip_in_decomp = true; } else { throw std::runtime_error("Invalid option in field specification: " + opt_name); } @@ -186,7 +189,8 @@ void add_bitfield(BitFieldType* bitfield_type, TypeSystem* ts, const goos::Objec } // it's fine if the size is -1, that means it'll just use the type's size. - ts->add_field_to_bitfield(bitfield_type, name, type, offset_override, size_override); + ts->add_field_to_bitfield(bitfield_type, name, type, offset_override, size_override, + skip_in_decomp); } void declare_method(Type* type, TypeSystem* type_system, const goos::Object& def) { diff --git a/decompiler/IR2/AtomicOpForm.cpp b/decompiler/IR2/AtomicOpForm.cpp index 9b8ec33f85..5179253a34 100644 --- a/decompiler/IR2/AtomicOpForm.cpp +++ b/decompiler/IR2/AtomicOpForm.cpp @@ -524,8 +524,8 @@ FormElement* make_label_load(int label_idx, if (as_bitfield && load_kind != LoadVarOp::Kind::FLOAT && load_size == 8) { // get the data ASSERT((label.offset % 8) == 0); - auto word0 = env.file->words_by_seg.at(label.target_segment).at(label.offset / 4); - auto word1 = env.file->words_by_seg.at(label.target_segment).at(1 + (label.offset / 4)); + auto& word0 = env.file->words_by_seg.at(label.target_segment).at(label.offset / 4); + auto& word1 = env.file->words_by_seg.at(label.target_segment).at(1 + (label.offset / 4)); ASSERT(word0.kind() == LinkedWord::PLAIN_DATA); ASSERT(word1.kind() == LinkedWord::PLAIN_DATA); u64 value; diff --git a/decompiler/config.cpp b/decompiler/config.cpp index c5b6b724a6..9654568f21 100644 --- a/decompiler/config.cpp +++ b/decompiler/config.cpp @@ -224,18 +224,6 @@ Config read_config_file(const std::string& path_to_config_file, config.levels_to_extract = inputs_json.at("levels_to_extract").get>(); config.levels_extract = cfg.at("levels_extract").get(); - // get new strings - if (!cfg.contains("new_strings_file")) { - return config; - } - - auto new_strings_json = read_json_file_from_config(cfg, "new_strings_file"); - config.new_strings_same_across_langs = new_strings_json.at("same_across_languages") - .get>(); - config.new_strings_different_across_langs = - new_strings_json.at("different_across_languages") - .get>>(); - return config; } diff --git a/decompiler/config.h b/decompiler/config.h index 9cf1eb26f5..52a61c6e23 100644 --- a/decompiler/config.h +++ b/decompiler/config.h @@ -130,9 +130,6 @@ struct Config { std::unordered_map> stack_structure_hints_by_function; - std::unordered_map new_strings_same_across_langs; - std::unordered_map> new_strings_different_across_langs; - std::unordered_map bad_format_strings; std::vector levels_to_extract; diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index 0ccf426857..c41bdff0a4 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -703,24 +703,24 @@ :bitfield #t :type uint32 (display-marks 0) - (bit1 1) ;; TODO - nav-control::9 - (bit2 2) ;; TODO - nav-control::9 - (bit3 3) ;; TODO - nav-enemy::45 | nav-control::9 - (bit4 4) ;; TODO - nav-control::9 - (bit5 5) ;; TODO - nav-enemy::45 | ;; TODO - nav-control::9 - (bit6 6) ;; TODO - nav-enemy::45 | ;; TODO - nav-control::9 - (bit7 7) ;; TODO - nav-enemy::45 | ;; TODO - nav-control::9 - (bit8 8) - (bit9 9) ;; TODO - nav-control::14 | 11 - (bit10 10) ;; TODO - nav-enemy::nav-enemy-patrol-post - (bit11 11) ;; TODO - nav-control::28 - (bit12 12) ;; TODO - rolling-lightning-mole::(enter nav-enemy-chase fleeing-nav-enemy) - (bit13 13) - (bit17 17) ;; TODO - nav-control::11 - (bit18 18) ;; TODO - nav-control::11 - (bit19 19) ;; TODO - nav-control::11 | 17 - (bit20 20) ;; TODO - nav-mesh::28 - (bit21 21) ;; TODO - nav-control::19 + (navcf1 1) ;; TODO - nav-control::9 + (navcf2 2) ;; TODO - nav-control::9 + (navcf3 3) ;; TODO - nav-enemy::45 | nav-control::9 + (navcf4 4) ;; TODO - nav-control::9 + (navcf5 5) ;; TODO - nav-enemy::45 | ;; TODO - nav-control::9 + (navcf6 6) ;; TODO - nav-enemy::45 | ;; TODO - nav-control::9 + (navcf7 7) ;; TODO - nav-enemy::45 | ;; TODO - nav-control::9 + (navcf8 8) + (navcf9 9) ;; TODO - nav-control::14 | 11 + (navcf10 10) ;; TODO - nav-enemy::nav-enemy-patrol-post + (navcf11 11) ;; TODO - nav-control::28 + (navcf12 12) ;; TODO - rolling-lightning-mole::(enter nav-enemy-chase fleeing-nav-enemy) + (navcf13 13) + (navcf17 17) ;; TODO - nav-control::11 + (navcf18 18) ;; TODO - nav-control::11 + (navcf19 19) ;; TODO - nav-control::11 | 17 + (navcf20 20) ;; TODO - nav-mesh::28 + (navcf21 21) ;; TODO - nav-control::19 ) (defenum task-status @@ -1300,6 +1300,68 @@ (inc #xf10) (europe #xf11) + + ;; extra IDs for pc port + (camera-options #x1000) + (normal #x1001) + (inverted #x1002) + (camera-controls-horz #x1003) + (camera-controls-vert #x1004) + (misc-options #x100f) + (accessibility-options #x1010) + (money-starburst #x1011) + (ps2-options #x1020) + (ps2-load-speed #x1021) + (ps2-parts #x1022) + (discord-rpc #x1030) + (display-mode #x1031) + (windowed #x1032) + (borderless #x1033) + (fullscreen #x1034) + (game-resolution #x1035) + (resolution-fmt #x1036) + (ps2-aspect-ratio #x1037) + (ps2-aspect-ratio-msg #x1038) + (aspect-ratio-ps2 #x1039) + (fit-to-screen #x103a) + (msaa #x1050) + (x-times-fmt #x1051) + (2-times #x1052) + (4-times #x1053) + (8-times #x1054) + (16-times #x1055) + (frame-rate #x1060) + (lod-bg #x1070) + (lod-fg #x1071) + (lod-highest #x1072) + (lod-high #x1073) + (lod-mid #x1074) + (lod-low #x1075) + (lod-lowest #x1076) + (lod-ps2 #x1077) + (subtitles #x1078) + (hinttitles #x1079) + (subtitles-language #x107a) + (subtitles-speaker #x107b) + (speaker-always #x107c) + (speaker-never #x107d) + (speaker-auto #x107e) + (hint-log #x107f) + (cheats #x1080) + (cheat-eco-blue #x1090) + (cheat-eco-red #x1091) + (cheat-eco-green #x1092) + (cheat-eco-yellow #x1093) + (cheat-sidekick-alt #x1094) + (cheat-invinc #x1095) + (music-player #x10c0) + (scene-player #x10c1) + (play-credits #x10c2) + (scrapbook #x10c3) + (scene-0 #x1100) + (scene-255 #x11ff) + (hint-0 #x1200) + (hint-511 #x13ff) ;; GAME-TEXT-ID ENUM ENDS ) @@ -10111,7 +10173,7 @@ ;; - Types (deftype pat-surface (uint32) - ((skip uint8 :offset 0 :size 3) + ((skip uint8 :offset 0 :size 3 :do-not-decompile) (mode pat-mode :offset 3 :size 3) (material pat-material :offset 6 :size 6) (camera uint8 :offset 12 :size 2) @@ -11478,13 +11540,26 @@ ) ) +(defenum nav-flags + :bitfield #t + :type uint8 + (navf0 0) + (navf1 1) + (navf2 2) + (navf3 3) + (navf4 4) + (navf5 5) + (navf6 6) + (navf7 7) + ) + (declare-type collide-edge-hold-list structure) (declare-type collide-work structure) (declare-type touching-shapes-entry structure) (deftype collide-shape (trsqv) - ((process process-drawable :offset-assert 140) + ((process process-drawable :offset-assert 140) (max-iteration-count uint8 :offset-assert 144) - (nav-flags uint8 :offset-assert 145) + (nav-flags nav-flags :offset-assert 145) (pad-byte uint8 2 :offset-assert 146) (pat-ignore-mask pat-surface :offset-assert 148) (event-self basic :offset-assert 152) @@ -12722,15 +12797,15 @@ (debug-draw (_type_) none 9) (fill-and-probe-using-line-sphere (_type_ vector vector float collide-kind process collide-tri-result int) float 10) (fill-and-probe-using-spheres (_type_ collide-using-spheres-params) symbol 11) - (fill-and-probe-using-y-probe (_type_ vector float collide-kind process collide-tri-result uint) float 12) + (fill-and-probe-using-y-probe (_type_ vector float collide-kind process-drawable collide-tri-result pat-surface) float 12) (fill-using-bounding-box (_type_ bounding-box collide-kind process-drawable pat-surface) none 13) (fill-using-line-sphere (_type_ vector vector float collide-kind process-drawable int) none 14) (fill-using-spheres (_type_ collide-using-spheres-params) none 15) - (fill-using-y-probe (_type_ vector float collide-kind process-drawable uint) none 16) + (fill-using-y-probe (_type_ vector float collide-kind process-drawable pat-surface) none 16) (initialize (_type_) none 17) (probe-using-line-sphere (_type_ vector vector float collide-kind collide-tri-result int) float 18) (probe-using-spheres (_type_ collide-using-spheres-params) symbol 19) - (probe-using-y-probe (_type_ vector float collide-kind collide-tri-result uint) float 20) + (probe-using-y-probe (_type_ vector float collide-kind collide-tri-result pat-surface) float 20) (fill-from-background (_type_ (function bsp-header int collide-list none) (function collide-cache object none)) none 21) ;; second functiom is method 28 (fill-from-foreground-using-box (_type_) none 22) (fill-from-foreground-using-line-sphere (_type_) none 23) @@ -15133,20 +15208,6 @@ :flag-assert #x900000034 ) -(deftype game-option (basic) - ((option-type uint64 :offset-assert 8) - (name game-text-id :offset-assert 16) - (scale basic :offset-assert 20) - (param1 float :offset-assert 24) - (param2 float :offset-assert 28) - (param3 int32 :offset-assert 32) - (value-to-modify pointer :offset-assert 36) ;; pointer to - symbol | ? - ) - :method-count-assert 9 - :size-assert #x28 - :flag-assert #x900000028 - ) - (defenum progress-screen :type int64 (invalid -1) @@ -15185,6 +15246,70 @@ (no-disc 32) (bad-disc 33) (quit 34) + + ;; extra screens for pc port + (camera-options) + (accessibility-options) + (game-ps2-options) + (misc-options) + (resolution) + (aspect-msg) + (aspect-ratio) + (gfx-ps2-options) + (secrets) + (hint-log) + (cheats) + (scrapbook) + (music-player) + (scene-player) + (credits) + + ;; the last one! + (max) + ) + +(defenum game-option-type + :type uint64 + (slider 0) + (language 1) + (on-off 2) + (center-screen 3) + (aspect-ratio 4) + (video-mode 5) + (menu 6) + (yes-no 7) + (button 8) + + ;; extra types for pc port + (normal-inverted) + (display-mode) + (msaa) + (frame-rate) + (lod-bg) + (lod-fg) + (resolution) + (aspect-new) + (language-subtitles) + (speaker) + (aspect-native) + ) + +(defenum game-option-menu + :type int32 + :copy-entries progress-screen) + +(deftype game-option (basic) + ((option-type game-option-type :offset-assert 8) + (name game-text-id :offset-assert 16) + (scale symbol :offset-assert 20) + (param1 float :offset-assert 24) + (param2 float :offset-assert 28) + (param3 game-option-menu :offset-assert 32) + (value-to-modify pointer :offset-assert 36) + ) + :method-count-assert 9 + :size-assert #x28 + :flag-assert #x900000028 ) (deftype progress (process) @@ -15206,8 +15331,8 @@ (force-transition basic :offset-assert 180) (stat-transition basic :offset-assert 184) (level-transition int32 :offset-assert 188) - (language-selection uint64 :offset-assert 192) - (language-direction basic :offset-assert 200) + (language-selection language-enum :offset-assert 192) + (language-direction symbol :offset-assert 200) (language-transition basic :offset-assert 204) (language-x-offset int32 :offset-assert 208) (sides-x-scale float :offset-assert 212) @@ -15231,8 +15356,8 @@ (total-nb-of-orbs int32 :offset-assert 284) (total-nb-of-buzzers int32 :offset-assert 288) (card-info mc-slot-info :offset-assert 292) - (last-option-index-change time-frame :offset-assert 296) - (video-mode-timeout time-frame :offset-assert 304) + (last-option-index-change time-frame :offset-assert 296) + (video-mode-timeout time-frame :offset-assert 304) (display-state-stack progress-screen 5 :offset-assert 312) (option-index-stack int32 5 :offset-assert 352) (display-state-pos int32 :offset-assert 372) @@ -15248,12 +15373,12 @@ :heap-base #x270 :flag-assert #x3b027002dc (:methods - (dummy-14 (_type_) none 14) - (dummy-15 (_type_) none 15) - (dummy-16 (_type_) none 16) + (progress-dummy-14 (_type_) none 14) ;; unused + (progress-dummy-15 (_type_) none 15) ;; unused + (progress-dummy-16 (_type_) none 16) ;; unused (draw-progress (_type_) none 17) - (dummy-18 () none 18) - (dummy-19 (_type_) symbol 19) + (progress-dummy-18 () none 18) ;; unused + (visible? (_type_) symbol 19) (hidden? (_type_) symbol 20) (adjust-sprites (_type_) none 21) (adjust-icons (_type_) none 22) @@ -15263,10 +15388,10 @@ (draw-buzzer-screen (_type_ int) none 26) (draw-notice-screen (_type_) none 27) (draw-options (_type_ int int float) none 28) - (dummy-29 (_type_) none 29) + (respond-common (_type_) none 29) (respond-progress (_type_) none 30) - (dummy-31 (_type_) none 31) - (dummy-32 (_type_) symbol 32) + (respond-memcard (_type_) none 31) + (can-go-back? (_type_) symbol 32) (initialize-icons (_type_) none 33) (initialize-particles (_type_) none 34) (draw-memcard-storage-error (_type_ font-context) none 35) @@ -15278,16 +15403,16 @@ (draw-memcard-auto-save-error (_type_ font-context) none 41) (draw-memcard-removed (_type_ font-context) none 42) (draw-memcard-error (_type_ font-context) none 43) - (dummy-44 (_type_) none 44) + (progress-dummy-44 (_type_) none 44) ;; unused (push! (_type_) none 45) (pop! (_type_) none 46) - (dummy-47 (_type_) none 47) + (progress-dummy-47 (_type_) none 47) ;; unused (enter! (_type_ progress-screen int) none 48) (draw-memcard-format (_type_ font-context) none 49) (draw-auto-save (_type_ font-context) none 50) (set-transition-progress! (_type_ int) none 51) (set-transition-speed! (_type_) none 52) - (dummy-53 (_type_ progress-screen) progress-screen 53) + (set-memcard-screen (_type_ progress-screen) progress-screen 53) (draw-pal-change-to-60hz (_type_ font-context) none 54) (draw-pal-now-60hz (_type_ font-context) none 55) (draw-no-disc (_type_ font-context) none 56) @@ -17669,7 +17794,7 @@ (life 201) (money 202) (money-total 203) - (moeny-per-level 204) + (money-per-level 204) (buzzer-total 205) (fuel-cell 206) (death-movie-tick 207) @@ -21631,7 +21756,7 @@ (starting-state progress-screen :offset-assert 24) (last-slot-saved int32 :offset-assert 32) (slider-backup float :offset-assert 36) - (language-backup int64 :offset-assert 40) + (language-backup language-enum :offset-assert 40) (on-off-backup symbol :offset-assert 48) (center-x-backup int32 :offset-assert 52) (center-y-backup int32 :offset-assert 56) @@ -21710,7 +21835,7 @@ (define-extern projectile-collision-reaction (function collide-shape-moving collide-shape-intersect vector vector uint)) (define-extern projectile-update-velocity-space-wars (function projectile none)) (define-extern find-nearest-attackable (function vector float uint uint vector float projectile)) ;; Whatever te search returns (match from search-info) -(define-extern find-ground-and-draw-shadow (function vector vector float collide-kind process float float none)) +(define-extern find-ground-and-draw-shadow (function vector vector float collide-kind process-drawable float float none)) (define-extern spawn-projectile-blue (function target none)) ;; - Unknowns @@ -22676,7 +22801,7 @@ (use-proximity-notice symbol :offset-assert 204) (use-jump-blocked symbol :offset-assert 208) (use-jump-patrol symbol :offset-assert 212) - (gnd-collide-with uint64 :offset-assert 216) + (gnd-collide-with collide-kind :offset-assert 216) (debug-draw-neck symbol :offset-assert 224) (debug-draw-jump symbol :offset-assert 228) ) @@ -22685,6 +22810,43 @@ :flag-assert #x9000000e8 ) +(defenum nav-enemy-flags + :bitfield #t + :type uint32 + (navenmf0 0) + (navenmf1 1) + (navenmf2 2) + (enable-rotate 3) + (enable-travel 4) + (navenmf5 5) + (navenmf6 6) + (navenmf7 7) + (navenmf8 8) + (standing-jump 9) + (drop-jump 10) + (navenmf11 11) + (navenmf12 12) + (navenmf13 13) + (navenmf14 14) + (navenmf15 15) + (navenmf16 16) + (navenmf17 17) + (navenmf18 18) + (navenmf19 19) + (navenmf20 20) + (navenmf21 21) + (navenmf22 22) + (navenmf23 23) + (navenmf24 24) + (navenmf25 25) + (navenmf26 26) + (navenmf27 27) + (navenmf28 28) + (navenmf29 29) + (navenmf30 30) + (navenmf31 31) + ) + (deftype nav-enemy (process-drawable) ((collide-info collide-shape-moving :score 100 :offset 112) (enemy-info fact-info-enemy :score 100 :offset 144) @@ -22693,22 +22855,22 @@ (frustration-point vector :inline :offset-assert 208) (jump-dest vector :inline :offset-assert 224) (jump-trajectory trajectory :inline :offset-assert 240) - (jump-time time-frame :offset-assert 280) + (jump-time time-frame :offset-assert 280) (nav-info nav-enemy-info :offset-assert 288) (target-speed float :offset-assert 292) (momentum-speed float :offset-assert 296) (acceleration float :offset-assert 300) (rotate-speed float :offset-assert 304) - (turn-time time-frame :offset-assert 312) - (frustration-time time-frame :offset-assert 320) + (turn-time time-frame :offset-assert 312) + (frustration-time time-frame :offset-assert 320) (speed-scale float :offset-assert 328) (neck joint-mod :offset-assert 332) - (reaction-time time-frame :offset-assert 336) - (notice-time time-frame :offset-assert 344) - (state-timeout time-frame :offset-assert 352) - (free-time time-frame :offset-assert 360) - (touch-time time-frame :offset-assert 368) - (nav-enemy-flags uint32 :offset-assert 376) + (reaction-time time-frame :offset-assert 336) + (notice-time time-frame :offset-assert 344) + (state-timeout time-frame :offset-assert 352) + (free-time time-frame :offset-assert 360) + (touch-time time-frame :offset-assert 368) + (nav-enemy-flags nav-enemy-flags :offset-assert 376) (incomming-attack-id handle :offset-assert 384) (jump-return-state (state process) :offset-assert 392) (rand-gen random-generator :offset-assert 396) diff --git a/decompiler/config/jak1_ntsc_black_label.jsonc b/decompiler/config/jak1_ntsc_black_label.jsonc index 5682405412..ef42a305e6 100644 --- a/decompiler/config/jak1_ntsc_black_label.jsonc +++ b/decompiler/config/jak1_ntsc_black_label.jsonc @@ -74,7 +74,6 @@ "stack_structures_file": "decompiler/config/jak1_ntsc_black_label/stack_structures.jsonc", "hacks_file": "decompiler/config/jak1_ntsc_black_label/hacks.jsonc", "inputs_file": "decompiler/config/jak1_ntsc_black_label/inputs.jsonc", - "new_strings_file": "decompiler/config/jak1_ntsc_black_label/new_strings.jsonc", // optional: a predetermined object file name map from a file. // this will make decompilation naming consistent even if you only run on some objects. diff --git a/decompiler/config/jak1_ntsc_black_label/hacks.jsonc b/decompiler/config/jak1_ntsc_black_label/hacks.jsonc index fbaccc3a63..254a73b49f 100644 --- a/decompiler/config/jak1_ntsc_black_label/hacks.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/hacks.jsonc @@ -18,7 +18,8 @@ "cond_with_else_max_lengths": [ ["(method 20 res-lump)", "b0", 2], ["(method 11 res-lump)", "b0", 1], - ["(method 12 res-lump)", "b0", 1] + ["(method 12 res-lump)", "b0", 1], + ["(method 31 progress)", "b35", 1] ], // if a cond with an else case is being used a value in a place where it looks wrong diff --git a/decompiler/config/jak1_ntsc_black_label/inputs.jsonc b/decompiler/config/jak1_ntsc_black_label/inputs.jsonc index 957a623564..58293804f8 100644 --- a/decompiler/config/jak1_ntsc_black_label/inputs.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/inputs.jsonc @@ -262,7 +262,14 @@ //"audio_dir_file_name": "jak1/VAG", "audio_dir_file_name": "", - "streamed_audio_file_names": ["VAGWAD.ENG", "VAGWAD.JAP"], + "streamed_audio_file_names": [ + "VAGWAD.ENG", + "VAGWAD.FRE", + "VAGWAD.SPA", + "VAGWAD.GER", + "VAGWAD.ITA", + "VAGWAD.JAP" + ], "levels_to_extract": [ "BEA.DGO", diff --git a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc index 355241485e..1fb1823595 100644 --- a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc @@ -244,7 +244,29 @@ ["L231", "(pointer uint64)", 1] ], - "progress-static": [["L121", "(array game-text-id)"]], + "progress-static": [ + ["L121", "(array game-text-id)"], + ["L195", "(array game-option)"], + ["L190", "(array game-option)"], + ["L185", "(array game-option)"], + ["L180", "(array game-option)"], + ["L174", "(array game-option)"], + ["L169", "(array game-option)"], + ["L165", "(array game-option)"], + ["L161", "(array game-option)"], + ["L157", "(array game-option)"], + ["L152", "(array game-option)"], + ["L147", "(array game-option)"], + ["L145", "(array game-option)"], + ["L143", "(array game-option)"], + ["L137", "(array game-option)"], + ["L131", "(array game-option)"], + ["L124", "(array game-option)"], + ["L123", "(array (array game-option))"], + ["L122", "(array int32)"], + ["L3", "(array level-tasks-info)"], + ["L2", "(array int32)"] + ], "rigid-body": [["L89", "rigid-body-platform-constants"]], diff --git a/decompiler/config/jak1_ntsc_black_label/new_strings.jsonc b/decompiler/config/jak1_ntsc_black_label/new_strings.jsonc deleted file mode 100644 index eed40d182b..0000000000 --- a/decompiler/config/jak1_ntsc_black_label/new_strings.jsonc +++ /dev/null @@ -1,57 +0,0 @@ -{ - "same_across_languages": { - "1008": "UK ENGLISH", - "1009": "PORTUGUÊS", - "1010": "SUOMALAINEN", - "1011": "SVENSKA", - "1012": "DANSK", - "1013": "NORSK", - "1014": "KOREAN", - "1015": "RUSSIAN", - "1022": "4:3", - "1023": "5:4", - "1024": "16:9", - "1025": "21:9", - "1026": "32:9", - "1027": "640X480", - "1028": "800X600", - "1029": "1024X768", - "1030": "1280X960", - "1031": "1600X1200", - "1032": "960X768", - "1033": "1280X1024", - "1034": "1500X1200", - "1035": "854X480", - "1036": "1280X720", - "1037": "1920X1080", - "1038": "2560X1440", - "1039": "2880X1620", - "1040": "3840X2160", - "1041": "5120X2880", - "1042": "2560X1080", - "1043": "3120X1440", - "1044": "3200X1440", - "1045": "3440X1440", - "1046": "3840X1600", - "1047": "5120X2160", - "1048": "5120X1440" - }, - // will pad the rest of the array with 'TODO' placeholder - "different_across_languages": { - "1000": ["RESOLUTION"], - "1001": ["DISPLAY MODE"], - "1002": ["LETTERBOX"], - "1003": ["SUBTITLES"], - "1004": ["SUBTITLE SPEAKER"], - "1005": ["DISCORD RPC"], - "1006": ["LANGUAGE OPTIONS"], - "1007": ["SUBTITLE LANGUAGE"], - "1016": ["ON"], - "1017": ["OFF"], - "1018": ["AUTO"], - "1019": ["BORDERLESS"], - "1020": ["FULLSCREEN"], - "1021": ["WINDOWED"], - "1049": ["USE ORIGINAL ASPECT"] - } -} diff --git a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc index 2b01113675..ba4a567d55 100644 --- a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc @@ -7024,6 +7024,7 @@ [608, "a1", "(pointer symbol)"], [617, "v1", "(pointer symbol)"], [626, "a1", "(pointer symbol)"], + [883, "a0", "(pointer language-enum)"], [894, "a0", "(pointer symbol)"], [921, "a0", "(pointer symbol)"] ], diff --git a/decompiler/data/game_text.cpp b/decompiler/data/game_text.cpp index 7883c1c9a6..7fbe7e83a4 100644 --- a/decompiler/data/game_text.cpp +++ b/decompiler/data/game_text.cpp @@ -153,8 +153,12 @@ std::string write_game_text( // write! std::string result; // = "\xEF\xBB\xBF"; // UTF-8 encode (don't need this anymore) - result += fmt::format("(language-count {})\n", languages.size()); result += "(group-name \"common\")\n"; + result += "(language-id"; + for (auto lang : languages) { + result += fmt::format(" {}", lang); + } + result += ")\n"; for (auto& x : text_by_id) { result += fmt::format("(#x{:04x}\n ", x.first); for (auto& y : x.second) { @@ -163,28 +167,6 @@ std::string write_game_text( result += ")\n\n"; } - // add our own custom text additions from new_strings.jsonc - // - first add the strings that are the same across all languages - for (auto const& [key, val] : cfg.new_strings_same_across_langs) { - result += fmt::format("(#x{}\n ", key); - for (u32 i = 0; i < languages.size(); i++) { - result += fmt::format("\"{}\"\n ", val); - } - result += ")\n\n"; - } - // - now add the ones that are different, if they do not have all languages defined, pad with - // placeholders - for (auto const& [key, val] : cfg.new_strings_different_across_langs) { - result += fmt::format("(#x{}\n ", key); - for (auto const& str : val) { - result += fmt::format("\"{}\"\n ", str); - } - for (u32 i = 0; i < languages.size() - val.size(); i++) { - result += fmt::format("\"{}\"\n ", "TODO"); - } - result += ")\n\n"; - } - return result; } } // namespace decompiler diff --git a/decompiler/util/data_decompile.cpp b/decompiler/util/data_decompile.cpp index 1c1ce1da43..8f226774a8 100644 --- a/decompiler/util/data_decompile.cpp +++ b/decompiler/util/data_decompile.cpp @@ -1475,7 +1475,8 @@ std::optional> try_decompile_bitfield_from_int( int end_bit = 64 + start_bit; for (auto& field : type_info->fields()) { - if (field.offset() < start_bit || (field.offset() + field.size()) > end_bit) { + if (field.skip_in_decomp() || field.offset() < start_bit || + (field.offset() + field.size()) > end_bit) { continue; } diff --git a/game/assets/game_subtitle.txt b/game/assets/game_subtitle.gp similarity index 66% rename from game/assets/game_subtitle.txt rename to game/assets/game_subtitle.gp index 9db0711a4d..dedcad416b 100644 --- a/game/assets/game_subtitle.txt +++ b/game/assets/game_subtitle.gp @@ -4,8 +4,8 @@ ;; you can find the game-text-version parsing in .cpp and an enum in goal-lib.gc (subtitle - (jak1-v1 "game/assets/subtitle/jak1/game_subtitle_en.txt") - (jak1-v1 "game/assets/subtitle/jak1/game_subtitle_es.txt") + (jak1-v1 "game/assets/jak1/subtitle/game_subtitle_en.txt") + (jak1-v1 "game/assets/jak1/subtitle/game_subtitle_es.txt") ) diff --git a/game/assets/game_text.gp b/game/assets/game_text.gp new file mode 100644 index 0000000000..728481ca1c --- /dev/null +++ b/game/assets/game_text.gp @@ -0,0 +1,11 @@ +;; "project file" for text make tool. +;; it's very simple... a list of (version file) +;; eventually should also include output filename +;; you can find the game-text-version parsing in .cpp and an enum in goal-lib.gc + +(text + (jak1-v1 "assets/game_text.txt") + (jak1-v1 "game/assets/jak1/text/game_text_en.txt") + ) + + diff --git a/game/assets/subtitle/jak1/game_subtitle_en.txt b/game/assets/jak1/subtitle/game_subtitle_en.txt similarity index 100% rename from game/assets/subtitle/jak1/game_subtitle_en.txt rename to game/assets/jak1/subtitle/game_subtitle_en.txt diff --git a/game/assets/subtitle/jak1/game_subtitle_es.txt b/game/assets/jak1/subtitle/game_subtitle_es.txt similarity index 100% rename from game/assets/subtitle/jak1/game_subtitle_es.txt rename to game/assets/jak1/subtitle/game_subtitle_es.txt diff --git a/game/assets/jak1/text/game_text_en.txt b/game/assets/jak1/text/game_text_en.txt new file mode 100644 index 0000000000..6b19d8509c --- /dev/null +++ b/game/assets/jak1/text/game_text_en.txt @@ -0,0 +1,143 @@ +(group-name "common") +(language-id 0 6) + +;; ----------------- +;; progress menu (insanity) + +(#x1000 "CAMERA OPTIONS" + "CAMERA OPTIONS") +(#x1001 "NORMAL" + "NORMAL") +(#x1002 "INVERTED" + "INVERTED") +(#x1003 "HORIZONTAL CAMERA CONTROL" + "HORIZONTAL CAMERA CONTROL") +(#x1004 "VERTICAL CAMERA CONTROL" + "VERTICAL CAMERA CONTROL") + +(#x100f "MISCELLANEOUS" + "MISCELLANEOUS") + +(#x1010 "ACCESSIBILITY" + "ACCESSIBILITY") +(#x1011 "PRECURSOR ORB GLOW" + "PRECURSOR ORB GLOW") + +(#x1020 "PS2 OPTIONS" + "PS2 OPTIONS") +(#x1021 "PS2 LOAD SPEED" + "PS2 LOAD SPEED") +(#x1022 "PARTICLE CULLING" + "PARTICLE CULLING") + +(#x1030 "DISCORD RICH-PRESENCE" + "DISCORD RICH-PRESENCE") + +(#x1031 "DISPLAY MODE" + "DISPLAY MODE") +(#x1032 "WINDOWED" + "WINDOWED") +(#x1033 "BORDERLESS" + "BORDERLESS") +(#x1034 "FULLSCREEN" + "FULLSCREEN") + +(#x1035 "GAME RESOLUTION" + "GAME RESOLUTION") +(#x1036 "~D X ~D" + "~D X ~D") + +(#x1037 "PS2 ASPECT RATIO" + "PS2 ASPECT RATIO") +(#x1038 "WHEN PS2 ASPECT RATIO IS ENABLED, ONLY 4X3 AND 16X9 ASPECT RATIO CAN BE SELECTED. CONTINUE?" + "WHEN PS2 ASPECT RATIO IS ENABLED, ONLY 4X3 AND 16X9 ASPECT RATIO CAN BE SELECTED. CONTINUE?") +(#x1039 "ASPECT RATIO (PS2)" + "ASPECT RATIO (PS2)") +(#x103a "FIT TO SCREEN" + "FIT TO SCREEN") + +(#x1050 "MSAA" + "MSAA") +(#x1051 "~DX" + "~DX") +(#x1052 "2X" + "2X") +(#x1053 "4X" + "4X") +(#x1054 "8X" + "8X") +(#x1055 "16X" + "16X") + +(#x1060 "FRAME RATE" + "FRAME RATE") + +(#x1070 "LEVEL OF DETAIL (BACKGROUND)" + "LEVEL OF DETAIL (BACKGROUND)") +(#x1071 "LEVEL OF DETAIL (FOREGROUND)" + "LEVEL OF DETAIL (FOREGROUND)") +(#x1072 "HIGHEST" + "HIGHEST") +(#x1073 "HIGH" + "HIGH") +(#x1074 "MID" + "MID") +(#x1075 "LOW" + "LOW") +(#x1076 "LOWEST" + "LOWEST") +(#x1077 "PS2" + "PS2") + +(#x1078 "SUBTITLES" + "SUBTITLES") +(#x1079 "HINT SUBTITLES" + "HINT SUBTITLES") +(#x107a "SUBTITLES LANGUAGE" + "SUBTITLES LANGUAGE") +(#x107b "SUBTITLES SPEAKER" + "SUBTITLES SPEAKER") +(#x107c "ALWAYS" + "ALWAYS") +(#x107d "NEVER" + "NEVER") +(#x107e "OFF-SCREEN" + "OFF-SCREEN") + +(#x107f "HINT LOG" + "HINT LOG") + +(#x1080 "CHEATS" + "CHEATS") +(#x1090 "INFINITE BLUE ECO" + "INFINITE BLUE ECO") +(#x1091 "INFINITE RED ECO" + "INFINITE RED ECO") +(#x1092 "INFINITE GREEN ECO" + "INFINITE GREEN ECO") +(#x1093 "INFINITE YELLOW ECO" + "INFINITE YELLOW ECO") +(#x1094 "ALTERNATE DAXTER" + "ALTERNATE DAXTER") +(#x1095 "INVINCIBILITY" + "INVINCIBILITY") + +(#x10c0 "MUSIC PLAYER" + "MUSIC PLAYER") +(#x10c1 "SCENE PLAYER" + "SCENE PLAYER") +(#x10c2 "PLAY CREDITS" + "PLAY CREDITS") +(#x10c3 "SCRAPBOOK" + "SCRAPBOOK") + + +;; ----------------- +;; test + +(#x7fff + "ARMOR" + "ARMOUR" + ) + + diff --git a/game/graphics/display.cpp b/game/graphics/display.cpp index a7248945d6..430ffade63 100644 --- a/game/graphics/display.cpp +++ b/game/graphics/display.cpp @@ -95,7 +95,7 @@ int GfxDisplay::height() { int h; m_renderer->display_size(this, NULL, &h); #ifdef _WIN32 - if (fullscreen_mode() == 2) { + if (fullscreen_mode() == Gfx::DisplayMode::Borderless) { // windows borderless hack h--; } @@ -103,14 +103,6 @@ int GfxDisplay::height() { return h; } -void GfxDisplay::set_size(int w, int h) { - m_renderer->display_set_size(this, w, h); -} - -void GfxDisplay::get_scale(float* x, float* y) { - m_renderer->display_scale(this, x, y); -} - void GfxDisplay::backup_params() { m_renderer->display_size(this, &m_width, &m_height); m_renderer->display_position(this, &m_xpos, &m_ypos); diff --git a/game/graphics/display.h b/game/graphics/display.h index a811dacb92..d1983ac44f 100644 --- a/game/graphics/display.h +++ b/game/graphics/display.h @@ -25,9 +25,9 @@ class GfxDisplay { int m_xpos; int m_ypos; - int m_fullscreen_mode = 0; + Gfx::DisplayMode m_fullscreen_mode = Gfx::DisplayMode::Windowed; + Gfx::DisplayMode m_fullscreen_target_mode = Gfx::DisplayMode::Windowed; int m_fullscreen_screen; - int m_fullscreen_target_mode = 0; int m_fullscreen_target_screen; public: @@ -45,22 +45,26 @@ class GfxDisplay { void set_renderer(GfxPipeline pipeline); void set_window(GLFWwindow* window); void set_title(const char* title); - void set_size(int w, int h); - void get_scale(float* w, float* h); + void set_size(int w, int h) { m_renderer->display_set_size(this, w, h); } + void get_scale(float* x, float* y) { m_renderer->display_scale(this, x, y); } + void get_screen_size(s64 vmode_idx, s32* w, s32* h, s32* c) { + m_renderer->screen_size(this, vmode_idx, 0, w, h, c); + } const char* title() const { return m_title; } - bool fullscreen_pending() { return m_fullscreen_mode != m_fullscreen_target_mode; } + bool fullscreen_pending() const { return m_fullscreen_mode != m_fullscreen_target_mode; } void fullscreen_flush() { m_renderer->set_fullscreen(this, m_fullscreen_target_mode, m_fullscreen_target_screen); m_fullscreen_mode = m_fullscreen_target_mode; m_fullscreen_screen = m_fullscreen_target_screen; } - void set_fullscreen(int mode, int screen) { + void set_fullscreen(Gfx::DisplayMode mode, int screen) { m_fullscreen_target_mode = mode; m_fullscreen_target_screen = screen; } - int fullscreen_mode() { return m_fullscreen_mode; } - int fullscreen_screen() { return m_fullscreen_screen; } + int fullscreen_mode() const { return m_fullscreen_mode; } + int fullscreen_screen() const { return m_fullscreen_screen; } + bool windowed() const { return m_fullscreen_mode == Gfx::DisplayMode::Windowed; } void backup_params(); int width_backup() { return m_width; } int height_backup() { return m_height; } diff --git a/game/graphics/gfx.cpp b/game/graphics/gfx.cpp index 50813fb627..03f08aa6e0 100644 --- a/game/graphics/gfx.cpp +++ b/game/graphics/gfx.cpp @@ -215,12 +215,26 @@ void get_window_scale(float* x, float* y) { } } +int get_fullscreen() { + if (Display::GetMainDisplay()) { + return Display::GetMainDisplay()->fullscreen_mode(); + } else { + return DisplayMode::Windowed; + } +} + +void get_screen_size(s64 vmode_idx, s32* w, s32* h, s32* c) { + if (Display::GetMainDisplay()) { + Display::GetMainDisplay()->get_screen_size(vmode_idx, w, h, c); + } +} + void set_letterbox(int w, int h) { g_global_settings.lbox_w = w; g_global_settings.lbox_h = h; } -void set_fullscreen(int mode, int screen) { +void set_fullscreen(DisplayMode mode, int screen) { if (Display::GetMainDisplay()) { Display::GetMainDisplay()->set_fullscreen(mode, screen); } diff --git a/game/graphics/gfx.h b/game/graphics/gfx.h index b1d2ee24b0..ff6985792e 100644 --- a/game/graphics/gfx.h +++ b/game/graphics/gfx.h @@ -31,6 +31,7 @@ struct GfxRendererModule { std::function display_set_size; std::function display_scale; std::function set_fullscreen; + std::function screen_size; std::function exit; std::function vsync; std::function sync_path; @@ -87,6 +88,8 @@ extern GfxSettings g_settings; const GfxRendererModule* GetRenderer(GfxPipeline pipeline); const GfxRendererModule* GetCurrentRenderer(); +enum DisplayMode { Windowed = 0, Fullscreen = 1, Borderless = 2 }; + u32 Init(); void Loop(std::function f); u32 Exit(); @@ -102,8 +105,10 @@ u64 get_window_width(); u64 get_window_height(); void set_window_size(u64 w, u64 h); void get_window_scale(float* x, float* y); +int get_fullscreen(); +void get_screen_size(s64 vmode_idx, s32* w, s32* h, s32* c); void set_letterbox(int w, int h); -void set_fullscreen(int mode, int screen); +void set_fullscreen(DisplayMode mode, int screen); void input_mode_set(u32 enable); void input_mode_save(); s64 get_mapped_button(s64 pad, s64 button); diff --git a/game/graphics/opengl_renderer/Profiler.cpp b/game/graphics/opengl_renderer/Profiler.cpp index 3a6d1d82d3..269478fe19 100644 --- a/game/graphics/opengl_renderer/Profiler.cpp +++ b/game/graphics/opengl_renderer/Profiler.cpp @@ -185,7 +185,7 @@ void FramePlot::draw(float max) { auto* me = (FramePlot*)data; return me->m_buffer[(me->m_idx + idx) % SIZE]; }, - (void*)this, SIZE, 0, nullptr, 0, max, ImVec2(300, 40)); + (void*)this, SIZE, 0, nullptr, 0, max, ImVec2(300, 20)); } void SmallProfiler::draw(const std::string& status, const SmallProfilerStats& stats) { @@ -219,4 +219,4 @@ void SmallProfiler::draw(const std::string& status, const SmallProfilerStats& st } } ImGui::End(); -} \ No newline at end of file +} diff --git a/game/graphics/pipelines/opengl.cpp b/game/graphics/pipelines/opengl.cpp index ade6f5c909..414aa0eecc 100644 --- a/game/graphics/pipelines/opengl.cpp +++ b/game/graphics/pipelines/opengl.cpp @@ -126,7 +126,7 @@ static int gl_init(GfxSettings& settings) { glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_FALSE); } glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE); - glfwWindowHint(GLFW_SAMPLES, 4); + glfwWindowHint(GLFW_SAMPLES, 1); return 0; } @@ -285,7 +285,7 @@ static void gl_set_fullscreen(GfxDisplay* display, int mode, int /*screen*/) { GLFWmonitor* monitor = glfwGetPrimaryMonitor(); // todo auto window = display->window_glfw; switch (mode) { - case 0: { + case Gfx::DisplayMode::Windowed: { // windowed glfwSetWindowAttrib(window, GLFW_DECORATED, GLFW_TRUE); glfwSetWindowFocusCallback(window, NULL); @@ -293,18 +293,18 @@ static void gl_set_fullscreen(GfxDisplay* display, int mode, int /*screen*/) { glfwSetWindowMonitor(window, NULL, display->xpos_backup(), display->ypos_backup(), display->width_backup(), display->height_backup(), GLFW_DONT_CARE); } break; - case 1: { + case Gfx::DisplayMode::Fullscreen: { // fullscreen - if (display->fullscreen_mode() == 0) { + if (display->windowed()) { display->backup_params(); } const GLFWvidmode* vmode = glfwGetVideoMode(monitor); glfwSetWindowMonitor(window, monitor, 0, 0, vmode->width, vmode->height, 60); glfwSetWindowFocusCallback(window, FocusCallback); } break; - case 2: { + case Gfx::DisplayMode::Borderless: { // borderless fullscreen - if (display->fullscreen_mode() == 0) { + if (display->windowed()) { display->backup_params(); } int x, y; @@ -322,6 +322,35 @@ static void gl_set_fullscreen(GfxDisplay* display, int mode, int /*screen*/) { } } +static void gl_screen_size(GfxDisplay* display, + int vmode_idx, + int /*screen*/, + s32* w_out, + s32* h_out, + s32* count_out) { + int count = 0; + auto vmode = glfwGetVideoMode(glfwGetPrimaryMonitor()); + auto vmodes = glfwGetVideoModes(glfwGetPrimaryMonitor(), &count); + if (vmode_idx >= 0) { + vmode = &vmodes[vmode_idx]; + } else { + for (int i = 0; i < count; ++i) { + if (!vmode || vmode->height < vmodes[i].height) { + vmode = &vmodes[i]; + } + } + } + if (count_out) { + *count_out = count; + } + if (w_out) { + *w_out = vmode->width; + } + if (h_out) { + *h_out = vmode->height; + } +} + static void gl_render_display(GfxDisplay* display) { GLFWwindow* window = display->window_glfw; @@ -504,6 +533,7 @@ const GfxRendererModule moduleOpenGL = { gl_display_set_size, // display_set_size gl_display_scale, // display_scale gl_set_fullscreen, // set_fullscreen + gl_screen_size, // screen_size gl_exit, // exit gl_vsync, // vsync gl_sync_path, // sync_path diff --git a/game/kernel/kmachine.cpp b/game/kernel/kmachine.cpp index e323127485..477bf40882 100644 --- a/game/kernel/kmachine.cpp +++ b/game/kernel/kmachine.cpp @@ -737,7 +737,10 @@ void PutDisplayEnv(u32 ptr) { } /*! - * PC Port function to get a 300MHz timer value. + * PC PORT FUNCTIONS BEGIN + */ +/*! + * Get a 300MHz timer value. */ u64 read_ee_timer() { u64 ns = ee_clock_timer.getNs(); @@ -745,14 +748,14 @@ u64 read_ee_timer() { } /*! - * PC Port function to do a fast memory copy. + * Do a fast memory copy. */ void c_memmove(u32 dst, u32 src, u32 size) { memmove(Ptr(dst).c(), Ptr(src).c(), size); } /*! - * PC Port function to return the current OS as a symbol. + * Return the current OS as a symbol. Actually returns what it was compiled for! */ u64 get_os() { #ifdef _WIN32 @@ -765,7 +768,7 @@ u64 get_os() { } /*! - * PC Port function + * Returns size of window. */ void get_window_size(u32 w_ptr, u32 h_ptr) { if (w_ptr) { @@ -779,7 +782,7 @@ void get_window_size(u32 w_ptr, u32 h_ptr) { } /*! - * PC Port function + * Returns scale of window. This is for DPI stuff. */ void get_window_scale(u32 x_ptr, u32 y_ptr) { float* x = x_ptr ? Ptr(x_ptr).c() : NULL; @@ -787,6 +790,23 @@ void get_window_scale(u32 x_ptr, u32 y_ptr) { Gfx::get_window_scale(x, y); } +/*! + * Returns resolution of the monitor. + */ +void get_screen_size(s64 vmode_idx, u32 w_ptr, u32 h_ptr, u32 c_ptr) { + s32 *w_out = 0, *h_out = 0, *c_out = 0; + if (w_ptr) { + w_out = Ptr(w_ptr).c(); + } + if (h_ptr) { + h_out = Ptr(h_ptr).c(); + } + if (c_ptr) { + c_out = Ptr(c_ptr).c(); + } + Gfx::get_screen_size(vmode_idx, w_out, h_out, c_out); +} + void update_discord_rpc(u32 discord_info) { if (gDiscordRpcEnabled) { DiscordRichPresence rpc; @@ -814,7 +834,7 @@ void update_discord_rpc(u32 discord_info) { strcat(state, std::to_string(cells).c_str()); strcat(state, " | Orbs: "); strcat(state, std::to_string(orbs).c_str()); - strcat(state, " | Scout flies: "); + strcat(state, " | Flies: "); strcat(state, std::to_string(scout_flies).c_str()); } rpc.state = state; @@ -846,6 +866,28 @@ void mkdir_path(u32 filepath) { file_util::create_dir_if_needed_for_file(filepath_str); } +u32 get_fullscreen() { + switch (Gfx::get_fullscreen()) { + default: + case Gfx::DisplayMode::Windowed: + return intern_from_c("windowed").offset; + case Gfx::DisplayMode::Borderless: + return intern_from_c("borderless").offset; + case Gfx::DisplayMode::Fullscreen: + return intern_from_c("fullscreen").offset; + } +} + +void set_fullscreen(u32 symptr, s64 screen) { + if (symptr == intern_from_c("windowed").offset || symptr == s7.offset) { + Gfx::set_fullscreen(Gfx::DisplayMode::Windowed, screen); + } else if (symptr == intern_from_c("borderless").offset) { + Gfx::set_fullscreen(Gfx::DisplayMode::Borderless, screen); + } else if (symptr == intern_from_c("fullscreen").offset) { + Gfx::set_fullscreen(Gfx::DisplayMode::Fullscreen, screen); + } +} + void InitMachine_PCPort() { // PC Port added functions make_function_symbol_from_c("__read-ee-timer", (void*)read_ee_timer); @@ -869,9 +911,11 @@ void InitMachine_PCPort() { make_function_symbol_from_c("pc-get-os", (void*)get_os); make_function_symbol_from_c("pc-get-window-size", (void*)get_window_size); make_function_symbol_from_c("pc-get-window-scale", (void*)get_window_scale); + make_function_symbol_from_c("pc-get-fullscreen", (void*)get_fullscreen); + make_function_symbol_from_c("pc-get-screen-size", (void*)get_screen_size); make_function_symbol_from_c("pc-set-window-size", (void*)Gfx::set_window_size); make_function_symbol_from_c("pc-set-letterbox", (void*)Gfx::set_letterbox); - make_function_symbol_from_c("pc-set-fullscreen", (void*)Gfx::set_fullscreen); + make_function_symbol_from_c("pc-set-fullscreen", (void*)set_fullscreen); make_function_symbol_from_c("pc-renderer-tree-set-lod", (void*)Gfx::SetLod); // file related functions @@ -897,6 +941,9 @@ void InitMachine_PCPort() { intern_from_c("*pc-settings-folder*")->value = make_string_from_c(settings_path.string().c_str()); intern_from_c("*pc-settings-built-sha*")->value = make_string_from_c(GIT_SHORT_SHA); } +/*! + * PC PORT FUNCTIONS END + */ void vif_interrupt_callback() { // added for the PC port for faking VIF interrupts from the graphics system. diff --git a/game/system/Deci2Server.cpp b/game/system/Deci2Server.cpp index 87b66f50cd..a67d5cbe56 100644 --- a/game/system/Deci2Server.cpp +++ b/game/system/Deci2Server.cpp @@ -25,9 +25,9 @@ #include "Deci2Server.h" #include "common/util/Assert.h" -Deci2Server::Deci2Server(std::function shutdown_callback) { +Deci2Server::Deci2Server(std::function shutdown_callback) + : want_exit(std::move(shutdown_callback)) { buffer = new char[BUFFER_SIZE]; - want_exit = std::move(shutdown_callback); } Deci2Server::~Deci2Server() { diff --git a/goal_src/dgos/engine.gd b/goal_src/dgos/engine.gd index 7abbc3cad0..c00085d8f9 100644 --- a/goal_src/dgos/engine.gd +++ b/goal_src/dgos/engine.gd @@ -279,6 +279,7 @@ ("progress-part.o" "progress-part") ("progress-draw.o" "progress-draw") ("progress.o" "progress") + ("progress-pc.o" "progress-pc") ;; added ("credits.o" "credits") ("projectiles.o" "projectiles") ("ocean.o" "ocean") diff --git a/goal_src/dgos/game.gd b/goal_src/dgos/game.gd index 7b3573d782..44feb49583 100644 --- a/goal_src/dgos/game.gd +++ b/goal_src/dgos/game.gd @@ -275,6 +275,7 @@ ("progress-part.o" "progress-part") ("progress-draw.o" "progress-draw") ("progress.o" "progress") + ("progress-pc.o" "progress-pc") ;; added ("credits.o" "credits") ("projectiles.o" "projectiles") ("ocean.o" "ocean") diff --git a/goal_src/engine/collide/collide-cache-h.gc b/goal_src/engine/collide/collide-cache-h.gc index 992b7ce9f6..f5c31b4f37 100644 --- a/goal_src/engine/collide/collide-cache-h.gc +++ b/goal_src/engine/collide/collide-cache-h.gc @@ -133,15 +133,15 @@ (debug-draw (_type_) none 9) (fill-and-probe-using-line-sphere (_type_ vector vector float collide-kind process collide-tri-result int) float 10) (fill-and-probe-using-spheres (_type_ collide-using-spheres-params) symbol 11) - (fill-and-probe-using-y-probe (_type_ vector float collide-kind process collide-tri-result uint) float 12) + (fill-and-probe-using-y-probe (_type_ vector float collide-kind process-drawable collide-tri-result pat-surface) float 12) (fill-using-bounding-box (_type_ bounding-box collide-kind process-drawable pat-surface) none 13) (fill-using-line-sphere (_type_ vector vector float collide-kind process-drawable int) none 14) (fill-using-spheres (_type_ collide-using-spheres-params) none 15) - (fill-using-y-probe (_type_ vector float collide-kind process-drawable uint) none 16) + (fill-using-y-probe (_type_ vector float collide-kind process-drawable pat-surface) none 16) (initialize (_type_) none 17) (probe-using-line-sphere (_type_ vector vector float collide-kind collide-tri-result int) float 18) (probe-using-spheres (_type_ collide-using-spheres-params) symbol 19) - (probe-using-y-probe (_type_ vector float collide-kind collide-tri-result uint) float 20) + (probe-using-y-probe (_type_ vector float collide-kind collide-tri-result pat-surface) float 20) (fill-from-background (_type_ (function bsp-header int collide-list none) (function collide-cache object none)) none 21) ;; second functiom is method 28 (fill-from-foreground-using-box (_type_) none 22) (fill-from-foreground-using-line-sphere (_type_) none 23) diff --git a/goal_src/engine/collide/collide-cache.gc b/goal_src/engine/collide/collide-cache.gc index 93ec127b5c..b0ead97c4e 100644 --- a/goal_src/engine/collide/collide-cache.gc +++ b/goal_src/engine/collide/collide-cache.gc @@ -427,7 +427,7 @@ ;; Y PROBE ;;;;;;;;;;;;;;;;;;;;;;;;;; -(defmethod fill-using-y-probe collide-cache ((obj collide-cache) (arg0 vector) (arg1 float) (arg2 collide-kind) (arg3 process-drawable) (arg4 uint)) +(defmethod fill-using-y-probe collide-cache ((obj collide-cache) (arg0 vector) (arg1 float) (arg2 collide-kind) (arg3 process-drawable) (arg4 pat-surface)) (rlet ((vf1 :class vf) (vf2 :class vf) (vf3 :class vf) @@ -2214,15 +2214,15 @@ (arg0 vector) (arg1 float) (arg2 collide-kind) - (arg3 process) + (arg3 process-drawable) (arg4 collide-tri-result) - (arg5 uint) + (arg5 pat-surface) ) - (fill-using-y-probe obj arg0 arg1 arg2 (the-as process-drawable arg3) arg5) + (fill-using-y-probe obj arg0 arg1 arg2 arg3 arg5) (probe-using-y-probe obj arg0 arg1 arg2 arg4 arg5) ) -(defmethod probe-using-y-probe collide-cache ((obj collide-cache) (arg0 vector) (arg1 float) (arg2 collide-kind) (arg3 collide-tri-result) (arg4 uint)) +(defmethod probe-using-y-probe collide-cache ((obj collide-cache) (arg0 vector) (arg1 float) (arg2 collide-kind) (arg3 collide-tri-result) (arg4 pat-surface)) (rlet ((vf0 :class vf) (vf1 :class vf) (vf3 :class vf) @@ -2232,7 +2232,7 @@ (.mov vf3 arg1) (.lvf vf1 (&-> arg0 quad)) (set! (-> gp-0 best-u) 2.0) - (set! (-> gp-0 ignore-pat) (the-as pat-surface arg4)) + (set! (-> gp-0 ignore-pat) arg4) (set! (-> gp-0 tri-out) arg3) (.sub.x.vf vf3 vf0 vf3 :mask #b10) (.svf (&-> gp-0 start-pos quad) vf1) @@ -2248,10 +2248,7 @@ (puyp-mesh obj gp-0 (the-as collide-cache-prim s2-0)) ) (else - (if (zero? (logand (the-as pat-surface arg4) - (-> (the-as collide-shape-prim-sphere (-> (the-as collide-cache-prim s2-0) prim)) pat) - ) - ) + (if (zero? (logand arg4 (-> (the-as collide-shape-prim-sphere (-> (the-as collide-cache-prim s2-0) prim)) pat))) (puyp-sphere obj gp-0 (the-as collide-cache-prim s2-0)) ) ) diff --git a/goal_src/engine/collide/collide-shape-h.gc b/goal_src/engine/collide/collide-shape-h.gc index f52ba9e9cb..7e79589629 100644 --- a/goal_src/engine/collide/collide-shape-h.gc +++ b/goal_src/engine/collide/collide-shape-h.gc @@ -476,11 +476,24 @@ (declare-type collide-work structure) (declare-type touching-shapes-entry structure) +(defenum nav-flags + :bitfield #t + :type uint8 + (navf0 0) + (navf1 1) + (navf2 2) + (navf3 3) + (navf4 4) + (navf5 5) + (navf6 6) + (navf7 7) + ) + ;; we're a child of trsqv, so we store a full transform + derivative. (deftype collide-shape (trsqv) ((process process-drawable :offset-assert 140) (max-iteration-count uint8 :offset-assert 144) - (nav-flags uint8 :offset-assert 145) + (nav-flags nav-flags :offset-assert 145) (pad-byte uint8 2 :offset-assert 146) (pat-ignore-mask pat-surface :offset-assert 148) (event-self basic :offset-assert 152) @@ -647,7 +660,7 @@ (let ((obj (object-new allocation type-to-make (the int (-> type-to-make size))))) (set! (-> obj process) proc) (set! (-> obj max-iteration-count) 1) - (set! (-> obj nav-flags) #x1) + (set! (-> obj nav-flags) (nav-flags navf0)) (set! (-> obj event-self) #f) (set! (-> obj event-other) #f) (set! (-> obj riders) #f) diff --git a/goal_src/engine/collide/collide-shape.gc b/goal_src/engine/collide/collide-shape.gc index 4f3df579d5..a5105626e4 100644 --- a/goal_src/engine/collide/collide-shape.gc +++ b/goal_src/engine/collide/collide-shape.gc @@ -1641,7 +1641,7 @@ (+! (-> s4-0 y) arg0) 0.0 ;; find the ground - (let ((f0-4 (fill-and-probe-using-y-probe *collide-cache* s4-0 f30-0 arg3 (-> obj process) s3-0 (the-as uint 1)))) + (let ((f0-4 (fill-and-probe-using-y-probe *collide-cache* s4-0 f30-0 arg3 (-> obj process) s3-0 (new 'static 'pat-surface :noentity #x1)))) (when (< f0-4 0.0) (if arg2 (format 0 "WARNING: move-to-ground: (~f ~f) failed to locate ground [~S type ~S]~%" diff --git a/goal_src/engine/debug/default-menu.gc b/goal_src/engine/debug/default-menu.gc index 2624755135..5a105ec7bf 100644 --- a/goal_src/engine/debug/default-menu.gc +++ b/goal_src/engine/debug/default-menu.gc @@ -4433,9 +4433,10 @@ ;(flag "Alt load boundaries" #f ,(dm-lambda-boolean-flag (-> *pc-settings* new-lb?))) (flag "All actors" #f ,(dm-lambda-boolean-flag (-> *pc-settings* force-actors?))) (flag "Display actor counts" #f ,(dm-lambda-boolean-flag (-> *pc-settings* display-actor-counts))) + (flag "Display git commit" #f ,(dm-lambda-boolean-flag (-> *pc-settings* display-sha))) (function "Reset" #f (lambda () (reset *pc-settings*))) - (function "Save" #f (lambda () (write-to-file *pc-settings* PC_SETTINGS_FILE_NAME))) - (function "Load" #f (lambda () (read-from-file *pc-settings* PC_SETTINGS_FILE_NAME))) + (function "Save" #f (lambda () (commit-to-file *pc-settings*))) + (function "Load" #f (lambda () (load-settings *pc-settings*))) ) ) ) @@ -4452,6 +4453,7 @@ (float-var "Actor birth dist" #f ,(dm-lambda-meters-var (-> *ACTOR-bank* birth-dist)) 20 1 #t 0 10000 1) (float-var "Actor pause dist" #f ,(dm-lambda-meters-var (-> *ACTOR-bank* pause-dist)) 20 1 #t 0 10000 1) (flag "Heap status" #f ,(dm-lambda-boolean-flag (-> *pc-settings* display-heap-status))) + (flag "Text boxes" #f ,(dm-lambda-boolean-flag (-> *pc-settings* display-text-box))) (flag "Bug report" #f ,(dm-lambda-boolean-flag (-> *pc-settings* display-bug-report))) (menu "Mood override" (function "-- SIMPLE OVERRIDE" #f nothing) diff --git a/goal_src/engine/draw/drawable.gc b/goal_src/engine/draw/drawable.gc index 2da7fe1cb1..ff2deab428 100644 --- a/goal_src/engine/draw/drawable.gc +++ b/goal_src/engine/draw/drawable.gc @@ -1544,7 +1544,7 @@ ) (toggle-pause) ) - (when (or (not *progress-process*) (dummy-32 (-> *progress-process* 0))) + (when (or (not *progress-process*) (can-go-back? (-> *progress-process* 0))) (if (or (logtest? (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons select r3 start)) ;; push pause (and ;; controller lost (logtest? (-> *cpad-list* cpads 0 valid) 128) diff --git a/goal_src/engine/game/collectables.gc b/goal_src/engine/game/collectables.gc index fde83563a7..b9a37a4070 100644 --- a/goal_src/engine/game/collectables.gc +++ b/goal_src/engine/game/collectables.gc @@ -2828,9 +2828,9 @@ s2-1 (the-as float 81920.0) (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) s1-1 - (the-as uint 1) + (new 'static 'pat-surface :noentity #x1) ) 0.0 ) @@ -2841,7 +2841,7 @@ (if (= (the-as int s3-0) 6) (set! (-> s2-1 y) (+ 6144.0 (-> s2-1 y))) ) - (birth-pickup-at-point s2-1 (the-as pickup-type s3-0) f30-0 arg0 (the-as process-drawable arg1) obj) + (birth-pickup-at-point s2-1 (the-as pickup-type s3-0) f30-0 arg0 arg1 obj) ) ) ) diff --git a/goal_src/engine/game/game-save.gc b/goal_src/engine/game/game-save.gc index 11998b6dd5..8722d03aff 100644 --- a/goal_src/engine/game/game-save.gc +++ b/goal_src/engine/game/game-save.gc @@ -57,7 +57,7 @@ (life 201) (money 202) (money-total 203) - (moeny-per-level 204) + (money-per-level 204) (buzzer-total 205) (fuel-cell 206) (death-movie-tick 207) @@ -227,7 +227,7 @@ (when detail (let ((v1-4 (-> tag elt-type))) (cond - ((or (= v1-4 (game-save-elt moeny-per-level)) (= v1-4 (game-save-elt deaths-per-level))) + ((or (= v1-4 (game-save-elt money-per-level)) (= v1-4 (game-save-elt deaths-per-level))) ;; per level u8's (dotimes (prog-lev-idx (-> tag elt-count)) (let ((lev-name (progress-level-index->string prog-lev-idx))) @@ -421,7 +421,7 @@ ) (let ((v1-56 (&+ v1-55 16))) (let ((a0-30 (the-as game-save-tag (&+ v1-56 0)))) - (set! (-> a0-30 elt-type) (game-save-elt moeny-per-level)) + (set! (-> a0-30 elt-type) (game-save-elt money-per-level)) (set! (-> a0-30 elt-count) 32) (set! (-> a0-30 elt-size) (the-as uint 1)) ) @@ -861,7 +861,7 @@ (((game-save-elt money-total)) (set! (-> obj money-total) (-> data user-float0)) ) - (((game-save-elt moeny-per-level)) + (((game-save-elt money-per-level)) (let ((v1-34 (min 32 (-> data elt-count)))) (dotimes (a0-76 v1-34) (set! (-> obj money-per-level a0-76) (-> (the-as (pointer uint8) (&+ (the-as pointer data) 16)) a0-76)) diff --git a/goal_src/engine/game/main.gc b/goal_src/engine/game/main.gc index 4c04bff803..106794de10 100644 --- a/goal_src/engine/game/main.gc +++ b/goal_src/engine/game/main.gc @@ -356,7 +356,7 @@ ;; cheat mode (check-cheat-code (-> *cheat-temp* 0) 0 (up up down down left right left right x x square circle square circle) - (cpad-clear-buttons! 0 r1) + (cpad-clear! 0 r1) ;; toggle! (not! *cheat-mode*) (cheats-sound-play *cheat-mode*) @@ -366,7 +366,7 @@ (when *cheat-mode* (check-cheat-code (-> *cheat-temp* 1) 0 (circle square circle square x x right left right left down down up up) - (cpad-clear-buttons! 0 r1) + (cpad-clear! 0 r1) ;; toggle between #t and debug. (set! *cheat-mode* (if (= *cheat-mode* 'debug) #t @@ -382,7 +382,7 @@ ((GAME_TERRITORY_SCEI) (check-cheat-code (-> *cheat-temp* 2) 0 (l1 r1 l1 r1 triangle circle x square) - (cpad-clear-buttons! 0 r1) + (cpad-clear! 0 r1) (set! *progress-cheat* (if *progress-cheat* #f 'language @@ -397,7 +397,7 @@ (when *debug-segment* (check-cheat-code (-> *cheat-temp* 3) 0 (x square triangle circle x square triangle circle) - (cpad-clear-buttons! 0 r1) + (cpad-clear! 0 r1) (set! *progress-cheat* (if *progress-cheat* #f 'pal @@ -408,7 +408,7 @@ ;; added in PAL (check-cheat-code (-> *cheat-temp* 4) 0 ;; they erroneously used (-> *cheat-temp* 5) here! (triangle x circle square triangle x circle square) - (cpad-clear-buttons! 0 r1) + (cpad-clear! 0 r1) (set! *cheat-mode* (if (= *cheat-mode* 'camera) #f 'camera @@ -665,8 +665,9 @@ (*draw-hook*) (add-ee-profile-frame 'draw :g #x80) - (#when PC_PORT - (draw-build-revision)) + (with-pc + (if (-> *pc-settings* display-sha) + (draw-build-revision))) (*menu-hook*) (add-ee-profile-frame 'draw :g #x40) diff --git a/goal_src/engine/game/projectiles.gc b/goal_src/engine/game/projectiles.gc index 04f8047adb..08f3b2c129 100644 --- a/goal_src/engine/game/projectiles.gc +++ b/goal_src/engine/game/projectiles.gc @@ -1033,7 +1033,7 @@ (-> obj root-override shadow-pos) 8192.0 (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) 12288.0 81920.0 ) diff --git a/goal_src/engine/gfx/shadow/shadow-h.gc b/goal_src/engine/gfx/shadow/shadow-h.gc index 4a7fd20945..904cb49c30 100644 --- a/goal_src/engine/gfx/shadow/shadow-h.gc +++ b/goal_src/engine/gfx/shadow/shadow-h.gc @@ -5,10 +5,7 @@ ;; name in dgo: shadow-h ;; dgos: GAME, ENGINE -;; forward def - projectiles -(define-extern find-ground-and-draw-shadow (function vector vector float collide-kind process float float none)) -;; definition of type fake-shadow (deftype fake-shadow (structure) ((px float :offset-assert 0) (py float :offset-assert 4) @@ -25,7 +22,6 @@ :flag-assert #x900000020 ) -;; definition of type fake-shadow-buffer (deftype fake-shadow-buffer (basic) ((num-shadows int32 :offset-assert 4) (data fake-shadow 32 :inline :offset-assert 8) @@ -35,13 +31,10 @@ :flag-assert #x900000408 ) -;; definition for symbol *fake-shadow-buffer-1*, type fake-shadow-buffer (define *fake-shadow-buffer-1* (new 'global 'fake-shadow-buffer)) - -;; definition for symbol *fake-shadow-buffer-2*, type fake-shadow-buffer (define *fake-shadow-buffer-2* (new 'global 'fake-shadow-buffer)) - -;; definition for symbol *fake-shadow-buffer*, type fake-shadow-buffer (define *fake-shadow-buffer* *fake-shadow-buffer-1*) -(define-extern swap-fake-shadow-buffers (function none)) \ No newline at end of file +(define-extern swap-fake-shadow-buffers (function none)) + +(define-extern find-ground-and-draw-shadow (function vector vector float collide-kind process-drawable float float none)) \ No newline at end of file diff --git a/goal_src/engine/gfx/shadow/shadow.gc b/goal_src/engine/gfx/shadow/shadow.gc index 15f19eb4fb..11f21620da 100644 --- a/goal_src/engine/gfx/shadow/shadow.gc +++ b/goal_src/engine/gfx/shadow/shadow.gc @@ -109,14 +109,31 @@ ) ) -(defun find-ground-and-draw-shadow ((arg0 vector) (arg1 vector) (arg2 float) (arg3 collide-kind) (arg4 process) (arg5 float) (arg6 float)) +(defun find-ground-and-draw-shadow ((arg0 vector) + (arg1 vector) + (arg2 float) + (arg3 collide-kind) + (arg4 process-drawable) + (arg5 float) + (arg6 float) + ) (let ((s2-0 (new 'stack-no-clear 'vector))) (set! (-> s2-0 quad) (-> arg0 quad)) (new 'stack-no-clear 'vector) (+! (-> s2-0 y) arg5) (let ((s4-0 (new 'stack-no-clear 'collide-tri-result))) (cond - ((>= (fill-and-probe-using-y-probe *collide-cache* s2-0 arg6 arg3 arg4 s4-0 (the-as uint 1)) 0.0) + ((>= (fill-and-probe-using-y-probe + *collide-cache* + s2-0 + arg6 + arg3 + arg4 + s4-0 + (new 'static 'pat-surface :noentity #x1) + ) + 0.0 + ) (if (!= arg2 0.0) (compute-and-draw-shadow s2-0 (-> s4-0 intersect) (-> s4-0 normal) (the-as vector arg2) arg6 (the-as float 0)) ) diff --git a/goal_src/engine/gfx/sprite/sprite.gc b/goal_src/engine/gfx/sprite/sprite.gc index 11efc89472..434ad6280c 100644 --- a/goal_src/engine/gfx/sprite/sprite.gc +++ b/goal_src/engine/gfx/sprite/sprite.gc @@ -394,10 +394,8 @@ (defmethod new sprite-array-2d ((allocation symbol) (type-to-make type) (group-0-size int) (group-1-size int)) "Allocate a sprite-array for 2d sprites. There are two groups, each can contain the given number." (#when PC_BIG_MEMORY - (when (not (-> *pc-settings* ps2-parts?)) - (*! group-0-size 16) ;; 16x more particles! - (*! group-1-size 16) ;; 16x more particles! - ) + (*! group-0-size 16) ;; 16x more particles! + (*! group-1-size 16) ;; 16x more particles! ) (let* ((sprite-count (+ group-0-size group-1-size)) (vec-data-size (* 3 sprite-count)) ;; 3 quadwords of vec-data per sprite @@ -423,10 +421,8 @@ "Allocate a sprite-array for 3d sprites. There are two groups, each can contain the given number of sprites. Group 1 size is zero in practice for 3d." (#when PC_BIG_MEMORY - (when (and *pc-settings* (not (-> *pc-settings* ps2-parts?))) - (*! group-0-size 16) ;; 16x more particles! - (*! group-1-size 16) ;; 16x more particles! - ) + (*! group-0-size 16) ;; 16x more particles! + (*! group-1-size 16) ;; 16x more particles! ) (let* ((sprite-count (+ group-0-size group-1-size)) (vec-data-size (* 3 sprite-count)) diff --git a/goal_src/engine/nav/navigate-h.gc b/goal_src/engine/nav/navigate-h.gc index 809114854a..bd22c7f6e1 100644 --- a/goal_src/engine/nav/navigate-h.gc +++ b/goal_src/engine/nav/navigate-h.gc @@ -13,24 +13,24 @@ :bitfield #t :type uint32 (display-marks 0) - (bit1 1) ;; TODO - nav-control::9 - (bit2 2) ;; TODO - nav-control::9 - (bit3 3) ;; TODO - nav-enemy::45 | nav-control::9 - (bit4 4) ;; TODO - nav-control::9 - (bit5 5) ;; TODO - nav-enemy::45 | ;; TODO - nav-control::9 - (bit6 6) ;; TODO - nav-enemy::45 | ;; TODO - nav-control::9 - (bit7 7) ;; TODO - nav-enemy::45 | ;; TODO - nav-control::9 - (bit8 8) - (bit9 9) ;; TODO - nav-control::14 | 11 - (bit10 10) ;; TODO - nav-enemy::nav-enemy-patrol-post - (bit11 11) ;; TODO - nav-control::28 - (bit12 12) ;; TODO - rolling-lightning-mole::(enter nav-enemy-chase fleeing-nav-enemy) - (bit13 13) - (bit17 17) ;; TODO - nav-control::11 - (bit18 18) ;; TODO - nav-control::11 - (bit19 19) ;; TODO - nav-control::11 | 17 - (bit20 20) ;; TODO - nav-mesh::28 - (bit21 21) ;; TODO - nav-control::19 + (navcf1 1) ;; TODO - nav-control::9 + (navcf2 2) ;; TODO - nav-control::9 + (navcf3 3) ;; TODO - nav-enemy::45 | nav-control::9 + (navcf4 4) ;; TODO - nav-control::9 + (navcf5 5) ;; TODO - nav-enemy::45 | ;; TODO - nav-control::9 + (navcf6 6) ;; TODO - nav-enemy::45 | ;; TODO - nav-control::9 + (navcf7 7) ;; TODO - nav-enemy::45 | ;; TODO - nav-control::9 + (navcf8 8) + (navcf9 9) ;; TODO - nav-control::14 | 11 + (navcf10 10) ;; TODO - nav-enemy::nav-enemy-patrol-post + (navcf11 11) ;; TODO - nav-control::28 + (navcf12 12) ;; TODO - rolling-lightning-mole::(enter nav-enemy-chase fleeing-nav-enemy) + (navcf13 13) + (navcf17 17) ;; TODO - nav-control::11 + (navcf18 18) ;; TODO - nav-control::11 + (navcf19 19) ;; TODO - nav-control::11 | 17 + (navcf20 20) ;; TODO - nav-mesh::28 + (navcf21 21) ;; TODO - nav-control::19 ) (deftype nav-poly (structure) @@ -371,7 +371,7 @@ (goto cfg-4) ) (set! (-> obj max-spheres) sphere-count) - (set! (-> obj flags) (nav-control-flags bit8 bit13)) + (set! (-> obj flags) (nav-control-flags navcf8 navcf13)) (set! (-> obj mesh) (nav-mesh-connect (-> shape process) shape obj)) (let ((ent (-> shape process entity))) (set! (-> obj nearest-y-threshold) diff --git a/goal_src/engine/nav/navigate.gc b/goal_src/engine/nav/navigate.gc index 679f9e3e0b..f6ad510afd 100644 --- a/goal_src/engine/nav/navigate.gc +++ b/goal_src/engine/nav/navigate.gc @@ -1177,14 +1177,14 @@ (let ((v1-1 (find-poly-fast obj arg0 arg1))) (when v1-1 (if arg2 - (set! (-> arg2 0) (logior (nav-control-flags bit20) (-> arg2 0))) + (set! (-> arg2 0) (logior (nav-control-flags navcf20) (-> arg2 0))) ) (set! s3-1 v1-1) (goto cfg-14) ) ) (if arg2 - (logclear! (-> arg2 0) (nav-control-flags bit20)) + (logclear! (-> arg2 0) (nav-control-flags navcf20)) ) (let ((s2-0 (new 'stack-no-clear 'inline-array 'nav-vertex 3))) (set! s3-1 (the-as nav-poly #f)) @@ -1632,7 +1632,7 @@ (when #t (set! (-> s5-0 debug-time) (the-as uint (-> *display* actual-frame-counter))) (add-debug-sphere - (logtest? (-> obj flags) (nav-control-flags bit1)) + (logtest? (-> obj flags) (nav-control-flags navcf1)) (bucket-id debug-draw0) (-> s5-0 bounds) (-> s5-0 bounds w) @@ -1640,7 +1640,7 @@ ) (add-debug-vector #t (bucket-id debug-draw1) (-> s5-0 origin) *x-vector* (meters 1.0) *color-red*) (add-debug-vector #t (bucket-id debug-draw1) (-> s5-0 origin) *z-vector* (meters 1.0) *color-blue*) - (when (logtest? (-> obj flags) (nav-control-flags bit2)) + (when (logtest? (-> obj flags) (nav-control-flags navcf2)) (dotimes (s3-0 (-> s5-0 vertex-count)) (add-debug-x #t @@ -1695,7 +1695,7 @@ ) ) ) - (when (logtest? (-> obj flags) (nav-control-flags bit3)) + (when (logtest? (-> obj flags) (nav-control-flags navcf3)) (dotimes (s3-2 (-> s5-0 poly-count)) (let ((s2-1 (-> s5-0 poly s3-2))) (debug-draw-poly s5-0 s2-1 (the-as rgba (cond @@ -1720,7 +1720,7 @@ ) ) ) - (when (logtest? (-> obj flags) (nav-control-flags bit4)) + (when (logtest? (-> obj flags) (nav-control-flags navcf4)) (let ((s1-1 add-debug-text-3d) (s0-1 #t) ) @@ -1744,7 +1744,7 @@ ) ) ) - (when (logtest? (-> obj flags) (nav-control-flags bit5)) + (when (logtest? (-> obj flags) (nav-control-flags navcf5)) (if (-> obj next-poly) (debug-draw-poly s5-0 (-> obj next-poly) *color-cyan*) ) @@ -1755,7 +1755,7 @@ (debug-draw-poly s5-0 (-> obj current-poly) *color-red*) ) ) - (when (logtest? (-> obj flags) (nav-control-flags bit7)) + (when (logtest? (-> obj flags) (nav-control-flags navcf7)) (dotimes (s3-3 (the-as int (-> s5-0 static-sphere-count))) (let ((s2-2 (-> s5-0 static-sphere s3-3))) (add-debug-sphere #t (bucket-id debug-draw0) (the-as vector s2-2) (-> s2-2 trans w) *color-blue*) @@ -1788,7 +1788,7 @@ ) ) ) - (when (logtest? (-> obj flags) (nav-control-flags bit6)) + (when (logtest? (-> obj flags) (nav-control-flags navcf6)) (when (and (-> obj portal 0) (-> obj portal 1)) (let ((v1-80 (-> s5-0 origin)) (a2-22 (new 'stack-no-clear 'vector)) @@ -1828,7 +1828,7 @@ (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) ) ) - (when (logtest? (-> obj flags) (nav-control-flags bit7)) + (when (logtest? (-> obj flags) (nav-control-flags navcf7)) (add-debug-sphere #t (bucket-id debug-draw1) @@ -1890,7 +1890,7 @@ (defmethod set-current-poly! nav-control ((obj nav-control) (arg0 nav-poly)) (set! (-> obj current-poly) arg0) - (logior! (-> obj flags) (nav-control-flags bit9)) + (logior! (-> obj flags) (nav-control-flags navcf9)) 0 (none) ) @@ -1937,7 +1937,7 @@ ) (defun add-collide-shape-spheres ((arg0 nav-control) (arg1 collide-shape) (arg2 vector)) - (when (logtest? (-> arg1 nav-flags) 1) + (when (logtest? (-> arg1 nav-flags) (nav-flags navf0)) (set! (-> arg2 quad) (-> arg1 root-prim prim-core world-sphere quad)) (set! (-> arg2 w) (-> arg1 nav-radius)) (let ((s4-0 arg0) @@ -1959,7 +1959,7 @@ ) 0 ) - (when (logtest? (-> arg1 nav-flags) 2) + (when (logtest? (-> arg1 nav-flags) (nav-flags navf1)) (let ((s5-1 (-> arg1 process nav extra-nav-sphere))) (when (< (-> arg0 num-spheres) (-> arg0 max-spheres)) (let* ((s4-1 (-> arg0 sphere (-> arg0 num-spheres))) @@ -1995,13 +1995,13 @@ (s3-0 (new 'stack-no-clear 'vector)) ) (when (and *target* - (or (logtest? (-> obj flags) (nav-control-flags bit11)) (logtest? (-> *target* state-flags) #x80f8)) + (or (logtest? (-> obj flags) (nav-control-flags navcf11)) (logtest? (-> *target* state-flags) #x80f8)) ) (let ((s2-0 obj) (s1-0 (-> *target* control)) ) (let ((s0-0 s3-0)) - (when (logtest? (-> s1-0 nav-flags) 1) + (when (logtest? (-> s1-0 nav-flags) (nav-flags navf0)) (set! (-> s0-0 quad) (-> s1-0 root-prim prim-core world-sphere quad)) (set! (-> s0-0 w) (-> s1-0 nav-radius)) (set! sv-32 s2-0) @@ -2021,7 +2021,7 @@ 0 ) ) - (when (logtest? (-> s1-0 nav-flags) 2) + (when (logtest? (-> s1-0 nav-flags) (nav-flags navf1)) (let ((s1-1 (-> s1-0 process nav extra-nav-sphere))) (when (< (-> s2-0 num-spheres) (-> s2-0 max-spheres)) (let* ((s0-1 (-> s2-0 sphere (-> s2-0 num-spheres))) @@ -2041,7 +2041,7 @@ ) ) ) - (when (logtest? (-> obj flags) (nav-control-flags bit13)) + (when (logtest? (-> obj flags) (nav-control-flags navcf13)) (countdown (s2-1 (-> obj mesh static-sphere-count)) (let ((s1-2 obj) (s0-2 (-> obj mesh static-sphere s2-1)) @@ -2071,7 +2071,7 @@ (when (not (or (= s0-3 (-> obj shape)) (zero? (logand arg0 (-> s0-3 root-prim prim-core collide-as))))) (let ((s1-3 obj)) (set! sv-112 s3-0) - (when (logtest? (-> s0-3 nav-flags) 1) + (when (logtest? (-> s0-3 nav-flags) (nav-flags navf0)) (set! (-> sv-112 quad) (-> s0-3 root-prim prim-core world-sphere quad)) (set! (-> sv-112 w) (-> s0-3 nav-radius)) (set! sv-80 s1-3) @@ -2094,7 +2094,7 @@ ) 0 ) - (when (logtest? (-> s0-3 nav-flags) 2) + (when (logtest? (-> s0-3 nav-flags) (nav-flags navf1)) (let ((s0-4 (-> s0-3 process nav extra-nav-sphere))) (when (< (-> s1-3 num-spheres) (-> s1-3 max-spheres)) (set! sv-128 (-> s1-3 sphere (-> s1-3 num-spheres))) @@ -2466,7 +2466,7 @@ (set! (-> obj blocked-travel quad) (-> obj travel quad)) (let ((f0-0 (vector-xz-length (-> obj travel)))) (when (and (>= f30-0 f0-0) (< f0-0 204.8)) - (set! (-> obj flags) (logior (nav-control-flags bit17) (-> obj flags))) + (set! (-> obj flags) (logior (nav-control-flags navcf17) (-> obj flags))) (set! (-> obj block-time) (-> *display* base-frame-counter)) (set! (-> obj block-count) (+ 1.0 (-> obj block-count))) (if (-> obj block-event) @@ -2504,21 +2504,21 @@ ) (cond ((or (vector= arg2 (-> obj target-pos)) (< (fabs f28-0) 364.0889)) - (set! (-> obj flags) (logior (nav-control-flags bit21) (-> obj flags))) + (set! (-> obj flags) (logior (nav-control-flags navcf21) (-> obj flags))) (set! (-> arg0 quad) (-> arg2 quad)) ) (else (let ((s2-1 (vector-z-quaternion! (new 'stack-no-clear 'vector) (-> arg1 quat)))) (vector-rotate-y! s2-1 s2-1 (fmax (fmin f28-0 f30-0) (- f30-0))) (vector-normalize! s2-1 819.2) - (logclear! (-> obj flags) (nav-control-flags bit21)) + (logclear! (-> obj flags) (nav-control-flags navcf21)) (vector+! arg0 (-> arg1 trans) s2-1) ) (when (or (not (dummy-16 obj arg0)) - (logtest? (nav-control-flags bit17) (-> obj flags)) - (zero? (logand (-> obj flags) (nav-control-flags bit10))) + (logtest? (nav-control-flags navcf17) (-> obj flags)) + (zero? (logand (-> obj flags) (nav-control-flags navcf10))) ) - (set! (-> obj flags) (logior (nav-control-flags bit21) (-> obj flags))) + (set! (-> obj flags) (logior (nav-control-flags navcf21) (-> obj flags))) (vector-! (-> obj travel) arg2 (-> arg1 trans)) (set! (-> arg0 quad) (-> arg2 quad)) ) @@ -2718,7 +2718,7 @@ v1-0 (-> obj current-poly) (-> obj travel) - (zero? (logand (-> obj flags) (nav-control-flags bit12))) + (zero? (logand (-> obj flags) (nav-control-flags navcf12))) arg0 arg1 ) @@ -2925,7 +2925,7 @@ sv-84 sv-88 (-> obj travel) - (zero? (logand (-> obj flags) (nav-control-flags bit12))) + (zero? (logand (-> obj flags) (nav-control-flags navcf12))) 204.8 s5-1 ) @@ -2966,9 +2966,9 @@ (set! (-> obj old-travel quad) (-> obj travel quad)) (-> obj block-count) (set! (-> obj block-count) (seek (-> obj block-count) 0.0 0.016666668)) - (logclear! (-> obj flags) (nav-control-flags bit9 bit17 bit18 bit19)) + (logclear! (-> obj flags) (nav-control-flags navcf9 navcf17 navcf18 navcf19)) (TODO-RENAME-27 obj) - (if (logtest? (-> obj flags) (nav-control-flags bit8)) + (if (logtest? (-> obj flags) (nav-control-flags navcf8)) (TODO-RENAME-28 obj (collide-kind background cak-1 @@ -3043,7 +3043,7 @@ (let ((s5-1 (new 'stack-no-clear 'nav-gap-info))) (when (< (vector-xz-length (-> obj travel)) 204.8) (cond - ((logtest? (nav-control-flags bit17) (-> obj flags)) + ((logtest? (nav-control-flags navcf17) (-> obj flags)) ) ((-> obj next-poly) (cond @@ -3061,7 +3061,7 @@ ) ) (else - (set! (-> obj flags) (logior (nav-control-flags bit19) (-> obj flags))) + (set! (-> obj flags) (logior (nav-control-flags navcf19) (-> obj flags))) ) ) ) diff --git a/goal_src/engine/ps2/pad.gc b/goal_src/engine/ps2/pad.gc index 245c8294b4..2a9ad56298 100644 --- a/goal_src/engine/ps2/pad.gc +++ b/goal_src/engine/ps2/pad.gc @@ -359,7 +359,7 @@ `(logtest? (cpad-hold ,pad-idx) (pad-buttons ,@buttons)) ) -(defmacro cpad-clear-buttons! (pad-idx &rest buttons) +(defmacro cpad-clear! (pad-idx &rest buttons) `(begin (logclear! (cpad-pressed ,pad-idx) (pad-buttons ,@buttons)) (logclear! (cpad-hold ,pad-idx) (pad-buttons ,@buttons)) diff --git a/goal_src/engine/sparticle/sparticle-launcher.gc b/goal_src/engine/sparticle/sparticle-launcher.gc index 6435ed20d2..5edfd7139a 100644 --- a/goal_src/engine/sparticle/sparticle-launcher.gc +++ b/goal_src/engine/sparticle/sparticle-launcher.gc @@ -935,10 +935,10 @@ ;; can we see it? (#if (not PC_PORT) (sphere-in-view-frustum? (the-as sphere gp-1)) - (if (and (not (-> *pc-settings* ps2-parts?)) (not (-> *pc-settings* use-vis?)) (> (-> *sprite-array-2d* num-sprites 0) 1920)) - ;; pc port : launchers have larger bsphere if you have pc rendering on and ps2 parts off - (sphere-in-view-frustum? (the-as sphere (let ((bsph (new-stack-vector0))) (vector-copy! bsph gp-1) (*! (-> bsph w) 4.0) bsph))) - (sphere-in-view-frustum? (the-as sphere gp-1))) + (if (-> *pc-settings* ps2-parts?) + ;; pc port : launchers have larger bsphere if you have ps2 parts off + (sphere-in-view-frustum? (the-as sphere gp-1)) + (sphere-in-view-frustum? (the-as sphere (let ((bsph (new-stack-vector0))) (vector-copy! bsph gp-1) (*! (-> bsph w) 4.0) bsph)))) ) ) ) @@ -992,7 +992,7 @@ ;; pc hack for more particles. (with-pc - (if (and (> (-> *sprite-array-2d* num-sprites 0) 1920) (not (-> *pc-settings* ps2-parts?))) + (if (not (-> *pc-settings* ps2-parts?)) (/! f30-0 256.0))) ;; loop over particles in the group. diff --git a/goal_src/engine/sparticle/sparticle.gc b/goal_src/engine/sparticle/sparticle.gc index 78e6e84eb3..0265b8f302 100644 --- a/goal_src/engine/sparticle/sparticle.gc +++ b/goal_src/engine/sparticle/sparticle.gc @@ -63,10 +63,8 @@ arg3: pointer to sprite allocations arg4: pointer to adgif allocation" (#when PC_BIG_MEMORY - (when (not (-> *pc-settings* ps2-parts?)) - (*! arg0 16) ;; 16x more particles! - (*! arg1 16) ;; 16x more particles! - ) + (*! arg0 16) ;; 16x more particles! + (*! arg1 16) ;; 16x more particles! ) (let ((gp-0 (object-new allocation type-to-make (the-as int (-> type-to-make size))))) (let* ((v1-3 (/ (+ arg0 63) 64)) ;; num blocks diff --git a/goal_src/engine/target/target-death.gc b/goal_src/engine/target/target-death.gc index 486cebaf97..80548d12de 100644 --- a/goal_src/engine/target/target-death.gc +++ b/goal_src/engine/target/target-death.gc @@ -1202,7 +1202,7 @@ (clear-pending-settings-from-process *setting-control* self 'process-mask) (clear-pending-settings-from-process *setting-control* self 'allow-progress) (restore-collide-with-as (-> self control)) - (set! (-> self control pat-ignore-mask) (new 'static 'pat-surface :skip #x1 :noentity #x1)) + (set! (-> self control pat-ignore-mask) (new 'static 'pat-surface :noentity #x1)) (set! (-> self control dynam gravity-max) (-> self control unknown-dynamics00 gravity-max)) (set! (-> self control dynam gravity-length) (-> self control unknown-dynamics00 gravity-length)) (none) diff --git a/goal_src/engine/target/target-part.gc b/goal_src/engine/target/target-part.gc index c5126df955..13917373d5 100644 --- a/goal_src/engine/target/target-part.gc +++ b/goal_src/engine/target/target-part.gc @@ -43,7 +43,7 @@ (collide-kind background cak-1 cak-2 cak-3 water powerup crate enemy wall-object ground-object mother-spider) s5-0 s3-0 - (the-as uint 1) + (new 'static 'pat-surface :noentity #x1) ) 0.0 ) diff --git a/goal_src/engine/ui/progress-h.gc b/goal_src/engine/ui/progress-h.gc index 555baa45cb..ff111dc071 100644 --- a/goal_src/engine/ui/progress-h.gc +++ b/goal_src/engine/ui/progress-h.gc @@ -5,68 +5,163 @@ ;; name in dgo: progress-h ;; dgos: GAME, ENGINE +;; PC port adds new menus and option types +(#cond + ((not PC_PORT) + (defenum progress-screen + :type int64 + (invalid -1) + (fuel-cell 0) + (money 1) + (buzzer 2) + (settings 3) + (game-settings 4) + (graphic-settings 5) + (sound-settings 6) + (memcard-no-space 7) + (memcard-not-inserted 8) + (memcard-not-formatted 9) + (memcard-format 10) + (memcard-data-exists 11) + (memcard-loading 12) + (memcard-saving 13) + (memcard-formatting 14) + (memcard-creating 15) + (load-game 16) + (save-game 17) + (save-game-title 18) + (memcard-insert 19) + (memcard-error-loading 20) + (memcard-error-saving 21) + (memcard-removed 22) + (memcard-no-data 23) + (memcard-error-formatting 24) + (memcard-error-creating 25) + (memcard-auto-save-error 26) + (title 27) + (settings-title 28) + (auto-save 29) + (pal-change-to-60hz 30) + (pal-now-60hz 31) + (no-disc 32) + (bad-disc 33) + (quit 34) + (max 35) + ) -(defenum progress-screen - :type int64 - (invalid -1) - (fuel-cell 0) - (money 1) - (buzzer 2) - (settings 3) - (game-settings 4) - (graphic-settings 5) - (sound-settings 6) - (memcard-no-space 7) - (memcard-not-inserted 8) - (memcard-not-formatted 9) - (memcard-format 10) - (memcard-data-exists 11) - (memcard-loading 12) - (memcard-saving 13) - (memcard-formatting 14) - (memcard-creating 15) - (load-game 16) - (save-game 17) - (save-game-title 18) - (memcard-insert 19) - (memcard-error-loading 20) - (memcard-error-saving 21) - (memcard-removed 22) - (memcard-no-data 23) - (memcard-error-formatting 24) - (memcard-error-creating 25) - (memcard-auto-save-error 26) - (title 27) - (settings-title 28) - (auto-save 29) - (pal-change-to-60hz 30) - (pal-now-60hz 31) - (no-disc 32) - (bad-disc 33) - (quit 34) + (defenum game-option-type + :type uint64 + (slider 0) + (language 1) + (on-off 2) + (center-screen 3) + (aspect-ratio 4) + (video-mode 5) + (menu 6) + (yes-no 7) + (button 8) + ) + ) + (#t + (defenum progress-screen + :type int64 + (invalid -1) + (fuel-cell 0) + (money 1) + (buzzer 2) + (settings 3) + (game-settings 4) + (graphic-settings 5) + (sound-settings 6) + (memcard-no-space 7) + (memcard-not-inserted 8) + (memcard-not-formatted 9) + (memcard-format 10) + (memcard-data-exists 11) + (memcard-loading 12) + (memcard-saving 13) + (memcard-formatting 14) + (memcard-creating 15) + (load-game 16) + (save-game 17) + (save-game-title 18) + (memcard-insert 19) + (memcard-error-loading 20) + (memcard-error-saving 21) + (memcard-removed 22) + (memcard-no-data 23) + (memcard-error-formatting 24) + (memcard-error-creating 25) + (memcard-auto-save-error 26) + (title 27) + (settings-title 28) + (auto-save 29) + (pal-change-to-60hz 30) + (pal-now-60hz 31) + (no-disc 32) + (bad-disc 33) + (quit 34) + + ;; extra screens for pc port + (camera-options) + (accessibility-options) + (game-ps2-options) + (misc-options) + (resolution) + (aspect-msg) + (aspect-ratio) + (gfx-ps2-options) + (secrets) + (hint-log) + (cheats) + (scrapbook) + (music-player) + (scene-player) + (credits) + + ;; the last one! + (max) + ) + + (defenum game-option-type + :type uint64 + (slider 0) + (language 1) + (on-off 2) + (center-screen 3) + (aspect-ratio 4) + (video-mode 5) + (menu 6) + (yes-no 7) + (button 8) + + ;; extra types for pc port + (normal-inverted) + (display-mode) + (msaa) + (frame-rate) + (lod-bg) + (lod-fg) + (resolution) + (aspect-new) + (language-subtitles) + (speaker) + (aspect-native) + ) + ) ) +(defenum game-option-menu + :type int32 + :copy-entries progress-screen) + (defun-extern activate-progress process progress-screen none) (defun-extern hide-progress-screen none) (defun-extern hide-progress-icons none) -(declare-type level-tasks-info basic) - -(define-extern *level-task-data* (array level-tasks-info)) -(define-extern *level-task-data-remap* (array int32)) - -(declare-type count-info structure) - -(defun-extern get-game-count int count-info) (defun-extern progress-allowed? symbol) (defun-extern pause-allowed? symbol) -(declare-type progress process) - -(defun-extern deactivate-progress none) -(defun-extern calculate-completion progress float) -(defun-extern make-current-level-available-to-progress none) - ;; DECOMP BEGINS (deftype count-info (structure) @@ -115,13 +210,13 @@ (deftype game-option (basic) - ((option-type uint64 :offset-assert 8) - (name game-text-id :offset-assert 16) - (scale basic :offset-assert 20) - (param1 float :offset-assert 24) - (param2 float :offset-assert 28) - (param3 int32 :offset-assert 32) - (value-to-modify pointer :offset-assert 36) + ((option-type game-option-type :offset-assert 8) + (name game-text-id :offset-assert 16) + (scale symbol :offset-assert 20) + (param1 float :offset-assert 24) + (param2 float :offset-assert 28) + (param3 game-option-menu :offset-assert 32) + (value-to-modify pointer :offset-assert 36) ) :method-count-assert 9 :size-assert #x28 @@ -148,8 +243,8 @@ (force-transition basic :offset-assert 180) (stat-transition basic :offset-assert 184) (level-transition int32 :offset-assert 188) - (language-selection uint64 :offset-assert 192) - (language-direction basic :offset-assert 200) + (language-selection language-enum :offset-assert 192) + (language-direction symbol :offset-assert 200) (language-transition basic :offset-assert 204) (language-x-offset int32 :offset-assert 208) (sides-x-scale float :offset-assert 212) @@ -190,12 +285,12 @@ :size-assert #x2dc :flag-assert #x3b027002dc (:methods - (dummy-14 (_type_) none 14) - (dummy-15 (_type_) none 15) - (dummy-16 (_type_) none 16) + (progress-dummy-14 (_type_) none 14) ;; unused + (progress-dummy-15 (_type_) none 15) ;; unused + (progress-dummy-16 (_type_) none 16) ;; unused (draw-progress (_type_) none 17) - (dummy-18 () none 18) - (dummy-19 (_type_) symbol 19) + (progress-dummy-18 () none 18) ;; unused + (visible? (_type_) symbol 19) (hidden? (_type_) symbol 20) (adjust-sprites (_type_) none 21) (adjust-icons (_type_) none 22) @@ -205,10 +300,10 @@ (draw-buzzer-screen (_type_ int) none 26) (draw-notice-screen (_type_) none 27) (draw-options (_type_ int int float) none 28) - (dummy-29 (_type_) none 29) + (respond-common (_type_) none 29) (respond-progress (_type_) none 30) - (dummy-31 (_type_) none 31) - (dummy-32 (_type_) symbol 32) + (respond-memcard (_type_) none 31) + (can-go-back? (_type_) symbol 32) (initialize-icons (_type_) none 33) (initialize-particles (_type_) none 34) (draw-memcard-storage-error (_type_ font-context) none 35) @@ -220,16 +315,16 @@ (draw-memcard-auto-save-error (_type_ font-context) none 41) (draw-memcard-removed (_type_ font-context) none 42) (draw-memcard-error (_type_ font-context) none 43) - (dummy-44 (_type_) none 44) + (progress-dummy-44 (_type_) none 44) ;; unused (push! (_type_) none 45) (pop! (_type_) none 46) - (dummy-47 (_type_) none 47) + (progress-dummy-47 (_type_) none 47) ;; unused (enter! (_type_ progress-screen int) none 48) (draw-memcard-format (_type_ font-context) none 49) (draw-auto-save (_type_ font-context) none 50) (set-transition-progress! (_type_ int) none 51) (set-transition-speed! (_type_) none 52) - (dummy-53 (_type_ progress-screen) progress-screen 53) + (set-memcard-screen (_type_ progress-screen) progress-screen 53) (draw-pal-change-to-60hz (_type_ font-context) none 54) (draw-pal-now-60hz (_type_ font-context) none 55) (draw-no-disc (_type_ font-context) none 56) @@ -251,7 +346,15 @@ (define *progress-last-task-index* 0) -0 + +(defun-extern get-game-count int count-info) + +(define-extern *level-task-data* (array level-tasks-info)) +(define-extern *level-task-data-remap* (array int32)) + +(defun-extern deactivate-progress none) +(defun-extern calculate-completion progress float) +(defun-extern make-current-level-available-to-progress none) diff --git a/goal_src/engine/ui/progress/progress-draw.gc b/goal_src/engine/ui/progress/progress-draw.gc index 8235f15f56..16cd6833b3 100644 --- a/goal_src/engine/ui/progress/progress-draw.gc +++ b/goal_src/engine/ui/progress/progress-draw.gc @@ -1510,432 +1510,207 @@ ) (defmethod draw-options progress ((obj progress) (arg0 int) (arg1 int) (arg2 float)) - (local-vars - (sv-112 font-context) - (sv-128 int) - (sv-144 int) - (sv-160 (function _varargs_ object)) - (sv-176 string) - (sv-192 string) - (sv-208 string) - (sv-224 (function _varargs_ object)) - (sv-240 string) - (sv-256 string) - (sv-272 string) - (sv-288 (function string font-context symbol int int float)) - (sv-304 (function _varargs_ object)) - (sv-320 (function _varargs_ object)) - (sv-336 string) - (sv-352 string) - (sv-368 string) - (sv-384 (function _varargs_ object)) - (sv-400 string) - (sv-416 string) - (sv-432 string) - (sv-448 uint) - (sv-464 int) - (sv-480 int) - (sv-496 int) - (sv-512 uint) - (sv-528 (function _varargs_ object)) - (sv-544 string) - (sv-560 string) - (sv-576 string) - (sv-592 (function _varargs_ object)) - (sv-608 string) - (sv-624 string) - (sv-640 string) - (sv-656 (function _varargs_ object)) - (sv-672 string) - (sv-688 string) - (sv-704 string) - (sv-720 (function _varargs_ object)) - (sv-736 string) - (sv-752 string) - (sv-768 string) - (sv-784 (function _varargs_ object)) - (sv-800 string) - (sv-816 string) - (sv-832 string) - (sv-848 (function _varargs_ object)) - (sv-864 string) - (sv-880 string) - (sv-896 string) - (sv-912 string) - ) (let ((s3-0 (-> *options-remap* (-> obj display-state)))) (when s3-0 (let ((s2-1 (- arg0 (/ (* arg1 (length s3-0)) 2))) (s1-0 0) + (unkx 27) + (unk2 0) + (font (new 'stack 'font-context *font-default-matrix* 0 0 0.0 (font-color default) (font-flags shadow kerning))) ) - 27 - 0 - (set! sv-112 - (new 'stack 'font-context *font-default-matrix* 0 0 0.0 (font-color default) (font-flags shadow kerning)) - ) - (let ((v1-11 sv-112)) - (set! (-> v1-11 width) (the float 350)) - ) - (let ((v1-12 sv-112)) - (set! (-> v1-12 height) (the float 25)) - ) - (set! (-> sv-112 flags) (font-flags shadow kerning middle left large)) + (set-width! font 350) + (set-height! font 25) + (set! (-> font flags) (font-flags shadow kerning middle left large)) (dotimes (s0-0 (length s3-0)) - (set! sv-912 (the-as string #f)) - (set! sv-128 27) - (set! sv-144 s2-1) + (let ((option-str (the string #f)) + (x-off 27) + (y-off s2-1) + ) (let ((v1-18 (-> s3-0 s0-0 option-type))) (cond - ((= v1-18 7) - (cond - ((-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) - (set! sv-160 format) - (set! sv-176 (clear *temp-string*)) - (set! sv-192 "~30L~S~0L ~S") - (set! sv-208 (lookup-text! *common-text* (game-text-id yes) #f)) - (let ((a3-2 (lookup-text! *common-text* (game-text-id no) #f))) - (sv-160 sv-176 sv-192 sv-208 a3-2) - ) - (set! sv-912 *temp-string*) - sv-912 - ) - (else - (set! sv-224 format) - (set! sv-240 (clear *temp-string*)) - (set! sv-256 "~0L~S ~30L~S~1L") - (set! sv-272 (lookup-text! *common-text* (game-text-id yes) #f)) - (let ((a3-3 (lookup-text! *common-text* (game-text-id no) #f))) - (sv-224 sv-240 sv-256 sv-272 a3-3) - ) - (set! sv-912 *temp-string*) - sv-912 + ((= v1-18 (game-option-type yes-no)) + (if (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) + (set! option-str (string-format "~30L~S~0L ~S" (lookup-text! *common-text* (game-text-id yes) #f) (lookup-text! *common-text* (game-text-id no) #f))) + (set! option-str (string-format "~0L~S ~30L~S~1L" (lookup-text! *common-text* (game-text-id yes) #f) (lookup-text! *common-text* (game-text-id no) #f))) ) - ) ) - ((or (= v1-18 6) (= v1-18 8)) + ((or (= v1-18 (game-option-type menu)) (= v1-18 (game-option-type button))) (cond ((nonzero? (-> s3-0 s0-0 name)) - (set! sv-912 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) - sv-912 + (set! option-str (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) ) (else - (set! sv-912 (the-as string #f)) - (the-as symbol sv-912) + (set! option-str (the-as string #f)) ) ) ) ((and (-> obj selected-option) (= (-> obj option-index) s0-0)) - (let ((a0-19 sv-112)) - (set! (-> a0-19 color) (font-color default)) - ) - (set! (-> sv-112 origin x) (the float (- sv-128 (-> obj left-x-offset)))) + (set-color! font (font-color default)) + (set! (-> font origin x) (the float (- x-off (-> obj left-x-offset)))) (case (-> s3-0 s0-0 option-type) - ((3) - (set! (-> sv-112 origin y) (the float (+ s2-1 -20))) + (((game-option-type center-screen)) + (set! (-> font origin y) (the float (+ s2-1 -20))) ) (else - (set! (-> sv-112 origin y) (the float (+ s2-1 -8))) + (set! (-> font origin y) (the float (+ s2-1 -8))) ) ) - (let ((v1-64 sv-112)) - (set! (-> v1-64 scale) 0.6) - ) - (set! sv-288 print-game-text) - (let ((a0-23 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) - (a1-11 sv-112) - (a2-10 #f) - (a3-4 128) - (t0-1 22) - ) - (sv-288 a0-23 a1-11 a2-10 a3-4 t0-1) - ) + (set-scale! font 0.6) + (print-game-text (lookup-text! *common-text* (-> s3-0 s0-0 name) #f) font #f 128 22) (case (-> s3-0 s0-0 option-type) - ((3) - (set! sv-144 (+ s2-1 3)) - sv-144 + (((game-option-type center-screen)) + (set! y-off (+ s2-1 3)) ) (else - (set! sv-144 (+ s2-1 7)) - sv-144 + (set! y-off (+ s2-1 7)) ) ) - (let ((v1-81 (-> s3-0 s0-0 option-type))) - (cond - ((zero? v1-81) - (let* ((v1-82 (the-as uint #x8000ffff)) - (f0-12 (* 0.01 (-> (the-as (pointer float) (-> s3-0 s0-0 value-to-modify))))) - (a0-34 (logior (logand v1-82 -256) (shr (shl (the int (+ 64.0 (* 191.0 f0-12))) 56) 56))) - (a3-5 (logior (logand a0-34 -65281) (shr (shl (shr (shl a0-34 56) 56) 56) 48))) - ) - (draw-percent-bar (- 75 (-> obj left-x-offset)) (+ s2-1 8) f0-12 (the-as int a3-5)) - ) - (set! sv-304 format) - (let ((a0-42 (clear *temp-string*)) - (a1-13 "~D") - (a2-12 (the int (-> (the-as (pointer float) (-> s3-0 s0-0 value-to-modify))))) - ) - (sv-304 a0-42 a1-13 a2-12) - ) - (set! sv-912 *temp-string*) - (set! sv-128 (+ (the int (* 2.5 (-> (the-as (pointer float) (-> s3-0 s0-0 value-to-modify))))) -100)) - sv-128 - ) - ((= v1-81 2) - (cond - ((-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) - (set! sv-320 format) - (set! sv-336 (clear *temp-string*)) - (set! sv-352 "~30L~S~0L ~S") - (set! sv-368 (lookup-text! *common-text* (game-text-id on) #f)) - (let ((a3-6 (lookup-text! *common-text* (game-text-id off) #f))) - (sv-320 sv-336 sv-352 sv-368 a3-6) + (case (-> s3-0 s0-0 option-type) + (((game-option-type slider)) + (let* ((v1-82 (the-as uint #x8000ffff)) + (f0-12 (* 0.01 (-> (the-as (pointer float) (-> s3-0 s0-0 value-to-modify))))) + (a0-34 (logior (logand v1-82 -256) (shr (shl (the int (+ 64.0 (* 191.0 f0-12))) 56) 56))) + (a3-5 (logior (logand a0-34 -65281) (shr (shl (shr (shl a0-34 56) 56) 56) 48))) ) - (set! sv-912 *temp-string*) - sv-912 - ) - (else - (set! sv-384 format) - (set! sv-400 (clear *temp-string*)) - (set! sv-416 "~0L~S ~30L~S~1L") - (set! sv-432 (lookup-text! *common-text* (game-text-id on) #f)) - (let ((a3-7 (lookup-text! *common-text* (game-text-id off) #f))) - (sv-384 sv-400 sv-416 sv-432 a3-7) - ) - (set! sv-912 *temp-string*) - sv-912 - ) - ) + (draw-percent-bar (- 75 (-> obj left-x-offset)) (+ s2-1 8) f0-12 (the-as int a3-5)) ) - ((= v1-81 1) - (set! sv-512 (-> obj language-selection)) - (set! sv-448 (-> (the-as (pointer uint64) (-> s3-0 s0-0 value-to-modify)))) - (if (and (zero? (scf-get-territory)) - (not (and (= *progress-cheat* 'language) (cpad-hold? 0 l2) (cpad-hold? 0 r2))) - ) - (set! sv-464 5) - (set! sv-464 6) - ) - (if (-> obj language-transition) - (set! (-> obj language-x-offset) - (seekl (-> obj language-x-offset) 200 (the int (* 10.0 (-> *display* time-adjust-ratio)))) - ) - ) - (when (>= (-> obj language-x-offset) 100) - (set! (-> obj language-selection) sv-448) - (set! sv-512 sv-448) - (set! (-> obj language-transition) #f) - (set! (-> obj language-x-offset) 0) - 0 + (set! option-str (string-format "~D" (the int (-> (the-as (pointer float) (-> s3-0 s0-0 value-to-modify)))))) + (set! x-off (+ (the int (* 2.5 (-> (the-as (pointer float) (-> s3-0 s0-0 value-to-modify))))) -100)) + x-off + ) + (((game-option-type on-off)) + (if (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) + (set! option-str (string-format "~30L~S~0L ~S" (lookup-text! *common-text* (game-text-id on) #f) (lookup-text! *common-text* (game-text-id off) #f))) + (set! option-str (string-format "~0L~S ~30L~S~1L" (lookup-text! *common-text* (game-text-id on) #f) (lookup-text! *common-text* (game-text-id off) #f))) ) - (set! (-> sv-112 origin y) (the float (+ s2-1 3))) - (let ((a0-62 sv-112)) - (set! (-> a0-62 color) (font-color lighter-lighter-blue)) - ) - 0 - (set! sv-480 (mod (the-as int (+ sv-512 1)) sv-464)) - (let ((a0-66 (mod (+ sv-464 -1 sv-512) sv-464)) - (v1-153 (mod (the-as int (+ sv-512 2)) sv-464)) - ) - (set! sv-496 (mod (+ sv-464 -2 sv-512) sv-464)) - (cond - ((-> obj language-direction) - (let ((a2-22 (- 200 (+ (-> obj language-x-offset) 100)))) - (print-language-name a0-66 sv-112 a2-22 #f) - ) - (let ((a2-23 (+ (-> obj language-x-offset) 100))) - (cond - ((< a2-23 150) - (let ((t9-27 print-language-name) - (a1-30 sv-112) - (a3-9 #t) - ) - (t9-27 sv-480 a1-30 a2-23 a3-9) - ) - ) - (else - (let ((a2-24 (- 200 (-> obj language-x-offset))) - (t9-28 print-language-name) - (a1-31 sv-112) - (a3-10 #f) - ) - (t9-28 sv-496 a1-31 a2-24 a3-10) - ) + ) + (((game-option-type language)) + (let ((old-lang (-> obj language-selection)) + (new-lang (-> (the-as (pointer language-enum) (-> s3-0 s0-0 value-to-modify)))) + (max-lang (if (and (= (scf-get-territory) GAME_TERRITORY_SCEA) + (not (and (= *progress-cheat* 'language) (cpad-hold? 0 l2) (cpad-hold? 0 r2)))) + 5 + 6 + )) + ) + (if (-> obj language-transition) + (set! (-> obj language-x-offset) + (seekl (-> obj language-x-offset) 200 (the int (* 10.0 (-> *display* time-adjust-ratio)))))) + (when (>= (-> obj language-x-offset) 100) + (set! (-> obj language-selection) new-lang) + (set! old-lang new-lang) + (set! (-> obj language-transition) #f) + (set! (-> obj language-x-offset) 0) + ) + (set! (-> font origin y) (the float (+ s2-1 3))) + (set-color! font (font-color lighter-lighter-blue)) + 0 + (let ((next-lang (mod (+ old-lang 1) max-lang)) + (a0-66 (mod (+ max-lang -1 old-lang) max-lang)) + (v1-153 (mod (+ old-lang 2) max-lang)) + (prev-lang (mod (+ max-lang -2 old-lang) max-lang)) + ) + (cond + ((-> obj language-direction) + (let ((a2-22 (- 200 (+ (-> obj language-x-offset) 100)))) + (print-language-name a0-66 font a2-22 #f) + ) + (let ((a2-23 (+ (-> obj language-x-offset) 100))) + (cond + ((< a2-23 150) + (print-language-name (the int next-lang) font a2-23 #t) + ) + (else + (let ((a2-24 (- 200 (-> obj language-x-offset)))) + (print-language-name prev-lang font a2-24 #f) ) ) ) ) - (else - (let ((a2-25 (+ (-> obj language-x-offset) 100))) - (cond - ((< a2-25 150) - (print-language-name a0-66 sv-112 a2-25 #f) - ) - (else - (let ((a2-26 (- 200 (-> obj language-x-offset)))) - (print-language-name v1-153 sv-112 a2-26 #t) - ) + ) + (else + (let ((a2-25 (+ (-> obj language-x-offset) 100))) + (cond + ((< a2-25 150) + (print-language-name a0-66 font a2-25 #f) + ) + (else + (let ((a2-26 (- 200 (-> obj language-x-offset)))) + (print-language-name (the int v1-153) font a2-26 #t) ) ) ) - (let ((a2-27 (- 200 (+ (-> obj language-x-offset) 100)))) - (print-language-name sv-480 sv-112 a2-27 #t) - ) + ) + (let ((a2-27 (- 200 (+ (-> obj language-x-offset) 100)))) + (print-language-name (the int next-lang) font a2-27 #t) ) ) ) - (when (not (-> obj language-transition)) - (let ((a0-75 sv-112)) - (set! (-> a0-75 color) (font-color yellow-green-2)) - ) - ) - (let ((t9-32 print-language-name) - (a1-37 sv-112) - (a2-28 (-> obj language-x-offset)) - (a3-14 (-> obj language-direction)) - ) - (t9-32 (the-as int sv-512) a1-37 a2-28 (the-as symbol a3-14)) - ) ) - ((= v1-81 3) - (set! sv-912 (lookup-text! *common-text* (game-text-id move-dpad) #f)) - sv-912 - ) - ((= v1-81 4) - (cond - ((= (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) 'aspect4x3) - (set! sv-528 format) - (set! sv-544 (clear *temp-string*)) - (set! sv-560 "~30L~S~0L ~S") - (set! sv-576 (lookup-text! *common-text* (game-text-id 4x3) #f)) - (let ((a3-15 (lookup-text! *common-text* (game-text-id 16x9) #f))) - (sv-528 sv-544 sv-560 sv-576 a3-15) - ) - (set! sv-912 *temp-string*) - sv-912 - ) - (else - (set! sv-592 format) - (set! sv-608 (clear *temp-string*)) - (set! sv-624 "~0L~S ~30L~S~1L") - (set! sv-640 (lookup-text! *common-text* (game-text-id 4x3) #f)) - (let ((a3-16 (lookup-text! *common-text* (game-text-id 16x9) #f))) - (sv-592 sv-608 sv-624 sv-640 a3-16) - ) - (set! sv-912 *temp-string*) - sv-912 - ) + (if (not (-> obj language-transition)) + (set-color! font (font-color yellow-green-2))) + (print-language-name (the-as int old-lang) font (-> obj language-x-offset) (-> obj language-direction)) + )) + (((game-option-type center-screen)) + (set! option-str (lookup-text! *common-text* (game-text-id move-dpad) #f)) + ) + (((game-option-type aspect-ratio)) + (if (= (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) 'aspect4x3) + (set! option-str (string-format "~30L~S~0L ~S" (lookup-text! *common-text* (game-text-id 4x3) #f) (lookup-text! *common-text* (game-text-id 16x9) #f))) + (set! option-str (string-format "~0L~S ~30L~S~1L" (lookup-text! *common-text* (game-text-id 4x3) #f) (lookup-text! *common-text* (game-text-id 16x9) #f))) ) - ) - ((= v1-81 5) - (cond - ((= (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) 'ntsc) - (set! sv-656 format) - (set! sv-672 (clear *temp-string*)) - (set! sv-688 "~0L~S ~30L~S~1L") - (set! sv-704 (lookup-text! *common-text* (game-text-id 50hz) #f)) - (let ((a3-17 (lookup-text! *common-text* (game-text-id 60hz) #f))) - (sv-656 sv-672 sv-688 sv-704 a3-17) - ) - (set! sv-912 *temp-string*) - sv-912 - ) - (else - (set! sv-720 format) - (set! sv-736 (clear *temp-string*)) - (set! sv-752 "~30L~S~0L ~S") - (set! sv-768 (lookup-text! *common-text* (game-text-id 50hz) #f)) - (let ((a3-18 (lookup-text! *common-text* (game-text-id 60hz) #f))) - (sv-720 sv-736 sv-752 sv-768 a3-18) - ) - (set! sv-912 *temp-string*) - sv-912 - ) + ) + (((game-option-type video-mode)) + (if (= (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) 'ntsc) + (set! option-str (string-format "~0L~S ~30L~S~1L" (lookup-text! *common-text* (game-text-id 50hz) #f) (lookup-text! *common-text* (game-text-id 60hz) #f))) + (set! option-str (string-format "~30L~S~0L ~S" (lookup-text! *common-text* (game-text-id 50hz) #f) (lookup-text! *common-text* (game-text-id 60hz) #f))) ) - ) - ) + ) ) ) (else - (let ((v1-195 (-> s3-0 s0-0 option-type))) - (cond - ((or (zero? v1-195) (= v1-195 3) (= v1-195 4) (= v1-195 5)) - (set! sv-912 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) - sv-912 - ) - ((= v1-195 2) - (set! sv-784 format) - (set! sv-800 (clear *temp-string*)) - (set! sv-816 "~S: ~S") - (set! sv-832 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) - (let ((a3-19 (if (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) - (lookup-text! *common-text* (game-text-id on) #f) - (lookup-text! *common-text* (game-text-id off) #f) - ) - ) - ) - (sv-784 sv-800 sv-816 sv-832 a3-19) - ) - (set! sv-912 *temp-string*) - sv-912 - ) - ((= v1-195 1) - (set! sv-848 format) - (set! sv-864 (clear *temp-string*)) - (set! sv-880 "~S: ~S") - (set! sv-896 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) - (let ((a3-20 (lookup-text! - *common-text* - (-> *language-name-remap* (-> (the-as (pointer uint64) (-> s3-0 s0-0 value-to-modify)))) - #f - ) - ) - ) - (sv-848 sv-864 sv-880 sv-896 a3-20) - ) - (set! sv-912 *temp-string*) - sv-912 - ) + (case (-> s3-0 s0-0 option-type) + (((game-option-type slider) + (game-option-type center-screen) + (game-option-type aspect-ratio) + (game-option-type video-mode) ) + (set! option-str (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) + ) + (((game-option-type on-off)) + (set! option-str (string-format "~S: ~S" (lookup-text! *common-text* (-> s3-0 s0-0 name) #f) + (if (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) + (lookup-text! *common-text* (game-text-id on) #f) + (lookup-text! *common-text* (game-text-id off) #f) + ))) + ) + (((game-option-type language)) + (set! option-str (string-format "~S: ~S" (lookup-text! *common-text* (-> s3-0 s0-0 name) #f) + (lookup-text! *common-text* (-> *language-name-remap* (-> (the-as (pointer uint64) (-> s3-0 s0-0 value-to-modify)))) #f))) + ) ) ) ) ) - (when sv-912 + (when option-str (let ((f0-23 (-> obj transition-percentage-invert))) - (let ((v1-235 sv-112)) - (set! (-> v1-235 color) - (the-as font-color (if (and (= s0-0 (-> obj option-index)) (not (-> obj in-transition))) - 30 - 0 - ) - ) + (set-color! font (if (and (= s0-0 (-> obj option-index)) (not (-> obj in-transition))) + (font-color yellow-green-2) + (font-color default) + ) ) - ) - (set! (-> sv-112 origin x) (the float (- sv-128 (-> obj left-x-offset)))) - (set! (-> sv-112 origin y) (the float (the int (* (the float sv-144) (if (-> s3-0 s0-0 scale) + (set! (-> font origin x) (the float (- x-off (-> obj left-x-offset)))) + (set! (-> font origin y) (the float (the int (* (the float y-off) (if (-> s3-0 s0-0 scale) f0-23 1.0 - ) - ) - ) - ) - ) - (let ((v1-246 sv-112)) - (set! (-> v1-246 scale) (* arg2 f0-23)) - ) - (let ((t9-60 print-game-text) - (a1-64 sv-112) - (a2-50 #f) - (a3-21 (the int (* 128.0 f0-23))) - (t0-2 22) - ) - (t9-60 sv-912 a1-64 a2-50 a3-21 t0-2) - ) + ))))) + (set-scale! font (* arg2 f0-23)) + (print-game-text option-str font #f (the int (* 128.0 f0-23)) 22) ) ) (+! s2-1 arg1) (+! s1-0 1) - ) + )) ) ) ) @@ -2156,3 +1931,4 @@ + diff --git a/goal_src/engine/ui/progress/progress-part.gc b/goal_src/engine/ui/progress/progress-part.gc index 90168e6b6d..fe4a70a904 100644 --- a/goal_src/engine/ui/progress/progress-part.gc +++ b/goal_src/engine/ui/progress/progress-part.gc @@ -993,8 +993,8 @@ (progress-new-particle :part 90 :x 256.0 :y 224.0 :z 16.0) ;; tint (progress-new-particle :part 88 :x -42.0 :y (#if PC_PORT 256.0 254.0) :z 5.0) ;; left (progress-new-particle :part 89 :x 610.0 :y (#if PC_PORT 256.0 254.0) :z 5.0) ;; right - (progress-new-particle :part 85 :x -320.0 :y 40.0 :z 14.0) - (progress-new-particle :part 86 :x -320.0 :y 400.0 :z 14.0) + (progress-new-particle :part 85 :x -320.0 :y 40.0 :z 14.0) ;; prev + (progress-new-particle :part 86 :x -320.0 :y 400.0 :z 14.0) ;; next (progress-new-particle :part 87 :x -320.0 :y 194.0 :z 15.0) (progress-new-particle :part 97 :x -320.0 :y 194.0 :z 14.0) (progress-new-particle :part 97 :x -320.0 :y 194.0 :z 14.0) @@ -1022,6 +1022,10 @@ (progress-new-particle :part 572 :x -320.0 :y 338.0 :z 4.0) (progress-new-particle :part 573 :x -320.0 :y 338.0 :z 4.0) (progress-new-particle :part 615 :x -320.0 :y 180.0 :z 4.0) + (#when PC_PORT + (progress-new-particle :part 85 :x -320.0 :y 32.0 :z 14.0) ;; prev + (progress-new-particle :part 86 :x -320.0 :y 412.0 :z 14.0) ;; next + ) 0 (none) ) diff --git a/goal_src/engine/ui/progress/progress-static.gc b/goal_src/engine/ui/progress/progress-static.gc index 122b5ec991..b87c990629 100644 --- a/goal_src/engine/ui/progress/progress-static.gc +++ b/goal_src/engine/ui/progress/progress-static.gc @@ -9,154 +9,152 @@ ;; options in the start menu options (define *main-options* - (new 'static 'boxed-array :type game-option :length 7 :allocated-length 7 - (new 'static 'game-option :option-type #x6 :name (game-text-id game-options) :scale #t :param3 4) - (new 'static 'game-option :option-type #x6 :name (game-text-id graphic-options) :scale #t :param3 5) - (new 'static 'game-option :option-type #x6 :name (game-text-id sound-options) :scale #t :param3 6) - (new 'static 'game-option :option-type #x6 :name (game-text-id load-game) :scale #t :param3 16) - (new 'static 'game-option :option-type #x6 :name (game-text-id save-game) :scale #t :param3 17) - (new 'static 'game-option :option-type #x6 :name (game-text-id quit-game) :scale #t :param3 34) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) + (new 'static 'boxed-array :type game-option :length 7 :allocated-length 7 + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id game-options) :scale #t :param3 (game-option-menu game-settings)) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id graphic-options) :scale #t :param3 (game-option-menu graphic-settings)) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id sound-options) :scale #t :param3 (game-option-menu sound-settings)) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id load-game) :scale #t :param3 (game-option-menu load-game)) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id save-game) :scale #t :param3 (game-option-menu save-game)) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id quit-game) :scale #t :param3 (game-option-menu quit)) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) ) (define *title* - (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :option-type #x6 :name (game-text-id new-game) :scale #t :param3 18) - (new 'static 'game-option :option-type #x6 :name (game-text-id load-game) :scale #t :param3 16) - (new 'static 'game-option :option-type #x6 :name (game-text-id options) :scale #t :param3 28) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) + (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id new-game) :scale #t :param3 (game-option-menu save-game-title)) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id load-game) :scale #t :param3 (game-option-menu load-game)) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id options) :scale #t :param3 (game-option-menu settings-title)) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) ) (define *options* - (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :option-type #x6 :name (game-text-id game-options) :scale #t :param3 4) - (new 'static 'game-option :option-type #x6 :name (game-text-id graphic-options) :scale #t :param3 5) - (new 'static 'game-option :option-type #x6 :name (game-text-id sound-options) :scale #t :param3 6) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) + (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id game-options) :scale #t :param3 (game-option-menu game-settings)) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id graphic-options) :scale #t :param3 (game-option-menu graphic-settings)) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id sound-options) :scale #t :param3 (game-option-menu sound-settings)) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) ) (define *main-options-demo* - (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :option-type #x6 :name (game-text-id game-options) :scale #t :param3 4) - (new 'static 'game-option :option-type #x6 :name (game-text-id graphic-options) :scale #t :param3 5) - (new 'static 'game-option :option-type #x6 :name (game-text-id sound-options) :scale #t :param3 6) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) + (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id game-options) :scale #t :param3 (game-option-menu game-settings)) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id graphic-options) :scale #t :param3 (game-option-menu graphic-settings)) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id sound-options) :scale #t :param3 (game-option-menu sound-settings)) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) ) (define *main-options-demo-shared* - (new 'static 'boxed-array :type game-option :length 5 :allocated-length 5 - (new 'static 'game-option :option-type #x6 :name (game-text-id game-options) :scale #t :param3 4) - (new 'static 'game-option :option-type #x6 :name (game-text-id graphic-options) :scale #t :param3 5) - (new 'static 'game-option :option-type #x6 :name (game-text-id sound-options) :scale #t :param3 6) - (new 'static 'game-option :option-type #x8 :name (game-text-id exit-demo) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) + (new 'static 'boxed-array :type game-option :length 5 :allocated-length 5 + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id game-options) :scale #t :param3 (game-option-menu game-settings)) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id graphic-options) :scale #t :param3 (game-option-menu graphic-settings)) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id sound-options) :scale #t :param3 (game-option-menu sound-settings)) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id exit-demo) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) ) (define *game-options* - (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :option-type #x2 :name (game-text-id vibrations) :scale #t) - (new 'static 'game-option :option-type #x2 :name (game-text-id play-hints) :scale #t) - (new 'static 'game-option :option-type #x1 :name (game-text-id language) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) + (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id vibrations) :scale #t) + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id play-hints) :scale #t) + (new 'static 'game-option :option-type (game-option-type language) :name (game-text-id language) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) ) (define *game-options-japan* - (new 'static 'boxed-array :type game-option :length 3 :allocated-length 3 - (new 'static 'game-option :option-type #x2 :name (game-text-id vibrations) :scale #t) - (new 'static 'game-option :option-type #x2 :name (game-text-id play-hints) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) + (new 'static 'boxed-array :type game-option :length 3 :allocated-length 3 + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id vibrations) :scale #t) + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id play-hints) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) ) (define *game-options-demo* - (new 'static 'boxed-array :type game-option :length 3 :allocated-length 3 - (new 'static 'game-option :option-type #x2 :name (game-text-id vibrations) :scale #t) - (new 'static 'game-option :option-type #x2 :name (game-text-id play-hints) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) + (new 'static 'boxed-array :type game-option :length 3 :allocated-length 3 + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id vibrations) :scale #t) + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id play-hints) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) ) (define *graphic-options* - (new 'static 'boxed-array :type game-option :length 3 :allocated-length 3 - (new 'static 'game-option :option-type #x3 :name (game-text-id center-screen) :scale #t) - (new 'static 'game-option :option-type #x4 :name (game-text-id aspect-ratio) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) + (new 'static 'boxed-array :type game-option :length 3 :allocated-length 3 + (new 'static 'game-option :option-type (game-option-type center-screen) :name (game-text-id center-screen) :scale #t) + (new 'static 'game-option :option-type (game-option-type aspect-ratio) :name (game-text-id aspect-ratio) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) ) (define *graphic-title-options-pal* - (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :option-type #x3 :name (game-text-id center-screen) :scale #t) - (new 'static 'game-option :option-type #x5 :name (game-text-id video-mode) :scale #t) - (new 'static 'game-option :option-type #x4 :name (game-text-id aspect-ratio) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) + (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 + (new 'static 'game-option :option-type (game-option-type center-screen) :name (game-text-id center-screen) :scale #t) + (new 'static 'game-option :option-type (game-option-type video-mode) :name (game-text-id video-mode) :scale #t) + (new 'static 'game-option :option-type (game-option-type aspect-ratio) :name (game-text-id aspect-ratio) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) ) (define *sound-options* - (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :name (game-text-id sfx-volume) :scale #t :param2 100.0) - (new 'static 'game-option :name (game-text-id music-volume) :scale #t :param2 100.0) - (new 'static 'game-option :name (game-text-id speech-volume) :scale #t :param2 100.0) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) + (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 + (new 'static 'game-option :name (game-text-id sfx-volume) :scale #t :param2 100.0) + (new 'static 'game-option :name (game-text-id music-volume) :scale #t :param2 100.0) + (new 'static 'game-option :name (game-text-id speech-volume) :scale #t :param2 100.0) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) ) -(define *yes-no-options* - (new 'static 'boxed-array :type game-option :length 1 :allocated-length 1 - (new 'static 'game-option :option-type #x7 :scale #f) - ) - ) +(define *yes-no-options* (new 'static 'boxed-array :type game-option :length 1 :allocated-length 1 + (new 'static 'game-option :option-type (game-option-type yes-no) :scale #f) + ) + ) (define *ok-options* - (new 'static 'boxed-array :type game-option :length 1 :allocated-length 1 - (new 'static 'game-option :option-type #x8 :name (game-text-id ok) :scale #f) - ) + (new 'static 'boxed-array :type game-option :length 1 :allocated-length 1 + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id ok) :scale #f) + ) ) (define *load-options* - (new 'static 'boxed-array - :type game-option :length 5 :allocated-length 5 - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #f) - ) + (new 'static 'boxed-array :type game-option :length 5 :allocated-length 5 + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #f) + ) ) (define *save-options* - (new 'static 'boxed-array :type game-option :length 5 :allocated-length 5 - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #f) - ) + (new 'static 'boxed-array :type game-option :length 5 :allocated-length 5 + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #f) + ) ) (define *save-options-title* - (new 'static 'boxed-array - :type game-option :length 6 :allocated-length 6 - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :name (game-text-id continue-without-saving) :scale #f) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #f) - ) + (new 'static 'boxed-array :type game-option :length 6 :allocated-length 6 + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id continue-without-saving) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #f) + ) ) ;; maps options to a progress screen -(define *options-remap* - (new 'static 'boxed-array :type (array game-option) :length 0 :allocated-length 35) - ) +(#if (not PC_PORT) + (define *options-remap* (new 'static 'boxed-array :type (array game-option) :length 0 :allocated-length 35)) + (define *options-remap* (new 'static 'boxed-array :type (array game-option) :length 0 :allocated-length 50)) + ) ;; TODO probably an enum. ;; maps "levels" to the appropriate offset in *level-task-data* diff --git a/goal_src/engine/ui/progress/progress.gc b/goal_src/engine/ui/progress/progress.gc index ef35fb5f50..eede5ed1b0 100644 --- a/goal_src/engine/ui/progress/progress.gc +++ b/goal_src/engine/ui/progress/progress.gc @@ -15,7 +15,7 @@ (starting-state progress-screen :offset-assert 24) (last-slot-saved int32 :offset-assert 32) (slider-backup float :offset-assert 36) - (language-backup int64 :offset-assert 40) + (language-backup language-enum :offset-assert 40) (on-off-backup symbol :offset-assert 48) (center-x-backup int32 :offset-assert 52) (center-y-backup int32 :offset-assert 56) @@ -75,12 +75,12 @@ "Set the options for all of the menus." ;; start off by making them all invalid - (dotimes (i 35) + (dotimes (i (progress-screen max)) (set! (-> *options-remap* i) #f) ) ;; main menu - (set! (-> *options-remap* 3) + (set! (-> *options-remap* (progress-screen settings)) (case *kernel-boot-message* (('demo) ;; game demo @@ -96,7 +96,7 @@ ) ) ) - (set! (-> *options-remap* 4) + (set! (-> *options-remap* (progress-screen game-settings)) (cond ((!= *kernel-boot-message* 'play) (if (= (scf-get-territory) GAME_TERRITORY_SCEE) @@ -106,7 +106,7 @@ ) ((and (= (scf-get-territory) GAME_TERRITORY_SCEI) (not (and (= *progress-cheat* 'language) (cpad-hold? 0 l2) (cpad-hold? 0 r2)))) - ;; if ntsc-j and we're not using language cheat (needs l2+r2) + ;; if ntsc-j and we're not using language cheat (and holding l2+r2) *game-options-japan* ) (else @@ -114,45 +114,40 @@ ) ) ) - (set! (-> *options-remap* 5) - (if (and (= (-> *progress-state* starting-state) 27) + (set! (-> *options-remap* (progress-screen graphic-settings)) + (if (and (= (-> *progress-state* starting-state) (progress-screen title)) (or (= (scf-get-territory) GAME_TERRITORY_SCEE) - (and (= *progress-cheat* 'pal) - (logtest? (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons l2)) - (logtest? (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons r2)) - ) - ) - ) - ;; (only if we came from title) if PAL or we're using the PAL cheat (needs l2+r2) + (and (= *progress-cheat* 'pal) (cpad-hold? 0 l2) (cpad-hold? 0 r2)))) + ;; (only if we came from title) if PAL or we're using the PAL cheat (and holding l2+r2) *graphic-title-options-pal* *graphic-options* ) ) - (set! (-> *options-remap* 6) *sound-options*) - (set! (-> *options-remap* 7) *ok-options*) - (set! (-> *options-remap* 8) *ok-options*) - (set! (-> *options-remap* 9) *ok-options*) - (set! (-> *options-remap* 10) *yes-no-options*) - (set! (-> *options-remap* 11) *yes-no-options*) - (set! (-> *options-remap* 19) *ok-options*) - (set! (-> *options-remap* 16) *load-options*) - (set! (-> *options-remap* 17) *save-options*) - (set! (-> *options-remap* 18) *save-options-title*) - (set! (-> *options-remap* 20) *ok-options*) - (set! (-> *options-remap* 21) *ok-options*) - (set! (-> *options-remap* 24) *ok-options*) - (set! (-> *options-remap* 25) *ok-options*) - (set! (-> *options-remap* 26) *ok-options*) - (set! (-> *options-remap* 22) *ok-options*) - (set! (-> *options-remap* 23) *yes-no-options*) - (set! (-> *options-remap* 27) *title*) - (set! (-> *options-remap* 28) *options*) - (set! (-> *options-remap* 29) *ok-options*) - (set! (-> *options-remap* 30) *yes-no-options*) - (set! (-> *options-remap* 31) *yes-no-options*) - (set! (-> *options-remap* 32) *ok-options*) - (set! (-> *options-remap* 33) *ok-options*) - (set! (-> *options-remap* 34) *yes-no-options*) + (set! (-> *options-remap* (progress-screen sound-settings)) *sound-options*) + (set! (-> *options-remap* (progress-screen memcard-no-space)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-not-inserted)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-not-formatted)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-format)) *yes-no-options*) + (set! (-> *options-remap* (progress-screen memcard-data-exists)) *yes-no-options*) + (set! (-> *options-remap* (progress-screen memcard-insert)) *ok-options*) + (set! (-> *options-remap* (progress-screen load-game)) *load-options*) + (set! (-> *options-remap* (progress-screen save-game)) *save-options*) + (set! (-> *options-remap* (progress-screen save-game-title)) *save-options-title*) + (set! (-> *options-remap* (progress-screen memcard-error-loading)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-error-saving)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-error-formatting)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-error-creating)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-auto-save-error)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-removed)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-no-data)) *yes-no-options*) + (set! (-> *options-remap* (progress-screen title)) *title*) + (set! (-> *options-remap* (progress-screen settings-title)) *options*) + (set! (-> *options-remap* (progress-screen auto-save)) *ok-options*) + (set! (-> *options-remap* (progress-screen pal-change-to-60hz)) *yes-no-options*) + (set! (-> *options-remap* (progress-screen pal-now-60hz)) *yes-no-options*) + (set! (-> *options-remap* (progress-screen no-disc)) *ok-options*) + (set! (-> *options-remap* (progress-screen bad-disc)) *ok-options*) + (set! (-> *options-remap* (progress-screen quit)) *yes-no-options*) (set! (-> *progress-state* aspect-ratio-choice) (get-aspect-ratio)) (set! (-> *progress-state* video-mode-choice) (get-video-mode)) (set! (-> *progress-state* yes-no-choice) #f) @@ -299,51 +294,43 @@ Buzzers are tallied 10% Orbs are tallied 10%" - (local-vars - (current-cells int) - (current-buzzers int) - (current-orbs int) - (total-cells int) - (total-buzzers int) - (total-orbs int) - ) - (set! current-cells 0) - (set! current-buzzers 0) - (set! current-orbs 0) - (set! total-cells 0) - (set! total-buzzers 0) - (set! total-orbs 0) - (dotimes (s5-0 (length *level-task-data*)) - (let ((s4-0 (-> *level-task-data* s5-0))) - (when (!= s4-0 #f) - (when (or (= *kernel-boot-message* 'play) (= (-> s4-0 level-name-id) (game-text-id misty-level-name))) - (dotimes (s3-0 (-> s4-0 nb-of-tasks)) - (if (= (get-task-status (-> s4-0 task-info s3-0 task-id)) (task-status invalid)) - (set! current-cells (+ current-cells 1)) + (let ((current-cells 0) + (current-buzzers 0) + (current-orbs 0) + (total-cells 0) + (total-buzzers 0) + (total-orbs 0)) + (dotimes (s5-0 (length *level-task-data*)) + (let ((s4-0 (-> *level-task-data* s5-0))) + (when (!= s4-0 #f) + (when (or (= *kernel-boot-message* 'play) (= (-> s4-0 level-name-id) (game-text-id misty-level-name))) + (dotimes (s3-0 (-> s4-0 nb-of-tasks)) + (if (= (get-task-status (-> s4-0 task-info s3-0 task-id)) (task-status invalid)) + (1+! current-cells) + ) + ) + (set! total-cells (+ total-cells (-> s4-0 nb-of-tasks))) + (set! current-orbs (+ current-orbs (-> *game-info* money-per-level s5-0))) + (set! total-orbs (+ total-orbs (-> *game-counts* data s5-0 money-count))) + (let ((v1-20 (-> s4-0 buzzer-task-index))) + (when (!= v1-20 -1) + (set! current-buzzers (+ current-buzzers (buzzer-count *game-info* (-> s4-0 task-info v1-20 task-id)))) + (set! total-buzzers (+ total-buzzers (-> *game-counts* data s5-0 buzzer-count))) ) - ) - (set! total-cells (+ total-cells (-> s4-0 nb-of-tasks))) - (set! current-orbs (+ current-orbs (-> *game-info* money-per-level s5-0))) - (set! total-orbs (+ total-orbs (-> *game-counts* data s5-0 money-count))) - (let ((v1-20 (-> s4-0 buzzer-task-index))) - (when (!= v1-20 -1) - (set! current-buzzers (+ current-buzzers (buzzer-count *game-info* (-> s4-0 task-info v1-20 task-id)))) - (set! total-buzzers (+ total-buzzers (-> *game-counts* data s5-0 buzzer-count))) ) ) ) ) ) - ) - (when the-progress - (set! (-> the-progress total-nb-of-power-cells) total-cells) - (set! (-> the-progress total-nb-of-buzzers) total-buzzers) - (set! (-> the-progress total-nb-of-orbs) total-orbs) - ) - (+ (/ (* 80.0 (the float current-cells)) (the float total-cells)) - (/ (* 10.0 (the float current-orbs)) (the float total-orbs)) - (/ (* 10.0 (the float current-buzzers)) (the float total-buzzers)) - ) + (when the-progress + (set! (-> the-progress total-nb-of-power-cells) total-cells) + (set! (-> the-progress total-nb-of-buzzers) total-buzzers) + (set! (-> the-progress total-nb-of-orbs) total-orbs) + ) + (+ (/ (* 80.0 (the float current-cells)) (the float total-cells)) + (/ (* 10.0 (the float current-orbs)) (the float total-orbs)) + (/ (* 10.0 (the float current-buzzers)) (the float total-buzzers)) + )) ) (define *progress-save-info* (new 'global 'mc-slot-info)) @@ -467,7 +454,6 @@ ) (((progress-screen memcard-removed)) (set! (-> *progress-state* last-slot-saved) 0) - 0 ) ) ) @@ -513,7 +499,7 @@ (defmethod set-transition-progress! progress ((obj progress) (arg0 int)) (set! (-> obj transition-offset) arg0) (set! (-> obj transition-offset-invert) (- 512 arg0)) - (set! (-> obj transition-percentage) (* 0.001953125 (the float arg0))) + (set! (-> obj transition-percentage) (* (1/ 512) (the float arg0))) (set! (-> obj transition-percentage-invert) (- 1.0 (-> obj transition-percentage))) 0 (none) @@ -857,7 +843,7 @@ (none) ) -(defmethod dummy-32 progress ((obj progress)) +(defmethod can-go-back? progress ((obj progress)) (let ((v1-2 (-> *progress-process* 0 display-state)) (a1-1 (-> *progress-state* starting-state)) ) @@ -872,20 +858,35 @@ (= a1-1 (progress-screen buzzer)) (= a1-1 (progress-screen title)) ) - (or (= v1-2 (progress-screen settings)) - (= v1-2 (progress-screen game-settings)) - (= v1-2 (progress-screen graphic-settings)) - (= v1-2 (progress-screen sound-settings)) - (= v1-2 (progress-screen title)) - (= v1-2 (progress-screen settings-title)) - ) + (#if (not PC_PORT) + (or (= v1-2 (progress-screen settings)) + (= v1-2 (progress-screen game-settings)) + (= v1-2 (progress-screen graphic-settings)) + (= v1-2 (progress-screen sound-settings)) + (= v1-2 (progress-screen title)) + (= v1-2 (progress-screen settings-title))) + (or (= v1-2 (progress-screen settings)) + (= v1-2 (progress-screen game-settings)) + (= v1-2 (progress-screen graphic-settings)) + (= v1-2 (progress-screen sound-settings)) + (= v1-2 (progress-screen title)) + (= v1-2 (progress-screen settings-title)) + (= v1-2 (progress-screen camera-options)) + (= v1-2 (progress-screen accessibility-options)) + (= v1-2 (progress-screen misc-options)) + (= v1-2 (progress-screen game-ps2-options)) + (= v1-2 (progress-screen gfx-ps2-options)) + (= v1-2 (progress-screen resolution)) + (= v1-2 (progress-screen aspect-ratio)) + ) + ) ) ) ) ) ) -(defmethod dummy-19 progress ((obj progress)) +(defmethod visible? progress ((obj progress)) (the-as symbol (and *progress-process* (zero? (-> *progress-process* 0 in-out-position)))) ) @@ -933,7 +934,7 @@ ) ) -(defmethod dummy-53 progress ((obj progress) (arg0 progress-screen)) +(defmethod set-memcard-screen progress ((obj progress) (arg0 progress-screen)) (let ((s4-0 (-> obj card-info)) (gp-0 arg0) ) @@ -1034,14 +1035,12 @@ ) ) -(defmethod dummy-31 progress ((obj progress)) +(defmethod respond-memcard progress ((obj progress)) (let ((s5-0 (-> obj card-info))) (when (and s5-0 (not (-> obj in-transition))) (when (or (cpad-pressed? 0 x) (cpad-pressed? 0 circle)) - (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons x)) - (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons x)) - (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons circle)) - (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons circle)) + (cpad-clear! 0 x) + (cpad-clear! 0 circle) (case (-> obj display-state) (((progress-screen load-game)) (cond @@ -1091,14 +1090,12 @@ (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) (set! (-> obj next-display-state) (progress-screen memcard-saving)) ) - ((begin - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - (= (-> obj display-state-stack 0) (progress-screen title)) - ) - (set! (-> obj next-display-state) (progress-screen save-game-title)) - ) (else - (set! (-> obj next-display-state) (progress-screen save-game)) + (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) + (if (= (-> obj display-state-stack 0) (progress-screen title)) + (set! (-> obj next-display-state) (progress-screen save-game-title)) + (set! (-> obj next-display-state) (progress-screen save-game)) + ) ) ) ) @@ -1225,7 +1222,7 @@ (none) ) -(defmethod dummy-29 progress ((obj progress)) +(defmethod respond-common progress ((obj progress)) (mc-get-slot-info 0 *progress-save-info*) (set! (-> obj card-info) *progress-save-info*) (let ((s5-0 (-> *options-remap* (-> obj display-state)))) @@ -1249,7 +1246,7 @@ (when (-> obj selected-option) (let ((v1-34 #f)) (case (-> s5-0 (-> obj option-index) option-type) - ((3) + (((game-option-type center-screen)) (when (< -48 (-> *setting-control* current screeny)) (set! v1-34 #t) (+! (-> *setting-control* default screeny) -1) @@ -1290,7 +1287,7 @@ (when (-> obj selected-option) (let ((v1-69 #f)) (case (-> s5-0 (-> obj option-index) option-type) - ((3) + (((game-option-type center-screen)) (when (< (-> *setting-control* current screeny) 48) (set! v1-69 #t) (+! (-> *setting-control* default screeny) 1) @@ -1311,11 +1308,11 @@ ((cpad-hold? 0 left) (cond ((cpad-pressed? 0 left) - (when (or (-> obj selected-option) (= (-> s5-0 (-> obj option-index) option-type) 7)) + (when (or (-> obj selected-option) (= (-> s5-0 (-> obj option-index) option-type) (game-option-type yes-no))) (let ((s4-5 #f)) (case (-> s5-0 (-> obj option-index) option-type) - ((2 7) - (when (not (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)))) + (((game-option-type on-off) (game-option-type yes-no)) + (when (not (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) (set! s4-5 #t) (if (= (-> s5-0 (-> obj option-index) value-to-modify) (&-> *setting-control* current vibration)) (cpad-set-buzz! (-> *cpad-list* cpads 0) 1 255 (seconds 0.3)) @@ -1323,15 +1320,15 @@ ) (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) #t) ) - ((4) - (set! s4-5 (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'aspect16x9)) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'aspect4x3) + (((game-option-type aspect-ratio)) + (set! s4-5 (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'aspect16x9)) + (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'aspect4x3) ) - ((5) - (set! s4-5 (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'ntsc)) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'pal) + (((game-option-type video-mode)) + (set! s4-5 (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'ntsc)) + (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'pal) ) - ((1) + (((game-option-type language)) (if (> (the-as int (-> (the-as (pointer uint64) (-> s5-0 (-> obj option-index) value-to-modify)))) 0) (+! (-> (the-as (pointer uint64) (-> s5-0 (-> obj option-index) value-to-modify))) -1) (set! (-> (the-as (pointer int64) (-> s5-0 (-> obj option-index) value-to-modify))) @@ -1357,35 +1354,33 @@ (else (when (-> obj selected-option) (let ((v1-157 #f)) - (let ((a0-101 (-> s5-0 (-> obj option-index) option-type))) - (cond - ((zero? a0-101) - (cond - ((>= (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (+ 1.0 (-> s5-0 (-> obj option-index) param1)) + (case (-> s5-0 (-> obj option-index) option-type) + (((game-option-type slider)) + (cond + ((>= (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (+ 1.0 (-> s5-0 (-> obj option-index) param1)) + ) + (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (+ -1.0 (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify)))) ) - (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (+ -1.0 (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - (set! v1-157 #t) - ) - ((< (-> s5-0 (-> obj option-index) param1) - (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - ) - (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> s5-0 (-> obj option-index) param1) - ) - (set! v1-157 #t) - ) - ) + (set! v1-157 #t) + ) + ((< (-> s5-0 (-> obj option-index) param1) + (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + ) + (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (-> s5-0 (-> obj option-index) param1) + ) + (set! v1-157 #t) + ) ) - ((= a0-101 3) - (when (< -96 (-> *setting-control* default screenx)) - (set! v1-157 #t) - (+! (-> *setting-control* default screenx) -1) - ) + ) + (((game-option-type center-screen)) + (when (< -96 (-> *setting-control* default screenx)) + (set! v1-157 #t) + (+! (-> *setting-control* default screenx) -1) ) - ) + ) ) (when v1-157 (let ((f30-0 100.0)) @@ -1408,22 +1403,22 @@ ((cpad-hold? 0 right) (cond ((cpad-pressed? 0 right) - (when (or (-> obj selected-option) (= (-> s5-0 (-> obj option-index) option-type) 7)) + (when (or (-> obj selected-option) (= (-> s5-0 (-> obj option-index) option-type) (game-option-type yes-no))) (let ((v1-217 (the-as object #f))) (case (-> s5-0 (-> obj option-index) option-type) - ((2 7) - (set! v1-217 (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)))) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) #f) + (((game-option-type on-off) (game-option-type yes-no)) + (set! v1-217 (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) + (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) #f) ) - ((4) - (set! v1-217 (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'aspect4x3)) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'aspect16x9) + (((game-option-type aspect-ratio)) + (set! v1-217 (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'aspect4x3)) + (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'aspect16x9) ) - ((5) - (set! v1-217 (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'pal)) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'ntsc) + (((game-option-type video-mode)) + (set! v1-217 (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'pal)) + (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'ntsc) ) - ((1) + (((game-option-type language)) (let ((v1-243 (if (and (zero? (scf-get-territory)) (not (and (= *progress-cheat* 'language) (cpad-hold? 0 l2) (cpad-hold? 0 r2))) ) @@ -1456,35 +1451,33 @@ (else (when (-> obj selected-option) (let ((v1-263 #f)) - (let ((a0-177 (-> s5-0 (-> obj option-index) option-type))) - (cond - ((zero? a0-177) - (cond - ((>= (+ -1.0 (-> s5-0 (-> obj option-index) param2)) - (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (case (-> s5-0 (-> obj option-index) option-type) + (((game-option-type slider)) + (cond + ((>= (+ -1.0 (-> s5-0 (-> obj option-index) param2)) + (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + ) + (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (+ 1.0 (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify)))) ) - (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (+ 1.0 (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - (set! v1-263 #t) - ) - ((< (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> s5-0 (-> obj option-index) param2) - ) - (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> s5-0 (-> obj option-index) param2) - ) - (set! v1-263 #t) - ) - ) + (set! v1-263 #t) + ) + ((< (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (-> s5-0 (-> obj option-index) param2) + ) + (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (-> s5-0 (-> obj option-index) param2) + ) + (set! v1-263 #t) + ) ) - ((= a0-177 3) - (when (< (-> *setting-control* default screenx) 96) - (set! v1-263 #t) - (+! (-> *setting-control* default screenx) 1) - ) + ) + (((game-option-type center-screen)) + (when (< (-> *setting-control* default screenx) 96) + (set! v1-263 #t) + (+! (-> *setting-control* default screenx) 1) ) - ) + ) ) (when v1-263 (let ((f30-1 100.0)) @@ -1507,38 +1500,36 @@ ((or (cpad-pressed? 0 square) (cpad-pressed? 0 triangle)) (cond ((-> obj selected-option) - (let ((v1-319 (-> s5-0 (-> obj option-index) option-type))) - (cond - ((zero? v1-319) - (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> *progress-state* slider-backup) - ) - ) - ((= v1-319 1) - (set! (-> (the-as (pointer int64) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> *progress-state* language-backup) - ) - ) - ((= v1-319 2) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> *progress-state* on-off-backup) - ) - ) - ((= v1-319 3) - (set! (-> *setting-control* default screenx) (-> *progress-state* center-x-backup)) - (set! (-> *setting-control* default screeny) (-> *progress-state* center-y-backup)) - ) - ((or (= v1-319 4) (= v1-319 5)) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> *progress-state* aspect-ratio-backup) - ) - ) - ) + (case (-> s5-0 (-> obj option-index) option-type) + (((game-option-type slider)) + (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (-> *progress-state* slider-backup) + ) + ) + (((game-option-type language)) + (set! (-> (the-as (pointer language-enum) (-> s5-0 (-> obj option-index) value-to-modify))) + (-> *progress-state* language-backup) + ) + ) + (((game-option-type on-off)) + (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) + (-> *progress-state* on-off-backup) + ) + ) + (((game-option-type center-screen)) + (set! (-> *setting-control* default screenx) (-> *progress-state* center-x-backup)) + (set! (-> *setting-control* default screeny) (-> *progress-state* center-y-backup)) + ) + (((game-option-type aspect-ratio) (game-option-type video-mode)) + (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) + (-> *progress-state* aspect-ratio-backup) + ) + ) ) (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) (set! (-> obj selected-option) #f) ) - ((or (dummy-32 obj) + ((or (can-go-back? obj) (= (-> obj display-state) (progress-screen load-game)) (= (-> obj display-state) (progress-screen save-game)) (= (-> obj display-state) (progress-screen save-game-title)) @@ -1560,7 +1551,7 @@ (cond ((not (-> obj selected-option)) (cond - ((= (-> s5-0 (-> obj option-index) option-type) 6) + ((= (-> s5-0 (-> obj option-index) option-type) (game-option-type menu)) (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons x)) (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons x)) (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons circle)) @@ -1570,11 +1561,11 @@ (set! (-> obj next-display-state) (the-as progress-screen (-> s5-0 (-> obj option-index) param3))) (case (-> obj next-display-state) (((progress-screen load-game) (progress-screen save-game) (progress-screen save-game-title)) - (set! (-> obj next-display-state) (dummy-53 obj (-> obj next-display-state))) + (set! (-> obj next-display-state) (set-memcard-screen obj (-> obj next-display-state))) ) ) ) - ((= (-> s5-0 (-> obj option-index) option-type) 8) + ((= (-> s5-0 (-> obj option-index) option-type) (game-option-type button)) (cond ((= (-> s5-0 (-> obj option-index) name) (game-text-id exit-demo)) (set! *master-exit* 'force) @@ -1590,34 +1581,32 @@ ) ) ) - ((!= (-> s5-0 (-> obj option-index) option-type) 7) - (let ((v1-427 (-> s5-0 (-> obj option-index) option-type))) - (cond - ((zero? v1-427) - (set! (-> *progress-state* slider-backup) - (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - ) - ) - ((= v1-427 1) - (set! (-> *progress-state* language-backup) - (the-as int (-> (the-as (pointer uint64) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - ) - ((= v1-427 2) - (set! (-> *progress-state* on-off-backup) - (the-as symbol (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - ) - ((= v1-427 3) - (set! (-> *progress-state* center-x-backup) (-> *setting-control* default screenx)) - (set! (-> *progress-state* center-y-backup) (-> *setting-control* default screeny)) - ) - ((or (= v1-427 4) (= v1-427 5)) - (set! (-> *progress-state* aspect-ratio-backup) - (the-as symbol (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - ) - ) + ((!= (-> s5-0 (-> obj option-index) option-type) (game-option-type yes-no)) + (case (-> s5-0 (-> obj option-index) option-type) + (((game-option-type slider)) + (set! (-> *progress-state* slider-backup) + (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + ) + ) + (((game-option-type language)) + (set! (-> *progress-state* language-backup) + (-> (the-as (pointer language-enum) (-> s5-0 (-> obj option-index) value-to-modify))) + ) + ) + (((game-option-type on-off)) + (set! (-> *progress-state* on-off-backup) + (the-as symbol (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) + ) + ) + (((game-option-type center-screen)) + (set! (-> *progress-state* center-x-backup) (-> *setting-control* default screenx)) + (set! (-> *progress-state* center-y-backup) (-> *setting-control* default screeny)) + ) + (((game-option-type aspect-ratio) (game-option-type video-mode)) + (set! (-> *progress-state* aspect-ratio-backup) + (the-as symbol (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) + ) + ) ) (sound-play-by-name (static-sound-name "select-option") (new-sound-id) 1024 0 0 1 #t) (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons x)) @@ -1625,8 +1614,8 @@ (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons circle)) (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons circle)) (set! (-> obj selected-option) #t) - (when (= (-> s5-0 (-> obj option-index) option-type) 1) - (set! (-> obj language-selection) (the-as uint (-> *setting-control* current language))) + (when (= (-> s5-0 (-> obj option-index) option-type) (game-option-type language)) + (set! (-> obj language-selection) (-> *setting-control* current language)) (set! (-> obj language-direction) #t) (set! (-> obj language-transition) #f) (set! (-> obj language-x-offset) 0) @@ -1639,12 +1628,12 @@ (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) (set! (-> obj selected-option) #f) (case (-> s5-0 (-> obj option-index) option-type) - ((4) + (((game-option-type aspect-ratio)) (set! (-> *setting-control* default aspect-ratio) (the-as symbol (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) ) ) - ((5) + (((game-option-type video-mode)) (case (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify))) (('pal) (set! (-> *setting-control* default video-mode) @@ -1657,7 +1646,7 @@ ) ) ) - ((1) + (((game-option-type language)) (if (not (-> obj language-transition)) (load-level-text-files (-> obj display-level-index)) ) @@ -1992,7 +1981,7 @@ (case (-> self display-state) (((progress-screen fuel-cell) (progress-screen money) (progress-screen buzzer)) (let ((s5-0 (-> self display-level-index))) - (when (and (< (mod (-> *display* real-frame-counter) 60) 30) + (when (and (< (mod (-> *display* real-frame-counter) (seconds 0.2)) (seconds 0.1)) (zero? (-> *progress-process* 0 in-out-position)) (not (-> self in-transition)) (zero? (-> self transition-offset)) @@ -2017,8 +2006,8 @@ ) ) ) - (dummy-29 self) - (set! (-> self next-display-state) (dummy-53 self (-> self next-display-state))) + (respond-common self) + (set! (-> self next-display-state) (set-memcard-screen self (-> self next-display-state))) (let ((v1-74 (-> self display-state))) (cond ((or (= v1-74 (progress-screen fuel-cell)) @@ -2049,7 +2038,7 @@ (= v1-74 (progress-screen bad-disc)) (= v1-74 (progress-screen quit)) ) - (dummy-31 self) + (respond-memcard self) ) ) ) @@ -2061,158 +2050,157 @@ (behavior () (let* ((a1-0 (-> self display-level-index)) (gp-0 (-> *level-task-data* a1-0)) + (unk #t) + (s5-0 #f) ) - #t - (let ((s5-0 #f)) - (case (-> self display-state) - (((progress-screen fuel-cell)) - (set! s5-0 #t) - (draw-fuel-cell-screen self a1-0) - ) - (((progress-screen money)) - (set! s5-0 #t) - (draw-money-screen self a1-0) - ) - (((progress-screen buzzer)) - (set! s5-0 #t) - (draw-buzzer-screen self a1-0) - ) - (((progress-screen game-settings) (progress-screen settings)) - (hide-progress-icons) - (draw-options self 115 30 0.82) - ) - (((progress-screen graphic-settings) - (progress-screen sound-settings) - (progress-screen settings-title) - (progress-screen title) - ) - (hide-progress-icons) - (draw-options self 115 30 0.82) - ) - (((progress-screen memcard-removed) (progress-screen memcard-auto-save-error)) - (draw-notice-screen self) - (draw-options self 192 0 0.82) - ) - (((progress-screen memcard-no-data)) - (draw-notice-screen self) - (draw-options self 165 0 0.82) - ) - (((progress-screen memcard-format)) - (draw-notice-screen self) - (draw-options self 172 0 0.82) - ) - (((progress-screen memcard-no-space) - (progress-screen memcard-not-inserted) - (progress-screen memcard-not-formatted) - ) - (draw-notice-screen self) - (draw-options self 195 0 0.82) - ) - (((progress-screen memcard-error-loading) - (progress-screen memcard-error-saving) - (progress-screen memcard-error-formatting) - (progress-screen memcard-error-creating) - (progress-screen memcard-auto-save-error) - ) - (draw-notice-screen self) - (draw-options self 190 0 0.82) - ) - (((progress-screen pal-change-to-60hz)) - (draw-notice-screen self) - (draw-options self 190 0 0.82) - ) - (((progress-screen pal-now-60hz)) - (when (< (seconds 10) (- (-> *display* real-frame-counter) (-> self video-mode-timeout))) - (set! (-> *progress-state* video-mode-choice) 'pal) - (set! (-> *setting-control* default video-mode) (-> *progress-state* video-mode-choice)) - (set! (-> self next-display-state) (progress-screen invalid)) - ) - (draw-notice-screen self) - (draw-options self 140 0 0.82) - ) - (((progress-screen no-disc) (progress-screen bad-disc)) - (draw-notice-screen self) - (if (is-cd-in?) - (draw-options self 170 0 0.82) - ) - ) - (((progress-screen quit)) - (draw-notice-screen self) - (draw-options self 110 0 0.82) - ) - (((progress-screen auto-save)) - (draw-notice-screen self) - (draw-options self 190 0 0.82) - ) - (((progress-screen memcard-insert)) - (draw-notice-screen self) - (draw-options self 165 0 0.82) - ) - (((progress-screen memcard-data-exists)) - (draw-notice-screen self) - (draw-options self 168 0 0.82) - ) - (((progress-screen memcard-loading) - (progress-screen memcard-saving) - (progress-screen memcard-formatting) - (progress-screen memcard-creating) - ) - (draw-notice-screen self) - ) - (((progress-screen load-game) (progress-screen save-game)) - (draw-notice-screen self) - (draw-options self 190 0 0.82) - ) - (((progress-screen save-game-title)) - (draw-notice-screen self) - (draw-options self 169 15 0.6) - ) + (case (-> self display-state) + (((progress-screen fuel-cell)) + (set! s5-0 #t) + (draw-fuel-cell-screen self a1-0) + ) + (((progress-screen money)) + (set! s5-0 #t) + (draw-money-screen self a1-0) + ) + (((progress-screen buzzer)) + (set! s5-0 #t) + (draw-buzzer-screen self a1-0) + ) + (((progress-screen game-settings) (progress-screen settings)) + (hide-progress-icons) + (draw-options self 115 30 0.82) + ) + (((progress-screen graphic-settings) + (progress-screen sound-settings) + (progress-screen settings-title) + (progress-screen title) ) - (when s5-0 - (let* ((v1-98 (cond - ((-> self stat-transition) - 0 - ) - ((= (-> self level-transition) 1) - (- (-> self transition-offset)) - ) - (else - (-> self transition-offset) - ) + (hide-progress-icons) + (draw-options self 115 30 0.82) + ) + (((progress-screen memcard-removed) (progress-screen memcard-auto-save-error)) + (draw-notice-screen self) + (draw-options self 192 0 0.82) + ) + (((progress-screen memcard-no-data)) + (draw-notice-screen self) + (draw-options self 165 0 0.82) + ) + (((progress-screen memcard-format)) + (draw-notice-screen self) + (draw-options self 172 0 0.82) + ) + (((progress-screen memcard-no-space) + (progress-screen memcard-not-inserted) + (progress-screen memcard-not-formatted) + ) + (draw-notice-screen self) + (draw-options self 195 0 0.82) + ) + (((progress-screen memcard-error-loading) + (progress-screen memcard-error-saving) + (progress-screen memcard-error-formatting) + (progress-screen memcard-error-creating) + (progress-screen memcard-auto-save-error) + ) + (draw-notice-screen self) + (draw-options self 190 0 0.82) + ) + (((progress-screen pal-change-to-60hz)) + (draw-notice-screen self) + (draw-options self 190 0 0.82) + ) + (((progress-screen pal-now-60hz)) + (when (< (seconds 10) (- (-> *display* real-frame-counter) (-> self video-mode-timeout))) + (set! (-> *progress-state* video-mode-choice) 'pal) + (set! (-> *setting-control* default video-mode) (-> *progress-state* video-mode-choice)) + (set! (-> self next-display-state) (progress-screen invalid)) + ) + (draw-notice-screen self) + (draw-options self 140 0 0.82) + ) + (((progress-screen no-disc) (progress-screen bad-disc)) + (draw-notice-screen self) + (if (is-cd-in?) + (draw-options self 170 0 0.82) + ) + ) + (((progress-screen quit)) + (draw-notice-screen self) + (draw-options self 110 0 0.82) + ) + (((progress-screen auto-save)) + (draw-notice-screen self) + (draw-options self 190 0 0.82) + ) + (((progress-screen memcard-insert)) + (draw-notice-screen self) + (draw-options self 165 0 0.82) + ) + (((progress-screen memcard-data-exists)) + (draw-notice-screen self) + (draw-options self 168 0 0.82) + ) + (((progress-screen memcard-loading) + (progress-screen memcard-saving) + (progress-screen memcard-formatting) + (progress-screen memcard-creating) + ) + (draw-notice-screen self) + ) + (((progress-screen load-game) (progress-screen save-game)) + (draw-notice-screen self) + (draw-options self 190 0 0.82) + ) + (((progress-screen save-game-title)) + (draw-notice-screen self) + (draw-options self 169 15 0.6) + ) + ) + (when s5-0 + (let* ((v1-98 (cond + ((-> self stat-transition) + 0 + ) + ((= (-> self level-transition) 1) + (- (-> self transition-offset)) + ) + (else + (-> self transition-offset) ) ) - (f30-0 (the-as float (if (-> self stat-transition) - 1.0 - (-> self transition-percentage-invert) - ) - ) - ) - (s5-1 - (new - 'stack - 'font-context - *font-default-matrix* - (- 32 (-> self left-x-offset)) - (the int (* (+ 42.0 (the float (/ v1-98 2))) f30-0)) - 8325000.0 - (font-color lighter-lighter-blue) - (font-flags shadow kerning) - ) + ) + (f30-0 (the-as float (if (-> self stat-transition) + 1.0 + (-> self transition-percentage-invert) + ) + ) + ) + (s5-1 + (new + 'stack + 'font-context + *font-default-matrix* + (- 32 (-> self left-x-offset)) + (the int (* (+ 42.0 (the float (/ v1-98 2))) f30-0)) + 8325000.0 + (font-color lighter-lighter-blue) + (font-flags shadow kerning) ) ) - (let ((v1-103 s5-1)) - (set! (-> v1-103 width) (the float 328)) - ) - (let ((v1-104 s5-1)) - (set! (-> v1-104 height) (the float 45)) - ) - (set! (-> s5-1 flags) (font-flags shadow kerning middle left large)) - (print-game-text-scaled - (lookup-text! *common-text* (-> gp-0 level-name-id) #f) - f30-0 - s5-1 - (the int (* 128.0 f30-0)) - ) + ) + (let ((v1-103 s5-1)) + (set! (-> v1-103 width) (the float 328)) + ) + (let ((v1-104 s5-1)) + (set! (-> v1-104 height) (the float 45)) + ) + (set! (-> s5-1 flags) (font-flags shadow kerning middle left large)) + (print-game-text-scaled + (lookup-text! *common-text* (-> gp-0 level-name-id) #f) + f30-0 + s5-1 + (the int (* 128.0 f30-0)) ) ) ) diff --git a/goal_src/engine/ui/text-h.gc b/goal_src/engine/ui/text-h.gc index 62252845c5..3e444f6c2f 100644 --- a/goal_src/engine/ui/text-h.gc +++ b/goal_src/engine/ui/text-h.gc @@ -455,11 +455,73 @@ (inc #xf10) (europe #xf11) + + ;; extra IDs for pc port + (camera-options #x1000) + (normal #x1001) + (inverted #x1002) + (camera-controls-horz #x1003) + (camera-controls-vert #x1004) + (misc-options #x100f) + (accessibility-options #x1010) + (money-starburst #x1011) + (ps2-options #x1020) + (ps2-load-speed #x1021) + (ps2-parts #x1022) + (discord-rpc #x1030) + (display-mode #x1031) + (windowed #x1032) + (borderless #x1033) + (fullscreen #x1034) + (game-resolution #x1035) + (resolution-fmt #x1036) + (ps2-aspect-ratio #x1037) + (ps2-aspect-ratio-msg #x1038) + (aspect-ratio-ps2 #x1039) + (fit-to-screen #x103a) + (msaa #x1050) + (x-times-fmt #x1051) + (2-times #x1052) + (4-times #x1053) + (8-times #x1054) + (16-times #x1055) + (frame-rate #x1060) + (lod-bg #x1070) + (lod-fg #x1071) + (lod-highest #x1072) + (lod-high #x1073) + (lod-mid #x1074) + (lod-low #x1075) + (lod-lowest #x1076) + (lod-ps2 #x1077) + (subtitles #x1078) + (hinttitles #x1079) + (subtitles-language #x107a) + (subtitles-speaker #x107b) + (speaker-always #x107c) + (speaker-never #x107d) + (speaker-auto #x107e) + (hint-log #x107f) + (cheats #x1080) + (cheat-eco-blue #x1090) + (cheat-eco-red #x1091) + (cheat-eco-green #x1092) + (cheat-eco-yellow #x1093) + (cheat-sidekick-alt #x1094) + (cheat-invinc #x1095) + (music-player #x10c0) + (scene-player #x10c1) + (play-credits #x10c2) + (scrapbook #x10c3) + (scene-0 #x1100) + (scene-255 #x11ff) + (hint-0 #x1200) + (hint-511 #x13ff) ;; GAME-TEXT-ID ENUM ENDS ) -;; an individual string. +;; an individual string. (deftype game-text (structure) ((id game-text-id :offset-assert 0) (text string :offset-assert 4) diff --git a/goal_src/engine/ui/text.gc b/goal_src/engine/ui/text.gc index 77749e9a16..fa4e903234 100644 --- a/goal_src/engine/ui/text.gc +++ b/goal_src/engine/ui/text.gc @@ -647,6 +647,9 @@ (set! (-> *video-parms* relative-y-scale) sv-124) (set! (-> *video-parms* relative-x-scale-reciprical) sv-128) (set! (-> *video-parms* relative-y-scale-reciprical) sv-132) + (with-pc + (if (and *debug-segment* (-> *pc-settings* display-text-box)) + (draw-debug-text-box font-ctxt))) (if (> sv-168 0) (* sv-164 (the float sv-168)) 0.0 diff --git a/goal_src/game.gp b/goal_src/game.gp index 2a75dfb9a0..672aed5602 100644 --- a/goal_src/game.gp +++ b/goal_src/game.gp @@ -324,7 +324,7 @@ ;; Text ;;;;;;;;;;;;;;;;;;;;; -(defstep :in "assets/game_text.txt" +(defstep :in "game/assets/game_text.gp" :tool 'text :out '("out/iso/0COMMON.TXT" "out/iso/1COMMON.TXT" @@ -335,7 +335,7 @@ "out/iso/6COMMON.TXT") ) -(defstep :in "game/assets/game_subtitle.txt" +(defstep :in "game/assets/game_subtitle.gp" :tool 'subtitle :out '("out/iso/0SUBTIT.TXT" "out/iso/3SUBTIT.TXT" @@ -1632,6 +1632,7 @@ "gfx/decomp-h.gc" "gfx/hw/display.gc" "engine/connect.gc" + "ui/text-h.gc" "game/settings-h.gc" "gfx/capture.gc" "debug/memory-usage-h.gc" @@ -1721,6 +1722,7 @@ "camera/cam-update-h.gc" "debug/assert-h.gc" "ui/hud-h.gc" + "ui/progress-h.gc" "ps2/rpc-h.gc" "nav/path-h.gc" "nav/navigate-h.gc" @@ -1854,7 +1856,10 @@ "game/crates.gc" "ui/hud.gc" "ui/hud-classes.gc" + "ui/progress/progress-static.gc" "ui/progress/progress-part.gc" + "ui/progress/progress-draw.gc" + "ui/progress/progress.gc" "ui/credits.gc" "game/projectiles.gc" "gfx/ocean/ocean.gc" @@ -1931,10 +1936,6 @@ (goal-src "pc/pckernel-h.gc" "dma-disasm") (goal-src "pc/pckernel.gc" "settings") (goal-src "pc/subtitle.gc" "text") +(goal-src "pc/progress-pc.gc" "progress" "pckernel") -(goal-src "pc/engine/ui/text-h.gc" "connect") -(goal-src "pc/engine/ui/progress-h.gc" "hud-h") -(goal-src "pc/engine/ui/progress/progress-static.gc" "hud-classes") -(goal-src "pc/engine/ui/progress/progress-draw.gc" "progress-part") -(goal-src "pc/engine/ui/progress/progress.gc" "progress-draw") diff --git a/goal_src/goal-lib.gc b/goal_src/goal-lib.gc index a359c54cd9..cc913939b3 100644 --- a/goal_src/goal-lib.gc +++ b/goal_src/goal-lib.gc @@ -535,7 +535,7 @@ ) (defmacro 1-! (place) - `(set! ,place (- 1 ,place)) + `(set! ,place (+ -1 ,place)) ) (defmacro *! (place amount) diff --git a/goal_src/goos-lib.gs b/goal_src/goos-lib.gs index 8a29a18b0b..1acae5258a 100644 --- a/goal_src/goos-lib.gs +++ b/goal_src/goos-lib.gs @@ -377,7 +377,7 @@ (desfun enum-max (enum) "get the highest value in an enum" - (let ((max-val -999999999)) + (let ((max-val -999999999999)) (doenum (name val enum) (when (> val max-val) (set! max-val val)) diff --git a/goal_src/kernel-defs.gc b/goal_src/kernel-defs.gc index d3d445f536..2fa9b2d728 100644 --- a/goal_src/kernel-defs.gc +++ b/goal_src/kernel-defs.gc @@ -326,12 +326,14 @@ (define-extern pc-pad-input-index-get (function int)) (define-extern pc-pad-input-map-save! (function none)) (define-extern pc-pad-get-mapped-button (function int int int)) +(define-extern pc-get-fullscreen (function symbol)) +(define-extern pc-get-screen-size (function int (pointer int32) (pointer int32) (pointer int32) none)) (define-extern pc-get-os (function symbol)) (define-extern pc-get-window-size (function (pointer int32) (pointer int32) none)) (define-extern pc-get-window-scale (function (pointer float) (pointer float) none)) (define-extern pc-set-window-size (function int int none)) (define-extern pc-set-letterbox (function int int none)) -(define-extern pc-set-fullscreen (function int int none)) +(define-extern pc-set-fullscreen (function symbol int none)) (define-extern pc-renderer-tree-set-lod (function pc-renderer-tree-type int none)) (define-extern pc-discord-rpc-update (function discord-info none)) (define-extern pc-discord-rpc-set (function int none)) diff --git a/goal_src/levels/beach/lurkercrab.gc b/goal_src/levels/beach/lurkercrab.gc index 15b0620348..ce18412444 100644 --- a/goal_src/levels/beach/lurkercrab.gc +++ b/goal_src/levels/beach/lurkercrab.gc @@ -80,7 +80,7 @@ ) (defmethod dummy-44 lurkercrab ((obj lurkercrab) (arg0 process) (arg1 event-message-block)) - (if (and (logtest? (-> obj nav-enemy-flags) 64) + (if (and (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf6)) ((method-of-type touching-shapes-entry prims-touching?) (the-as touching-shapes-entry (-> arg1 param 0)) (-> obj collide-info) @@ -97,7 +97,7 @@ 6144.0 16384.0 ) - (the-as object (if (zero? (logand (-> obj nav-enemy-flags) 256)) + (the-as object (if (zero? (logand (-> obj nav-enemy-flags) (nav-enemy-flags navenmf8))) (do-push-aways! (-> obj collide-info)) ) ) @@ -114,7 +114,7 @@ ) ((= v1-1 'punch) (cond - ((logtest? (-> obj nav-enemy-flags) 32) + ((logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf5)) (logclear! (-> obj mask) (process-mask actor-pause)) (go (method-of-object obj nav-enemy-die)) ) @@ -136,7 +136,7 @@ ) ) ) - ((logtest? (-> obj nav-enemy-flags) 32) + ((logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf5)) (logclear! (-> obj mask) (process-mask actor-pause)) (go (method-of-object obj nav-enemy-die)) ) @@ -164,7 +164,7 @@ nav-enemy-default-event-handler (defmethod TODO-RENAME-37 lurkercrab ((obj lurkercrab)) (when (-> obj orient) - (if (logtest? (nav-control-flags bit19) (-> obj nav flags)) + (if (logtest? (nav-control-flags navcf19) (-> obj nav flags)) (seek-to-point-toward-point! (-> obj collide-info) (-> obj nav target-pos) @@ -275,7 +275,7 @@ nav-enemy-default-event-handler ) (defbehavior lurkercrab-invulnerable lurkercrab () - (set! (-> self nav-enemy-flags) (logand -33 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf5)) (let ((v1-3 (find-prim-by-id (-> self collide-info) (the-as uint 2)))) (when v1-3 (let ((v0-1 4)) @@ -287,7 +287,7 @@ nav-enemy-default-event-handler ) (defbehavior lurkercrab-vulnerable lurkercrab () - (logior! (-> self nav-enemy-flags) 32) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf5)) (let ((v1-3 (find-prim-by-id (-> self collide-info) (the-as uint 2)))) (when v1-3 (let ((v0-1 1)) @@ -308,8 +308,8 @@ nav-enemy-default-event-handler :exit (behavior () (lurkercrab-invulnerable) - (set! (-> self nav-enemy-flags) (logand -65 (-> self nav-enemy-flags))) - (logior! (-> self nav-enemy-flags) 8) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf6)) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (none) ) :code @@ -364,7 +364,7 @@ nav-enemy-default-event-handler (joint-control-channel-group! a0-12 (the-as art-joint-anim #f) num-func-loop!) ) (ja-channel-push! 1 180) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (nav-enemy-rnd-int-range 2 6) (until (not (nav-enemy-rnd-go-idle? 0.2)) (let ((gp-1 (-> self skel root-channel 0))) @@ -381,7 +381,7 @@ nav-enemy-default-event-handler ) ) ) - (logior! (-> self nav-enemy-flags) 8) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (let ((a0-19 (-> self skel root-channel 0))) (set! (-> a0-19 frame-group) (the-as art-joint-anim (-> self draw art-group data 5))) (set! (-> a0-19 param 0) @@ -416,7 +416,7 @@ nav-enemy-default-event-handler ) ) (lurkercrab-vulnerable) - (logior! (-> self nav-enemy-flags) 64) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf6)) (dotimes (gp-5 2) (let ((s5-0 (-> self skel root-channel 0))) (set! (-> s5-0 frame-group) (the-as art-joint-anim (-> self draw art-group data 7))) @@ -435,7 +435,7 @@ nav-enemy-default-event-handler ) ) (lurkercrab-invulnerable) - (set! (-> self nav-enemy-flags) (logand -65 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf6)) (let ((gp-6 (-> self skel root-channel 0))) (set! (-> gp-6 frame-group) (the-as art-joint-anim (-> self draw art-group data 8))) (set! (-> gp-6 param 0) (ja-aframe 90.0 0)) @@ -480,7 +480,7 @@ nav-enemy-default-event-handler :exit (behavior () (lurkercrab-invulnerable) - (set! (-> self nav-enemy-flags) (logand -65 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf6)) (none) ) :trans @@ -495,7 +495,7 @@ nav-enemy-default-event-handler ) :code (behavior () - (logior! (-> self nav-enemy-flags) 8) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (ja-channel-push! 1 22) (while #t (let ((a0-1 (-> self skel root-channel 0))) @@ -516,7 +516,7 @@ nav-enemy-default-event-handler ) ) (lurkercrab-vulnerable) - (logior! (-> self nav-enemy-flags) 64) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf6)) (let ((gp-0 (-> self skel root-channel 0))) (set! (-> gp-0 frame-group) (the-as art-joint-anim (-> self draw art-group data 7))) (set! (-> gp-0 param 0) (ja-aframe 30.0 0)) @@ -578,7 +578,7 @@ nav-enemy-default-event-handler ) ) (lurkercrab-invulnerable) - (set! (-> self nav-enemy-flags) (logand -65 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf6)) (let ((gp-8 (-> self skel root-channel 0))) (set! (-> gp-8 frame-group) (the-as art-joint-anim (-> self draw art-group data 8))) (set! (-> gp-8 param 0) (ja-aframe 90.0 0)) @@ -792,7 +792,7 @@ nav-enemy-default-event-handler :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -845,7 +845,7 @@ nav-enemy-default-event-handler (TODO-RENAME-45 obj *lurkercrab-nav-enemy-info*) (set! (-> obj part) (create-launch-control (-> *part-group-id-table* 159) obj)) (set! (-> obj orient) #t) - (set! (-> obj nav-enemy-flags) (logand -97 (-> obj nav-enemy-flags))) + (logclear! (-> obj nav-enemy-flags) (nav-enemy-flags navenmf5 navenmf6)) (set! (-> obj target-speed) 0.0) (set! (-> obj momentum-speed) 0.0) (set! (-> obj draw force-lod) 2) diff --git a/goal_src/levels/beach/lurkerpuppy.gc b/goal_src/levels/beach/lurkerpuppy.gc index dfa78fa277..5ac4077323 100644 --- a/goal_src/levels/beach/lurkerpuppy.gc +++ b/goal_src/levels/beach/lurkerpuppy.gc @@ -117,7 +117,7 @@ nav-enemy-default-event-handler (joint-control-channel-group! a0-14 (the-as art-joint-anim (-> self draw art-group data 7)) num-func-seek!) ) (until (ja-done? 0) - (if (logtest? (-> self nav-enemy-flags) 256) + (if (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (go-virtual nav-enemy-attack) ) (suspend) @@ -144,10 +144,10 @@ nav-enemy-default-event-handler (behavior () (set! (-> self rotate-speed) 1456355.5) (set! (-> self turn-time) (seconds 0.1)) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((f30-0 (rand-vu-float-range 0.8 1.2))) (while #t - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (ja-channel-push! 1 30) (let ((gp-0 (-> self skel root-channel 0))) (set! (-> gp-0 frame-group) (the-as art-joint-anim (-> self draw art-group data 8))) @@ -158,9 +158,9 @@ nav-enemy-default-event-handler ) (until (ja-done? 0) (let ((f0-3 (ja-aframe-num 0))) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (if (and (>= f0-3 2.5) (>= 7.5 f0-3)) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) ) ) (suspend) @@ -170,7 +170,7 @@ nav-enemy-default-event-handler (joint-control-channel-group-eval! gp-1 (the-as art-joint-anim #f) num-func-seek!) ) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((a0-11 (-> self skel root-channel 0))) (set! (-> a0-11 param 0) 1.0) (joint-control-channel-group! a0-11 (the-as art-joint-anim #f) num-func-loop!) @@ -230,7 +230,7 @@ nav-enemy-default-event-handler (joint-control-channel-group-eval! a0-2 (the-as art-joint-anim #f) num-func-seek!) ) ) - (logclear! (-> self nav flags) (nav-control-flags bit17 bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf17 navcf19)) (nav-enemy-get-new-patrol-point) (let ((a0-7 (-> self skel root-channel 0))) (set! (-> a0-7 frame-group) (the-as art-joint-anim (-> self draw art-group data 5))) @@ -284,12 +284,12 @@ nav-enemy-default-event-handler ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (none) ) :code (behavior () - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (ja-channel-push! 1 22) (dotimes (gp-0 4) (let ((a0-2 (-> self skel root-channel 0))) @@ -303,9 +303,9 @@ nav-enemy-default-event-handler ) (until (ja-done? 0) (let ((f0-4 (ja-aframe-num 0))) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (if (and (>= f0-4 2.5) (>= 7.5 f0-4)) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) ) ) (suspend) @@ -371,7 +371,7 @@ nav-enemy-default-event-handler :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/goal_src/levels/citadel/citb-bunny.gc b/goal_src/levels/citadel/citb-bunny.gc index c44db07cdb..c6ae091fba 100644 --- a/goal_src/levels/citadel/citb-bunny.gc +++ b/goal_src/levels/citadel/citb-bunny.gc @@ -75,7 +75,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/goal_src/levels/common/babak.gc b/goal_src/levels/common/babak.gc index 4a09e372f6..7f988518fc 100644 --- a/goal_src/levels/common/babak.gc +++ b/goal_src/levels/common/babak.gc @@ -139,7 +139,7 @@ (behavior () (set! (-> self turn-time) (seconds 0.2)) (let ((f30-0 (nav-enemy-rnd-float-range 0.8 1.2))) - (when (or (logtest? (-> self nav-enemy-flags) 256) + (when (or (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (and (nav-enemy-player-vulnerable?) (nav-enemy-rnd-percent? 0.5)) ) (ja-channel-push! 1 30) @@ -161,7 +161,7 @@ ) (while #t (when (not (nav-enemy-facing-player? 2730.6667)) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((a0-9 (-> self skel root-channel 0))) (set! (-> a0-9 param 0) 1.0) (joint-control-channel-group! a0-9 (the-as art-joint-anim #f) num-func-loop!) @@ -182,7 +182,7 @@ (joint-control-channel-group-eval! a0-15 (the-as art-joint-anim #f) num-func-loop!) ) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) ) (if (not (= (if (> (-> self skel active-channels) 0) (-> self skel root-channel 0 frame-group) @@ -267,7 +267,7 @@ ) ) ) - (logclear! (-> self nav flags) (nav-control-flags bit17 bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf17 navcf19)) (nav-enemy-get-new-patrol-point) (let ((a0-12 (-> self skel root-channel 0))) (set! (-> a0-12 frame-group) (the-as art-joint-anim (-> self draw art-group data 10))) @@ -383,7 +383,7 @@ :use-proximity-notice #t :use-jump-blocked #t :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/goal_src/levels/common/battlecontroller.gc b/goal_src/levels/common/battlecontroller.gc index 13b9dcdb1c..6ee31768f0 100644 --- a/goal_src/levels/common/battlecontroller.gc +++ b/goal_src/levels/common/battlecontroller.gc @@ -150,7 +150,7 @@ battlecontroller-default-event-handler (let* ((s5-0 (-> self spawner-array gp-0)) (s4-0 (handle->process (-> s5-0 creature))) ) - (when (and s4-0 (logtest? (-> (the-as nav-enemy s4-0) nav-enemy-flags) 2048)) + (when (and s4-0 (logtest? (-> (the-as nav-enemy s4-0) nav-enemy-flags) (nav-enemy-flags navenmf11))) (cond ((< (-> s5-0 state) (-> s5-0 path curve num-cverts)) (when (or (-> self noticed-player) (= (-> s5-0 state) 1)) @@ -158,7 +158,7 @@ battlecontroller-default-event-handler (eval-path-curve-div! (-> s5-0 path) s3-0 (the float (-> s5-0 state)) 'interp) (send-event s4-0 'cue-jump-to-point s3-0) ) - (if (zero? (logand (-> (the-as nav-enemy s4-0) nav-enemy-flags) 2048)) + (if (zero? (logand (-> (the-as nav-enemy s4-0) nav-enemy-flags) (nav-enemy-flags navenmf11))) (+! (-> s5-0 state) 1) ) ) @@ -206,7 +206,7 @@ battlecontroller-default-event-handler (when (the-as (pointer nav-enemy) gp-0) (logclear! (-> (the-as (pointer nav-enemy) gp-0) 0 mask) (process-mask actor-pause)) (if (-> self misty-ambush-collision-hack) - (logior! (-> (the-as (pointer nav-enemy) gp-0) 0 nav-enemy-flags) #x8000) + (logior! (-> (the-as (pointer nav-enemy) gp-0) 0 nav-enemy-flags) (nav-enemy-flags navenmf15)) ) (+! (-> self spawn-count) 1) (-> self fact pickup-type) diff --git a/goal_src/levels/common/joint-exploder.gc b/goal_src/levels/common/joint-exploder.gc index feace80fbe..09ef5dabeb 100644 --- a/goal_src/levels/common/joint-exploder.gc +++ b/goal_src/levels/common/joint-exploder.gc @@ -412,7 +412,7 @@ (-> arg0 bbox) (collide-kind background) obj - (new 'static 'pat-surface :skip #x1 :noentity #x1) + (new 'static 'pat-surface :noentity #x1) ) (let ((gp-1 (-> obj joints)) (v1-2 (-> arg0 head)) diff --git a/goal_src/levels/common/nav-enemy-h.gc b/goal_src/levels/common/nav-enemy-h.gc index f245297a34..6ed761ad0a 100644 --- a/goal_src/levels/common/nav-enemy-h.gc +++ b/goal_src/levels/common/nav-enemy-h.gc @@ -11,60 +11,97 @@ (define-extern nav-enemy-get-new-patrol-point (function int :behavior nav-enemy)) (define-extern nav-enemy-test-point-near-nav-mesh? (function vector symbol :behavior nav-enemy)) +(defenum nav-enemy-flags + :bitfield #t + :type uint32 + (navenmf0 0) + (navenmf1 1) + (navenmf2 2) + (enable-rotate 3) + (enable-travel 4) + (navenmf5 5) + (navenmf6 6) + (navenmf7 7) + (navenmf8 8) + (standing-jump 9) + (drop-jump 10) + (navenmf11 11) + (navenmf12 12) + (navenmf13 13) + (navenmf14 14) + (navenmf15 15) + (navenmf16 16) + (navenmf17 17) + (navenmf18 18) + (navenmf19 19) + (navenmf20 20) + (navenmf21 21) + (navenmf22 22) + (navenmf23 23) + (navenmf24 24) + (navenmf25 25) + (navenmf26 26) + (navenmf27 27) + (navenmf28 28) + (navenmf29 29) + (navenmf30 30) + (navenmf31 31) + ) + ;; DECOMP BEGINS (deftype nav-enemy-info (basic) - ((idle-anim int32 :offset-assert 4) - (walk-anim int32 :offset-assert 8) - (turn-anim int32 :offset-assert 12) - (notice-anim int32 :offset-assert 16) - (run-anim int32 :offset-assert 20) - (jump-anim int32 :offset-assert 24) - (jump-land-anim int32 :offset-assert 28) - (victory-anim int32 :offset-assert 32) - (taunt-anim int32 :offset-assert 36) - (die-anim int32 :offset-assert 40) - (neck-joint int32 :offset-assert 44) - (player-look-at-joint int32 :offset-assert 48) - (run-travel-speed meters :offset-assert 52) - (run-rotate-speed degrees :offset-assert 56) - (run-acceleration meters :offset-assert 60) - (run-turn-time seconds :offset-assert 64) - (walk-travel-speed meters :offset-assert 72) - (walk-rotate-speed degrees :offset-assert 76) - (walk-acceleration meters :offset-assert 80) - (walk-turn-time seconds :offset-assert 88) - (attack-shove-back meters :offset-assert 96) - (attack-shove-up meters :offset-assert 100) - (shadow-size meters :offset-assert 104) - (notice-nav-radius meters :offset-assert 108) - (nav-nearest-y-threshold meters :offset-assert 112) - (notice-distance meters :offset-assert 116) - (proximity-notice-distance meters :offset-assert 120) - (stop-chase-distance meters :offset-assert 124) - (frustration-distance meters :offset-assert 128) - (frustration-time time-frame :offset-assert 136) - (die-anim-hold-frame float :offset-assert 144) - (jump-anim-start-frame float :offset-assert 148) - (jump-land-anim-end-frame float :offset-assert 152) - (jump-height-min meters :offset-assert 156) - (jump-height-factor float :offset-assert 160) - (jump-start-anim-speed float :offset-assert 164) - (shadow-max-y meters :offset-assert 168) - (shadow-min-y meters :offset-assert 172) - (shadow-locus-dist meters :offset-assert 176) - (use-align symbol :offset-assert 180) - (draw-shadow symbol :offset-assert 184) - (move-to-ground symbol :offset-assert 188) - (hover-if-no-ground symbol :offset-assert 192) - (use-momentum symbol :offset-assert 196) - (use-flee symbol :offset-assert 200) - (use-proximity-notice symbol :offset-assert 204) - (use-jump-blocked symbol :offset-assert 208) - (use-jump-patrol symbol :offset-assert 212) - (gnd-collide-with uint64 :offset-assert 216) - (debug-draw-neck symbol :offset-assert 224) - (debug-draw-jump symbol :offset-assert 228) + ((idle-anim int32 :offset-assert 4) + (walk-anim int32 :offset-assert 8) + (turn-anim int32 :offset-assert 12) + (notice-anim int32 :offset-assert 16) + (run-anim int32 :offset-assert 20) + (jump-anim int32 :offset-assert 24) + (jump-land-anim int32 :offset-assert 28) + (victory-anim int32 :offset-assert 32) + (taunt-anim int32 :offset-assert 36) + (die-anim int32 :offset-assert 40) + (neck-joint int32 :offset-assert 44) + (player-look-at-joint int32 :offset-assert 48) + (run-travel-speed meters :offset-assert 52) + (run-rotate-speed degrees :offset-assert 56) + (run-acceleration meters :offset-assert 60) + (run-turn-time seconds :offset-assert 64) + (walk-travel-speed meters :offset-assert 72) + (walk-rotate-speed degrees :offset-assert 76) + (walk-acceleration meters :offset-assert 80) + (walk-turn-time seconds :offset-assert 88) + (attack-shove-back meters :offset-assert 96) + (attack-shove-up meters :offset-assert 100) + (shadow-size meters :offset-assert 104) + (notice-nav-radius meters :offset-assert 108) + (nav-nearest-y-threshold meters :offset-assert 112) + (notice-distance meters :offset-assert 116) + (proximity-notice-distance meters :offset-assert 120) + (stop-chase-distance meters :offset-assert 124) + (frustration-distance meters :offset-assert 128) + (frustration-time time-frame :offset-assert 136) + (die-anim-hold-frame float :offset-assert 144) + (jump-anim-start-frame float :offset-assert 148) + (jump-land-anim-end-frame float :offset-assert 152) + (jump-height-min meters :offset-assert 156) + (jump-height-factor float :offset-assert 160) + (jump-start-anim-speed float :offset-assert 164) + (shadow-max-y meters :offset-assert 168) + (shadow-min-y meters :offset-assert 172) + (shadow-locus-dist meters :offset-assert 176) + (use-align symbol :offset-assert 180) + (draw-shadow symbol :offset-assert 184) + (move-to-ground symbol :offset-assert 188) + (hover-if-no-ground symbol :offset-assert 192) + (use-momentum symbol :offset-assert 196) + (use-flee symbol :offset-assert 200) + (use-proximity-notice symbol :offset-assert 204) + (use-jump-blocked symbol :offset-assert 208) + (use-jump-patrol symbol :offset-assert 212) + (gnd-collide-with collide-kind :offset-assert 216) + (debug-draw-neck symbol :offset-assert 224) + (debug-draw-jump symbol :offset-assert 228) ) :method-count-assert 9 :size-assert #xe8 @@ -95,7 +132,7 @@ (state-timeout time-frame :offset-assert 352) (free-time time-frame :offset-assert 360) (touch-time time-frame :offset-assert 368) - (nav-enemy-flags uint32 :offset-assert 376) + (nav-enemy-flags nav-enemy-flags :offset-assert 376) (incomming-attack-id handle :offset-assert 384) (jump-return-state (state process) :offset-assert 392) (rand-gen random-generator :offset-assert 396) diff --git a/goal_src/levels/common/nav-enemy.gc b/goal_src/levels/common/nav-enemy.gc index ca28648a40..7641802bb9 100644 --- a/goal_src/levels/common/nav-enemy.gc +++ b/goal_src/levels/common/nav-enemy.gc @@ -74,14 +74,14 @@ ) (defmethod common-post nav-enemy ((obj nav-enemy)) - (when (and (logtest? (-> obj nav-enemy-flags) 256) + (when (and (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf8)) (or (not *target*) (and (zero? (logand (-> *target* state-flags) #x80f8)) (>= (- (-> *display* base-frame-counter) (-> obj touch-time)) (seconds 0.05)) ) ) ) (set-collide-offense (-> obj collide-info) 2 (collide-offense touch)) - (set! (-> obj nav-enemy-flags) (logand -257 (-> obj nav-enemy-flags))) + (logclear! (-> obj nav-enemy-flags) (nav-enemy-flags navenmf8)) ) (update-direction-from-time-of-day (-> obj draw shadow-ctrl)) (when *target* @@ -89,13 +89,13 @@ (look-at-enemy! (-> *target* neck) (the-as vector (-> obj collide-info root-prim prim-core)) - (if (logtest? (-> obj nav-enemy-flags) 4) + (if (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf2)) 'attacking ) obj ) ) - (if (and (nonzero? (-> obj neck)) (logtest? (-> obj nav-enemy-flags) #x4000)) + (if (and (nonzero? (-> obj neck)) (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf14))) (set-target! (-> obj neck) (target-pos (-> obj nav-info player-look-at-joint))) ) ) @@ -110,22 +110,24 @@ ) (defmethod dummy-44 nav-enemy ((obj nav-enemy) (arg0 process) (arg1 event-message-block)) - (if (and (logtest? (-> obj nav-enemy-flags) 64) ((method-of-type touching-shapes-entry prims-touching?) - (the-as touching-shapes-entry (-> arg1 param 0)) - (-> obj collide-info) - (the-as uint 1) - ) + (if (and (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf6)) + ((method-of-type touching-shapes-entry prims-touching?) + (the-as touching-shapes-entry (-> arg1 param 0)) + (-> obj collide-info) + (the-as uint 1) + ) ) (nav-enemy-send-attack arg0 (the-as touching-shapes-entry (-> arg1 param 0)) 'generic) ) ) (defmethod nav-enemy-touch-handler nav-enemy ((obj nav-enemy) (arg0 process) (arg1 event-message-block)) - (if (and (logtest? (-> obj nav-enemy-flags) 64) ((method-of-type touching-shapes-entry prims-touching?) - (the-as touching-shapes-entry (-> arg1 param 0)) - (-> obj collide-info) - (the-as uint 1) - ) + (if (and (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf6)) + ((method-of-type touching-shapes-entry prims-touching?) + (the-as touching-shapes-entry (-> arg1 param 0)) + (-> obj collide-info) + (the-as uint 1) + ) ) (nav-enemy-send-attack arg0 (the-as touching-shapes-entry (-> arg1 param 0)) 'generic) ) @@ -140,7 +142,7 @@ (defmethod dummy-43 nav-enemy ((obj nav-enemy) (arg0 process) (arg1 event-message-block)) (cond - ((logtest? (-> obj nav-enemy-flags) 32) + ((logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf5)) (send-event arg0 'get-attack-count 1) (logclear! (-> obj mask) (process-mask actor-pause attackable)) (go (method-of-object obj nav-enemy-die)) @@ -165,7 +167,7 @@ ) (the-as object (when (send-event-function arg0 v1-0) (set-collide-offense (-> self collide-info) 2 (collide-offense no-offense)) - (logior! (-> self nav-enemy-flags) 256) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) #t ) ) @@ -200,9 +202,9 @@ ) ) (('cue-jump-to-point) - (when (logtest? (-> self nav-enemy-flags) 2048) + (when (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf11)) (set! (-> self event-param-point quad) (-> (the-as vector (-> arg3 param 0)) quad)) - (set! (-> self nav-enemy-flags) (logand -2049 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf11)) ) ) (('cue-chase) @@ -315,8 +317,10 @@ nav-enemy-default-event-handler ) (defmethod TODO-RENAME-37 nav-enemy ((obj nav-enemy)) - (when (logtest? (-> obj nav-enemy-flags) 16) - (if (or (logtest? (-> obj nav-enemy-flags) 128) (logtest? (nav-control-flags bit19) (-> obj nav flags))) + (when (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags enable-travel)) + (if (or (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf7)) + (logtest? (nav-control-flags navcf19) (-> obj nav flags)) + ) (seek-to-point-toward-point! (-> obj collide-info) (-> obj nav target-pos) @@ -335,11 +339,11 @@ nav-enemy-default-event-handler (integrate-for-enemy-with-move-to-ground! (-> obj collide-info) (-> obj collide-info transv) - (the-as collide-kind (-> obj nav-info gnd-collide-with)) + (-> obj nav-info gnd-collide-with) 8192.0 #f (-> obj nav-info hover-if-no-ground) - (logtest? (-> obj nav-enemy-flags) #x8000) + (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf15)) ) (dummy-58 (-> obj collide-info) (-> obj collide-info transv)) ) @@ -349,7 +353,7 @@ nav-enemy-default-event-handler (defbehavior nav-enemy-travel-post nav-enemy () (cond - ((logtest? (-> self nav-enemy-flags) 8) + ((logtest? (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (TODO-RENAME-9 (-> self align)) (dummy-40 self) (dummy-41 self) @@ -380,9 +384,9 @@ nav-enemy-default-event-handler ) (defbehavior nav-enemy-patrol-post nav-enemy () - (when (or (logtest? (nav-control-flags bit19) (-> self nav flags)) (< 2.0 (-> self nav block-count))) + (when (or (logtest? (nav-control-flags navcf19) (-> self nav flags)) (< 2.0 (-> self nav block-count))) (set! (-> self nav block-count) 2.0) - (logior! (-> self nav flags) (nav-control-flags bit10)) + (logior! (-> self nav flags) (nav-control-flags navcf10)) (nav-enemy-get-new-patrol-point) ) (dummy-19 @@ -392,8 +396,8 @@ nav-enemy-default-event-handler (-> self nav destination-pos) (-> self rotate-speed) ) - (if (logtest? (nav-control-flags bit21) (-> self nav flags)) - (logclear! (-> self nav flags) (nav-control-flags bit10)) + (if (logtest? (nav-control-flags navcf21) (-> self nav flags)) + (logclear! (-> self nav flags) (nav-control-flags navcf10)) ) (nav-enemy-travel-post) 0 @@ -424,7 +428,7 @@ nav-enemy-default-event-handler ) (defbehavior nav-enemy-face-player-post nav-enemy () - (if (and *target* (logtest? (-> self nav-enemy-flags) 16)) + (if (and *target* (logtest? (-> self nav-enemy-flags) (nav-enemy-flags enable-travel))) (seek-to-point-toward-point! (-> self collide-info) (target-pos 0) (-> self rotate-speed) (-> self turn-time)) ) (nav-enemy-simple-post) @@ -459,7 +463,7 @@ nav-enemy-default-event-handler ) (defbehavior nav-enemy-neck-control-look-at nav-enemy () - (logior! (-> self nav-enemy-flags) #x4000) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf14)) (if (nonzero? (-> self neck)) (set-mode! (-> self neck) (joint-mod-handler-mode look-at)) ) @@ -468,8 +472,8 @@ nav-enemy-default-event-handler ) (defbehavior nav-enemy-neck-control-inactive nav-enemy () - (when (and (nonzero? (-> self neck)) (logtest? (-> self nav-enemy-flags) #x4000)) - (set! (-> self nav-enemy-flags) (logand -16385 (-> self nav-enemy-flags))) + (when (and (nonzero? (-> self neck)) (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf14))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf14)) (shut-down! (-> self neck)) ) 0 @@ -483,7 +487,7 @@ nav-enemy-default-event-handler (defmethod TODO-RENAME-46 nav-enemy ((obj nav-enemy) (arg0 float)) (and *target* (zero? (logand (-> *target* state-flags) #x80f8)) - (and (or (zero? (logand (-> obj nav-enemy-flags) 4096)) + (and (or (zero? (logand (-> obj nav-enemy-flags) (nav-enemy-flags navenmf12))) (< (vector-vector-distance (target-pos 0) (-> obj collide-info trans)) arg0) ) (nav-enemy-test-point-near-nav-mesh? (-> *target* control shadow-pos)) @@ -494,10 +498,10 @@ nav-enemy-default-event-handler (defbehavior nav-enemy-notice-player? nav-enemy () (let ((gp-0 #f)) (cond - ((logtest? (-> self nav-enemy-flags) 1) + ((logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf0)) (when (>= (- (-> *display* base-frame-counter) (-> self notice-time)) (-> self reaction-time)) (set! gp-0 #t) - (set! (-> self nav-enemy-flags) (logand -2 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf0)) ) ) (else @@ -509,7 +513,7 @@ nav-enemy-default-event-handler ) ) ) - (logior! (-> self nav-enemy-flags) 1) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf0)) (set! (-> self notice-time) (-> *display* base-frame-counter)) ) ) @@ -750,15 +754,9 @@ nav-enemy-default-event-handler (nav-enemy-neck-control-inactive) (set! (-> self state-time) (-> *display* base-frame-counter)) (if (-> self nav-info move-to-ground) - (move-to-ground - (-> self collide-info) - 40960.0 - 40960.0 - #t - (the-as collide-kind (-> self nav-info gnd-collide-with)) - ) + (move-to-ground (-> self collide-info) 40960.0 40960.0 #t (-> self nav-info gnd-collide-with)) ) - (set! (-> self nav-enemy-flags) (logand -7 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1 navenmf2)) (set! (-> self state-timeout) (seconds 1)) (none) ) @@ -814,10 +812,10 @@ nav-enemy-default-event-handler (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) (set! (-> self nav flags) - (the-as nav-control-flags (the-as int (logior (nav-control-flags bit19) (-> self nav flags)))) + (the-as nav-control-flags (the-as int (logior (nav-control-flags navcf19) (-> self nav flags)))) ) - (set! (-> self nav-enemy-flags) (logand -5 (-> self nav-enemy-flags))) - (logior! (-> self nav-enemy-flags) 8) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (set! (-> self state-timeout) (seconds 1)) (set! (-> self target-speed) (-> self nav-info walk-travel-speed)) (set! (-> self acceleration) (-> self nav-info walk-acceleration)) @@ -827,7 +825,7 @@ nav-enemy-default-event-handler ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 8) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (none) ) :trans @@ -905,7 +903,7 @@ nav-enemy-default-event-handler (joint-control-channel-group! a0-5 (the-as art-joint-anim #f) num-func-loop!) ) (ja-channel-push! 1 180) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (let ((a0-8 (-> self skel root-channel 0))) (set! (-> a0-8 frame-group) (the-as art-joint-anim (-> self draw art-group data (-> self nav-info idle-anim))) @@ -959,7 +957,7 @@ nav-enemy-default-event-handler ) ) ) - (logior! (-> self nav-enemy-flags) 8) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (let ((a0-15 (-> self skel root-channel 0))) (set! (-> a0-15 param 0) 1.0) (joint-control-channel-group! a0-15 (the-as art-joint-anim #f) num-func-loop!) @@ -1009,12 +1007,12 @@ nav-enemy-default-event-handler ) :enter (behavior () - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (nav-enemy-neck-control-look-at) - (if (logtest? (-> self nav-enemy-flags) 2) + (if (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (go-virtual nav-enemy-chase) ) - (logior! (-> self nav-enemy-flags) 2) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (let ((gp-0 (-> self nav)) (v1-10 (target-pos 0)) ) @@ -1175,7 +1173,7 @@ nav-enemy-default-event-handler ) (defbehavior nav-enemy-reset-frustration nav-enemy () - (set! (-> self nav-enemy-flags) (logand -8193 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf13)) (if *target* (set! (-> self frustration-point quad) (-> *target* control shadow-pos quad)) ) @@ -1191,7 +1189,9 @@ nav-enemy-default-event-handler ) (defbehavior nav-enemy-frustrated? nav-enemy () - (and (logtest? (-> self nav-enemy-flags) 8192) (nav-enemy-player-at-frustration-point?)) + (and (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf13)) + (nav-enemy-player-at-frustration-point?) + ) ) (defstate nav-enemy-chase (nav-enemy) @@ -1206,7 +1206,7 @@ nav-enemy-default-event-handler (nav-enemy-neck-control-look-at) (set! (-> self state-time) (-> *display* base-frame-counter)) (set! (-> self free-time) (-> *display* base-frame-counter)) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (set! (-> self target-speed) (-> self nav-info run-travel-speed)) (set! (-> self acceleration) (-> self nav-info run-acceleration)) (set! (-> self rotate-speed) (-> self nav-info run-rotate-speed)) @@ -1219,7 +1219,7 @@ nav-enemy-default-event-handler (if (logtest? (-> *target* state-flags) 128) (go-virtual nav-enemy-patrol) ) - (if (logtest? (-> self nav-enemy-flags) 256) + (if (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (go-virtual nav-enemy-victory) ) (if (or (not (nav-enemy-player-at-frustration-point?)) @@ -1233,15 +1233,15 @@ nav-enemy-default-event-handler (if (>= (- (-> *display* base-frame-counter) (-> self frustration-time)) (+ (-> self reaction-time) (-> self nav-info frustration-time)) ) - (logior! (-> self nav-enemy-flags) 8192) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf13)) ) (if (or (not (TODO-RENAME-46 self (-> self nav-info stop-chase-distance))) - (logtest? (-> self nav-enemy-flags) 8192) + (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf13)) ) (go-virtual nav-enemy-stop-chase) ) (cond - ((logtest? (nav-control-flags bit17) (-> self nav flags)) + ((logtest? (nav-control-flags navcf17) (-> self nav flags)) (if (>= (- (-> *display* base-frame-counter) (-> self free-time)) (seconds 1)) (go-virtual nav-enemy-patrol) ) @@ -1315,7 +1315,7 @@ nav-enemy-default-event-handler (vector-vector-distance (-> self collide-info trans) (-> *target* control trans)) ) ) - (logtest? (nav-control-flags bit17) (-> self nav flags)) + (logtest? (nav-control-flags navcf17) (-> self nav flags)) (>= (- (-> *display* base-frame-counter) (-> self state-time)) (-> self state-timeout)) ) (go-virtual nav-enemy-stare) @@ -1360,7 +1360,7 @@ nav-enemy-default-event-handler :enter (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((f0-0 (vector-vector-distance (-> self collide-info trans) (target-pos 0)))) (set! (-> self state-timeout) (the-as @@ -1376,7 +1376,7 @@ nav-enemy-default-event-handler ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (none) ) :trans @@ -1407,7 +1407,7 @@ nav-enemy-default-event-handler ) ) ) - (set! (-> self nav-enemy-flags) (logand -5 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (if (>= (- (-> *display* base-frame-counter) (-> self state-time)) (-> self state-timeout)) (go-virtual nav-enemy-give-up) ) @@ -1416,7 +1416,7 @@ nav-enemy-default-event-handler (vector-vector-distance (-> self collide-info trans) (-> *target* control trans)) ) ) - (logtest? (nav-control-flags bit17) (-> self nav flags)) + (logtest? (nav-control-flags navcf17) (-> self nav flags)) ) (go-virtual nav-enemy-give-up) ) @@ -1443,7 +1443,7 @@ nav-enemy-default-event-handler (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) (nav-enemy-neck-control-inactive) - (set! (-> self nav-enemy-flags) (logand -5 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (none) ) :trans @@ -1605,7 +1605,7 @@ nav-enemy-default-event-handler ) (defbehavior nav-enemy-jump-post nav-enemy () - (if (logtest? (-> self nav-enemy-flags) 16) + (if (logtest? (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (seek-to-point-toward-point! (-> self collide-info) (-> self jump-dest) @@ -1613,7 +1613,7 @@ nav-enemy-default-event-handler (-> self turn-time) ) ) - (when (logtest? (-> self nav-enemy-flags) 8) + (when (logtest? (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (let ((f30-0 (the float (- (-> *display* base-frame-counter) (-> self jump-time))))) (let ((v1-12 (eval-position! (-> self jump-trajectory) f30-0 (new 'stack-no-clear 'vector)))) (set! (-> self collide-info trans quad) (-> v1-12 quad)) @@ -1641,24 +1641,24 @@ nav-enemy-default-event-handler (set! (-> s2-2 y) 0.0) (vector-xz-normalize! s1-1 1.0) (vector-xz-normalize! s2-2 1.0) - (set! (-> self nav-enemy-flags) (logand -1537 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags standing-jump drop-jump)) (if (or (>= (* 0.5 (-> self nav-info run-travel-speed)) f24-0) (>= (cos 3640.889) (vector-dot s1-1 s2-2))) - (logior! (-> self nav-enemy-flags) 512) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags standing-jump)) ) ) (if (or (and (< f26-0 0.0) (< f28-0 (fabs f26-0))) (and (< (fabs f26-0) 12288.0) (< f28-0 20480.0))) - (logior! (-> self nav-enemy-flags) 1024) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags drop-jump)) ) ) - (when (and arg1 (logtest? (-> self nav-enemy-flags) 1024)) - (set! (-> self nav-enemy-flags) (logand -513 (-> self nav-enemy-flags))) + (when (and arg1 (logtest? (-> self nav-enemy-flags) (nav-enemy-flags drop-jump))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags standing-jump)) (set! f30-0 2048.0) ) (setup-from-to-height! (-> self jump-trajectory) s4-0 arg0 f30-0 (* 0.000011111111 arg4)) ) (set! (-> self nav extra-nav-sphere quad) (-> arg0 quad)) (set! (-> self nav extra-nav-sphere w) (-> self collide-info nav-radius)) - (logior! (-> self collide-info nav-flags) 2) + (logior! (-> self collide-info nav-flags) (nav-flags navf1)) 0 (none) ) @@ -1676,13 +1676,13 @@ nav-enemy-default-event-handler ) (defbehavior nav-enemy-execute-custom-jump nav-enemy ((arg0 int) (arg1 float) (arg2 float)) - (when (logtest? (-> self nav-enemy-flags) 512) + (when (logtest? (-> self nav-enemy-flags) (nav-enemy-flags standing-jump)) (let ((a0-1 (-> self skel root-channel 0))) (set! (-> a0-1 param 0) 1.0) (joint-control-channel-group! a0-1 (the-as art-joint-anim #f) num-func-loop!) ) (ja-channel-push! 1 30) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (let ((s3-0 (-> self skel root-channel 0))) (set! (-> s3-0 frame-group) (the-as art-joint-anim (-> self draw art-group data arg0))) (set! (-> s3-0 param 0) (ja-aframe arg1 0)) @@ -1702,9 +1702,9 @@ nav-enemy-default-event-handler ) (set! (-> self collide-info status) (logand -8 (-> self collide-info status))) (set! (-> self jump-time) (-> *display* base-frame-counter)) - (logior! (-> self nav-enemy-flags) 8) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (cond - ((logtest? (-> self nav-enemy-flags) 1024) + ((logtest? (-> self nav-enemy-flags) (nav-enemy-flags drop-jump)) (cond ((= (if (> (-> self skel active-channels) 0) (-> self skel root-channel 0 frame-group) @@ -1756,7 +1756,7 @@ nav-enemy-default-event-handler ) (set! (-> self collide-info trans quad) (-> self jump-dest quad)) (set! (-> self collide-info transv y) 0.0) - (set! (-> self collide-info nav-flags) (logand -3 (-> self collide-info nav-flags))) + (logclear! (-> self collide-info nav-flags) (nav-flags navf1)) 0 (none) ) @@ -1825,7 +1825,7 @@ nav-enemy-default-event-handler ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 24) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) (none) ) :code @@ -1862,7 +1862,9 @@ nav-enemy-default-event-handler (set! (-> self collide-info transv x) (-> v1-9 x)) (set! (-> self collide-info transv z) (-> v1-9 z)) ) - (if (or (logtest? (-> self nav-enemy-flags) 128) (logtest? (nav-control-flags bit19) (-> self nav flags))) + (if (or (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf7)) + (logtest? (nav-control-flags navcf19) (-> self nav flags)) + ) (seek-to-point-toward-point! (-> self collide-info) (-> self nav target-pos) @@ -1883,7 +1885,7 @@ nav-enemy-default-event-handler (integrate-for-enemy-with-move-to-ground! (-> self collide-info) (-> self collide-info transv) - (the-as collide-kind (-> self nav-info gnd-collide-with)) + (-> self nav-info gnd-collide-with) 8192.0 #f (-> self nav-info hover-if-no-ground) @@ -1903,7 +1905,7 @@ nav-enemy-default-event-handler :enter (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (logclear! (-> self nav flags) (nav-control-flags bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf19)) (let ((gp-0 (new 'stack-no-clear 'vector))) (set! (-> gp-0 quad) (-> self collide-info transv quad)) (set! (-> gp-0 y) 0.0) @@ -1917,7 +1919,7 @@ nav-enemy-default-event-handler :trans (behavior () (if (or (>= (- (-> *display* base-frame-counter) (-> self state-time)) (seconds 0.5)) - (logtest? (nav-control-flags bit19) (-> self nav flags)) + (logtest? (nav-control-flags navcf19) (-> self nav flags)) ) (go-virtual nav-enemy-chase) ) @@ -2007,7 +2009,7 @@ nav-enemy-default-event-handler :code (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (logior! (-> self nav-enemy-flags) 2048) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf11)) (ja-channel-push! 1 30) (let ((f30-0 (nav-enemy-rnd-float-range 0.8 1.2))) (let ((v1-6 (-> self skel root-channel 0))) @@ -2019,7 +2021,7 @@ nav-enemy-default-event-handler (set! (-> v1-9 num-func) num-func-identity) (set! (-> v1-9 frame-num) 0.0) ) - (while (logtest? (-> self nav-enemy-flags) 2048) + (while (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf11)) (suspend) (let ((a0-8 (-> self skel root-channel 0))) (set! (-> a0-8 param 0) f30-0) @@ -2053,7 +2055,7 @@ nav-enemy-default-event-handler nav-enemy-jump-event-handler :exit (behavior () - (logior! (-> self nav-enemy-flags) 24) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) (none) ) :trans @@ -2066,15 +2068,15 @@ nav-enemy-default-event-handler (set! (-> self state-time) (-> *display* base-frame-counter)) (nav-enemy-initialize-jump (-> self event-param-point)) (nav-enemy-neck-control-look-at) - (logior! (-> self nav-enemy-flags) 16) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (when (not (nav-enemy-facing-point? (-> self jump-dest) 5461.3335)) (ja-channel-push! 1 60) (nav-enemy-turn-to-face-point (-> self jump-dest) 1820.4445) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (nav-enemy-execute-jump) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (nav-enemy-jump-land-anim) (go-virtual nav-enemy-wait-for-cue) (none) @@ -2117,7 +2119,7 @@ nav-enemy-default-event-handler ) (set! (-> obj align) (new 'process 'align-control obj)) (set! (-> obj nav) (new 'process 'nav-control (-> obj collide-info) 16 (-> arg0 nav-nearest-y-threshold))) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj nav gap-event) 'jump) (TODO-RENAME-26 (-> obj nav)) (set! (-> obj path) (new 'process 'path-control obj 'path 0.0)) @@ -2127,7 +2129,7 @@ nav-enemy-default-event-handler ) (set! (-> obj reaction-time) (nav-enemy-rnd-int-range (seconds 0.1) (seconds 0.8))) (set! (-> obj speed-scale) 1.0) - (logior! (-> obj nav-enemy-flags) 4216) + (logior! (-> obj nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel navenmf5 navenmf6 navenmf12)) 0 (none) ) @@ -2165,8 +2167,8 @@ nav-enemy-default-event-handler (vector-identity! (-> self collide-info scale)) (set! (-> self entity) (-> arg0 entity)) (TODO-RENAME-48 self) - (set! (-> self nav-enemy-flags) (logand -4097 (-> self nav-enemy-flags))) - (logior! (-> self nav-enemy-flags) 2) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf12)) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (go-virtual nav-enemy-wait-for-cue) (none) ) diff --git a/goal_src/levels/common/sharkey.gc b/goal_src/levels/common/sharkey.gc index d167bedd1f..23d4302a30 100644 --- a/goal_src/levels/common/sharkey.gc +++ b/goal_src/levels/common/sharkey.gc @@ -229,7 +229,7 @@ nav-enemy-default-event-handler :enter (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (set! (-> self nav-enemy-flags) (logand -2 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf0)) (none) ) :exit @@ -251,8 +251,8 @@ nav-enemy-default-event-handler ) ) ((sharkey-notice-player?) - (when (zero? (logand (-> self nav-enemy-flags) 1)) - (logior! (-> self nav-enemy-flags) 1) + (when (zero? (logand (-> self nav-enemy-flags) (nav-enemy-flags navenmf0))) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf0)) (set! (-> self notice-time) (-> *display* base-frame-counter)) ) (let ((a0-4 (dummy-16 (-> self nav) (-> *target* control trans)))) @@ -269,7 +269,7 @@ nav-enemy-default-event-handler ) (else (if (>= (- (-> *display* base-frame-counter) (-> self notice-time)) (seconds 10)) - (set! (-> self nav-enemy-flags) (logand -2 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf0)) ) ) ) @@ -810,7 +810,7 @@ nav-enemy-default-event-handler :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/goal_src/levels/finalboss/green-eco-lurker.gc b/goal_src/levels/finalboss/green-eco-lurker.gc index 724a858abb..1eea85e807 100644 --- a/goal_src/levels/finalboss/green-eco-lurker.gc +++ b/goal_src/levels/finalboss/green-eco-lurker.gc @@ -101,7 +101,8 @@ :use-proximity-notice #f :use-jump-blocked #t :use-jump-patrol #f - :gnd-collide-with #x805 + :gnd-collide-with + (collide-kind background cak-2 ground-object) :debug-draw-neck #f :debug-draw-jump #f ) @@ -336,11 +337,12 @@ ) (defmethod dummy-44 green-eco-lurker ((obj green-eco-lurker) (arg0 process) (arg1 event-message-block)) - (when (and (logtest? (-> obj nav-enemy-flags) 64) ((method-of-type touching-shapes-entry prims-touching?) - (the-as touching-shapes-entry (-> arg1 param 0)) - (-> obj collide-info) - (the-as uint 1) - ) + (when (and (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf6)) + ((method-of-type touching-shapes-entry prims-touching?) + (the-as touching-shapes-entry (-> arg1 param 0)) + (-> obj collide-info) + (the-as uint 1) + ) ) (if (nav-enemy-send-attack arg0 (the-as touching-shapes-entry (-> arg1 param 0)) 'generic) (send-event (ppointer->process (-> obj parent)) 'blob-hit-jak) @@ -349,11 +351,12 @@ ) (defmethod nav-enemy-touch-handler green-eco-lurker ((obj green-eco-lurker) (arg0 process) (arg1 event-message-block)) - (when (and (logtest? (-> obj nav-enemy-flags) 64) ((method-of-type touching-shapes-entry prims-touching?) - (the-as touching-shapes-entry (-> arg1 param 0)) - (-> obj collide-info) - (the-as uint 1) - ) + (when (and (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf6)) + ((method-of-type touching-shapes-entry prims-touching?) + (the-as touching-shapes-entry (-> arg1 param 0)) + (-> obj collide-info) + (the-as uint 1) + ) ) (if (nav-enemy-send-attack arg0 (the-as touching-shapes-entry (-> arg1 param 0)) 'generic) (send-event (ppointer->process (-> obj parent)) 'blob-hit-jak) @@ -440,33 +443,34 @@ ) (defmethod dummy-53 green-eco-lurker ((obj green-eco-lurker)) - (the-as - symbol - (cond - ((and (-> obj draw shadow) (zero? (-> obj draw cur-lod)) (logtest? (-> obj draw status) (draw-status was-drawn))) - (let ((f0-0 (-> obj appear-dest y)) - (v1-7 (-> obj draw shadow-ctrl)) - ) - (let ((a0-1 v1-7)) - (set! (-> a0-1 settings flags) (logand -33 (-> a0-1 settings flags))) - ) - 0 - (let ((a0-3 v1-7)) - (set! (-> a0-3 settings bot-plane w) (- (+ -6144.0 f0-0))) - ) - 0 - (set! (-> v1-7 settings top-plane w) (- (+ 6144.0 f0-0))) - ) - 0 - ) - (else - (let ((v1-9 (-> obj draw shadow-ctrl))) - (logior! (-> v1-9 settings flags) 32) + (the-as symbol (cond + ((and (-> obj draw shadow) + (zero? (-> obj draw cur-lod)) + (logtest? (-> obj draw status) (draw-status was-drawn)) + ) + (let ((f0-0 (-> obj appear-dest y)) + (v1-7 (-> obj draw shadow-ctrl)) + ) + (let ((a0-1 v1-7)) + (set! (-> a0-1 settings flags) (logand -33 (-> a0-1 settings flags))) + ) + 0 + (let ((a0-3 v1-7)) + (set! (-> a0-3 settings bot-plane w) (- (+ -6144.0 f0-0))) + ) + 0 + (set! (-> v1-7 settings top-plane w) (- (+ 6144.0 f0-0))) + ) + 0 + ) + (else + (let ((v1-9 (-> obj draw shadow-ctrl))) + (logior! (-> v1-9 settings flags) 32) + ) + 0 + ) + ) ) - 0 - ) - ) - ) ) (defstate green-eco-lurker-appear (green-eco-lurker) @@ -480,7 +484,7 @@ (+ (-> (the-as green-eco-lurker-gen (-> self parent 0)) root trans x) (fmax -32768.0 (fmin 32768.0 f0-1))) ) ) - (logior! (-> self collide-info nav-flags) 2) + (logior! (-> self collide-info nav-flags) (nav-flags navf1)) (set! (-> self nav extra-nav-sphere quad) (-> self appear-dest quad)) (set! (-> self nav extra-nav-sphere w) 8192.0) (setup-from-to-duration! (-> self traj) (-> self collide-info trans) (-> self appear-dest) 225.0 -9.102222) @@ -510,8 +514,8 @@ (let ((f30-0 (fmin (the float (- (-> *display* base-frame-counter) (-> self state-time))) (-> self traj time)))) (eval-position! (-> self traj) f30-0 (-> self collide-info trans)) (when (= f30-0 (-> self traj time)) - (logior! (-> self collide-info nav-flags) 1) - (set! (-> self collide-info nav-flags) (logand -3 (-> self collide-info nav-flags))) + (logior! (-> self collide-info nav-flags) (nav-flags navf0)) + (logclear! (-> self collide-info nav-flags) (nav-flags navf1)) (go green-eco-lurker-appear-land) ) ) @@ -645,7 +649,7 @@ (joint-control-channel-group-eval! a0-16 (the-as art-joint-anim #f) num-func-seek!) ) ) - (logior! (-> self nav-enemy-flags) 2) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (go-virtual nav-enemy-chase) (none) ) @@ -892,7 +896,7 @@ (defmethod TODO-RENAME-48 green-eco-lurker ((obj green-eco-lurker)) (initialize-skeleton obj *green-eco-lurker-sg* '()) (set! (-> obj draw origin-joint-index) (the-as uint 3)) - (set! (-> obj collide-info nav-flags) (logand -2 (-> obj collide-info nav-flags))) + (logclear! (-> obj collide-info nav-flags) (nav-flags navf0)) (TODO-RENAME-45 obj *green-eco-lurker-nav-enemy-info*) (logior! (-> obj draw shadow-ctrl settings flags) 4) (set! (-> obj neck up) (the-as uint 0)) diff --git a/goal_src/levels/finalboss/robotboss.gc b/goal_src/levels/finalboss/robotboss.gc index 000e15186e..74389005a9 100644 --- a/goal_src/levels/finalboss/robotboss.gc +++ b/goal_src/levels/finalboss/robotboss.gc @@ -4501,8 +4501,8 @@ (initialize-skeleton obj *robotboss-sg* '()) (aybabtu 2) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 (the-as float 40960.0))) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) - (set! (-> obj root-override nav-flags) (logand -2 (-> obj root-override nav-flags))) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) + (logclear! (-> obj root-override nav-flags) (nav-flags navf0)) (set! (-> obj path) (new 'process 'path-control obj 'path (the-as float 0.0))) (logior! (-> obj path flags) (path-control-flag display draw-line draw-point draw-text)) (logclear! (-> obj mask) (process-mask actor-pause)) diff --git a/goal_src/levels/jungle/hopper.gc b/goal_src/levels/jungle/hopper.gc index a302e7cc14..6dac7904a6 100644 --- a/goal_src/levels/jungle/hopper.gc +++ b/goal_src/levels/jungle/hopper.gc @@ -27,7 +27,7 @@ :shadow 4 ) -(defstatehandler hopper :event nav-enemy-default-event-handler) +nav-enemy-default-event-handler (defmethod common-post hopper ((obj hopper)) (let ((v1-1 (-> obj draw shadow-ctrl))) @@ -46,9 +46,16 @@ ) (set! (-> s5-0 quad) (-> arg0 quad)) (set! (-> s5-0 y) (+ 20480.0 (-> s5-0 y))) - (let ((f0-2 - (fill-and-probe-using-y-probe *collide-cache* s5-0 f30-0 (collide-kind background) self t1-0 (the-as uint 1)) - ) + (let ((f0-2 (fill-and-probe-using-y-probe + *collide-cache* + s5-0 + f30-0 + (collide-kind background) + self + t1-0 + (new 'static 'pat-surface :noentity #x1) + ) + ) ) (if (< f0-2 0.0) (return (the-as object #f)) @@ -74,18 +81,18 @@ (-> self nav-info jump-height-factor) -409600.0 ) - (set! (-> self nav-enemy-flags) (logand -513 (-> self nav-enemy-flags))) - (set! (-> self nav-enemy-flags) (logand -1025 (-> self nav-enemy-flags))) - (logior! (-> self nav-enemy-flags) 16) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags standing-jump)) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags drop-jump)) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (when (not (nav-enemy-facing-point? (-> self jump-dest) 5461.3335)) (ja-channel-push! 1 60) (nav-enemy-turn-to-face-point (-> self jump-dest) 1820.4445) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (nav-enemy-execute-jump) (set! (-> self shadow-min-y) (+ (-> self collide-info trans y) (-> self nav-info shadow-min-y))) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (nav-enemy-jump-land-anim) 0 (none) @@ -163,7 +170,7 @@ ) :trans (behavior () - (if (zero? (logand (-> self nav-enemy-flags) 8)) + (if (zero? (logand (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate))) ((-> (method-of-type nav-enemy nav-enemy-patrol) trans)) ) (none) @@ -172,7 +179,7 @@ (behavior () (vector-reset! (-> self collide-info transv)) (set! (-> self jump-length) 16384.0) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (while #t (cond ((= (if (> (-> self skel active-channels) 0) @@ -245,9 +252,9 @@ (joint-control-channel-group-eval! a0-21 (the-as art-joint-anim #f) num-func-loop!) ) ) - (when (or (logtest? (nav-control-flags bit19) (-> self nav flags)) (< 2.0 (-> self nav block-count))) + (when (or (logtest? (nav-control-flags navcf19) (-> self nav flags)) (< 2.0 (-> self nav block-count))) (set! (-> self nav block-count) 0.0) - (logior! (-> self nav flags) (nav-control-flags bit10)) + (logior! (-> self nav flags) (nav-control-flags navcf10)) (nav-enemy-get-new-patrol-point) (set! (-> self nav target-pos quad) (-> self nav destination-pos quad)) ) @@ -282,7 +289,7 @@ ) :trans (behavior () - (if (zero? (logand (-> self nav-enemy-flags) 8)) + (if (zero? (logand (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate))) ((-> (method-of-type nav-enemy nav-enemy-chase) trans)) ) (none) @@ -291,7 +298,7 @@ (behavior () (vector-reset! (-> self collide-info transv)) (set! (-> self jump-length) 32768.0) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (while #t (cond ((= (if (> (-> self skel active-channels) 0) @@ -435,7 +442,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #t ) diff --git a/goal_src/levels/jungle/junglefish.gc b/goal_src/levels/jungle/junglefish.gc index c9e74046dc..eded00dc5c 100644 --- a/goal_src/levels/jungle/junglefish.gc +++ b/goal_src/levels/jungle/junglefish.gc @@ -377,7 +377,7 @@ nav-enemy-default-event-handler :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/goal_src/levels/jungleb/aphid.gc b/goal_src/levels/jungleb/aphid.gc index 2b5ef5134f..ef18a7b415 100644 --- a/goal_src/levels/jungleb/aphid.gc +++ b/goal_src/levels/jungleb/aphid.gc @@ -27,20 +27,22 @@ ) (defbehavior aphid-invulnerable aphid () - (set! (-> self nav-enemy-flags) (logand -33 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf5)) (set-collide-offense (-> self collide-info) 2 (collide-offense indestructible)) (none) ) (defbehavior aphid-vulnerable aphid () - (logior! (-> self nav-enemy-flags) 32) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf5)) (set-collide-offense (-> self collide-info) 2 (collide-offense touch)) (none) ) (defmethod dummy-43 aphid ((obj aphid) (arg0 process) (arg1 event-message-block)) (cond - ((or (logtest? (-> obj nav-enemy-flags) 32) (= arg0 (ppointer->process (-> obj parent)))) + ((or (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf5)) + (= arg0 (ppointer->process (-> obj parent))) + ) (send-event arg0 'get-attack-count 1) (logclear! (-> obj mask) (process-mask actor-pause attackable)) (go (method-of-object obj nav-enemy-die)) @@ -168,7 +170,7 @@ (behavior () (set! (-> self turn-time) (seconds 0.2)) (let ((f30-0 (nav-enemy-rnd-float-range 0.8 1.2))) - (when (or (logtest? (-> self nav-enemy-flags) 256) + (when (or (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (and (nav-enemy-player-vulnerable?) (nav-enemy-rnd-percent? 0.5)) ) (ja-channel-push! 1 30) @@ -192,7 +194,7 @@ ) (while #t (when (not (nav-enemy-facing-player? 2730.6667)) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((a0-7 (-> self skel root-channel 0))) (set! (-> a0-7 param 0) 1.0) (joint-control-channel-group! a0-7 (the-as art-joint-anim #f) num-func-loop!) @@ -213,7 +215,7 @@ (joint-control-channel-group-eval! a0-13 (the-as art-joint-anim #f) num-func-loop!) ) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) ) (when (nav-enemy-rnd-percent? 0.3) (if (not (= (if (> (-> self skel active-channels) 0) @@ -282,7 +284,7 @@ ) ) ) - (logclear! (-> self nav flags) (nav-control-flags bit17 bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf17 navcf19)) (nav-enemy-get-new-patrol-point) (let ((a0-12 (-> self skel root-channel 0))) (set! (-> a0-12 frame-group) (the-as art-joint-anim (-> self draw art-group data 8))) @@ -360,7 +362,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -413,7 +415,7 @@ (vector-identity! (-> self collide-info scale)) (set! (-> self entity) (-> arg0 entity)) (TODO-RENAME-48 self) - (set! (-> self nav-enemy-flags) (logand -4097 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf12)) (let ((a1-3 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-3 from) self) (set! (-> a1-3 num-params) 0) diff --git a/goal_src/levels/maincave/baby-spider.gc b/goal_src/levels/maincave/baby-spider.gc index 7c9088742e..b637de21db 100644 --- a/goal_src/levels/maincave/baby-spider.gc +++ b/goal_src/levels/maincave/baby-spider.gc @@ -115,7 +115,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -168,7 +168,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -599,7 +599,7 @@ baby-spider-default-event-handler (set! (-> self turn-time) (seconds 0.07333333)) (let ((f30-0 (rand-vu-float-range 0.8 1.2))) (while #t - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (ja-channel-push! 1 30) (let ((a0-2 (-> self skel root-channel 0))) (set! (-> a0-2 frame-group) (the-as art-joint-anim (-> self draw art-group data 12))) @@ -622,7 +622,7 @@ baby-spider-default-event-handler (set! (-> a0-5 param 0) 1.0) (joint-control-channel-group! a0-5 (the-as art-joint-anim #f) num-func-loop!) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((gp-0 (rand-vu-int-range 300 600)) (s5-0 (-> *display* base-frame-counter)) ) @@ -678,7 +678,7 @@ baby-spider-default-event-handler (joint-control-channel-group-eval! a0-2 (the-as art-joint-anim #f) num-func-seek!) ) ) - (logclear! (-> self nav flags) (nav-control-flags bit17 bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf17 navcf19)) (nav-enemy-get-new-patrol-point) (let ((a0-7 (-> self skel root-channel 0))) (set! (-> a0-7 frame-group) (the-as art-joint-anim (-> self draw art-group data 6))) @@ -904,7 +904,7 @@ baby-spider-default-event-handler (set! (-> obj mask) (logior (process-mask enemy) (-> obj mask))) (logior! (-> obj mask) (process-mask actor-pause)) (set! (-> obj nav) (new 'process 'nav-control (-> obj collide-info) 24 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj path) (new 'process 'path-control obj 'path 0.0)) (logior! (-> obj path flags) (path-control-flag display draw-line draw-point draw-text)) (create-connection! diff --git a/goal_src/levels/maincave/mother-spider-egg.gc b/goal_src/levels/maincave/mother-spider-egg.gc index ee7e181d4f..852e958de1 100644 --- a/goal_src/levels/maincave/mother-spider-egg.gc +++ b/goal_src/levels/maincave/mother-spider-egg.gc @@ -173,7 +173,10 @@ (defmethod draw-egg-shadow mother-spider-egg ((obj mother-spider-egg) (arg0 vector) (arg1 symbol)) (cond - ((and (-> obj draw shadow) (zero? (-> obj draw cur-lod)) (logtest? (-> obj draw status) (draw-status was-drawn))) + ((and (-> obj draw shadow) + (zero? (-> obj draw cur-lod)) + (logtest? (-> obj draw status) (draw-status was-drawn)) + ) (let ((s5-0 (new 'stack-no-clear 'collide-tri-result)) (a1-1 (new 'stack-no-clear 'vector)) (a2-1 (new 'stack-no-clear 'vector)) @@ -581,8 +584,8 @@ (logior! (-> v1-8 settings flags) 32) ) 0 - (set! (-> self root-override nav-flags) (logand -2 (-> self root-override nav-flags))) - (set! (-> self root-override nav-flags) (logand -3 (-> self root-override nav-flags))) + (logclear! (-> self root-override nav-flags) (nav-flags navf0)) + (logclear! (-> self root-override nav-flags) (nav-flags navf1)) (clear-collide-with-as (-> self root-override)) (until (not (-> self child)) (suspend) @@ -625,9 +628,9 @@ (setup-lods! (-> self broken-look) *mother-spider-egg-broken-sg* (-> self draw art-group) (-> self entity)) (set! (-> self draw shadow-ctrl) (new 'process 'shadow-control 0.0 0.0 614400.0 (the-as float 60) 245760.0)) (set! (-> self nav) (new 'process 'nav-control (-> self root-override) 16 40960.0)) - (logior! (-> self nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) - (set! (-> self root-override nav-flags) (logand -2 (-> self root-override nav-flags))) - (logior! (-> self root-override nav-flags) 2) + (logior! (-> self nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) + (logclear! (-> self root-override nav-flags) (nav-flags navf0)) + (logior! (-> self root-override nav-flags) (nav-flags navf1)) (set! (-> self nav extra-nav-sphere quad) (-> self fall-dest quad)) (set! (-> self nav extra-nav-sphere w) 4096.0) (setup-from-to-height! (-> self traj) (-> self root-override trans) arg2 4096.0 -4.551111) diff --git a/goal_src/levels/maincave/mother-spider-proj.gc b/goal_src/levels/maincave/mother-spider-proj.gc index a618aec85a..18fd75116f 100644 --- a/goal_src/levels/maincave/mother-spider-proj.gc +++ b/goal_src/levels/maincave/mother-spider-proj.gc @@ -261,7 +261,7 @@ (the-as vector #f) f0-5 (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) 0.0 81920.0 ) diff --git a/goal_src/levels/maincave/mother-spider.gc b/goal_src/levels/maincave/mother-spider.gc index 58e9f0e369..8038b6f4ad 100644 --- a/goal_src/levels/maincave/mother-spider.gc +++ b/goal_src/levels/maincave/mother-spider.gc @@ -2104,10 +2104,10 @@ (process-drawable-from-entity! obj arg0) (initialize-skeleton obj *mother-spider-sg* '()) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj nav nearest-y-threshold) 409600.0) - (set! (-> obj root-override nav-flags) (logand -2 (-> obj root-override nav-flags))) - (set! (-> obj root-override nav-flags) (logand -3 (-> obj root-override nav-flags))) + (logclear! (-> obj root-override nav-flags) (nav-flags navf0)) + (logclear! (-> obj root-override nav-flags) (nav-flags navf1)) (set! (-> obj path) (new 'process 'path-control obj 'path 0.0)) (logior! (-> obj path flags) (path-control-flag display draw-line draw-point draw-text)) (set! (-> obj fact) diff --git a/goal_src/levels/misty/babak-with-cannon.gc b/goal_src/levels/misty/babak-with-cannon.gc index 5d0ce12e70..bc99041b4a 100644 --- a/goal_src/levels/misty/babak-with-cannon.gc +++ b/goal_src/levels/misty/babak-with-cannon.gc @@ -139,7 +139,7 @@ nav-enemy-default-event-handler (if (nav-enemy-notice-player?) (go-virtual nav-enemy-chase) ) - (if (logtest? (nav-control-flags bit19) (-> self nav flags)) + (if (logtest? (nav-control-flags navcf19) (-> self nav flags)) (go babak-with-cannon-jump-onto-cannon) ) (none) @@ -230,7 +230,7 @@ nav-enemy-default-event-handler ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 24) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) (none) ) :code @@ -238,7 +238,7 @@ nav-enemy-default-event-handler (set! (-> self state-time) (-> *display* base-frame-counter)) (set! (-> self rotate-speed) (-> self nav-info run-rotate-speed)) (set! (-> self turn-time) (-> self nav-info run-turn-time)) - (set! (-> self nav-enemy-flags) (logand -25 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) (nav-enemy-neck-control-inactive) (let* ((v1-7 (-> self cannon-ent)) (gp-0 (if v1-7 @@ -264,9 +264,9 @@ nav-enemy-default-event-handler (ja-channel-push! 1 60) (nav-enemy-turn-to-face-point (-> self jump-dest) 1820.4445) ) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (nav-enemy-execute-jump) - (set! (-> self nav-enemy-flags) (logand -25 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) (let* ((v1-20 (-> self cannon-ent)) (gp-1 (if v1-20 (-> v1-20 extra process) @@ -320,7 +320,7 @@ nav-enemy-default-event-handler ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 24) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) (none) ) :code @@ -328,7 +328,7 @@ nav-enemy-default-event-handler (set! (-> self state-time) (-> *display* base-frame-counter)) (nav-enemy-initialize-jump (-> self entity extra trans)) (nav-enemy-neck-control-look-at) - (set! (-> self nav-enemy-flags) (logand -25 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) (let ((a0-2 (-> self skel root-channel 0))) (set! (-> a0-2 frame-group) (the-as art-joint-anim (-> self draw art-group data 17))) (set! (-> a0-2 param 0) 0.0) @@ -350,7 +350,7 @@ nav-enemy-default-event-handler (ja-channel-push! 1 60) (nav-enemy-turn-to-face-point (-> self jump-dest) 1820.4445) ) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (nav-enemy-execute-jump) (let ((a1-6 (dummy-16 (-> self nav) (-> self jump-dest)))) (set-current-poly! (-> self nav) a1-6) diff --git a/goal_src/levels/misty/bonelurker.gc b/goal_src/levels/misty/bonelurker.gc index a25911bd75..19be4cc918 100644 --- a/goal_src/levels/misty/bonelurker.gc +++ b/goal_src/levels/misty/bonelurker.gc @@ -44,20 +44,19 @@ ) (defmethod dummy-44 bonelurker ((obj bonelurker) (arg0 process) (arg1 event-message-block)) - (the-as - object - (when (and (logtest? (-> obj nav-enemy-flags) 64) ((method-of-type touching-shapes-entry prims-touching?) - (the-as touching-shapes-entry (-> arg1 param 0)) - (-> obj collide-info) - (the-as uint 1) - ) - ) - (when (nav-enemy-send-attack arg0 (the-as touching-shapes-entry (-> arg1 param 0)) 'generic) - (set! (-> obj speed-scale) 0.5) - #t - ) - ) - ) + (the-as object (when (and (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf6)) + ((method-of-type touching-shapes-entry prims-touching?) + (the-as touching-shapes-entry (-> arg1 param 0)) + (-> obj collide-info) + (the-as uint 1) + ) + ) + (when (nav-enemy-send-attack arg0 (the-as touching-shapes-entry (-> arg1 param 0)) 'generic) + (set! (-> obj speed-scale) 0.5) + #t + ) + ) + ) ) (defmethod dummy-43 bonelurker ((obj bonelurker) (arg0 process) (arg1 event-message-block)) @@ -124,7 +123,7 @@ (send-event-function arg0 a1-6) ) (set! (-> obj bump-player-time) (-> *display* base-frame-counter)) - (set! (-> obj nav-enemy-flags) (logand -65 (-> obj nav-enemy-flags))) + (logclear! (-> obj nav-enemy-flags) (nav-enemy-flags navenmf6)) 'push ) ) @@ -237,10 +236,10 @@ nav-enemy-default-event-handler :trans (behavior () ((-> (method-of-type nav-enemy nav-enemy-chase) trans)) - (if (and (zero? (logand (-> self nav-enemy-flags) 64)) + (if (and (zero? (logand (-> self nav-enemy-flags) (nav-enemy-flags navenmf6))) (>= (- (-> *display* base-frame-counter) (-> self bump-player-time)) (seconds 0.5)) ) - (logior! (-> self nav-enemy-flags) 64) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf6)) ) (none) ) @@ -344,7 +343,7 @@ nav-enemy-default-event-handler (joint-control-channel-group-eval! a0-23 (the-as art-joint-anim #f) num-func-seek!) ) ) - (if (logtest? (-> self nav-enemy-flags) 256) + (if (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (go-virtual nav-enemy-victory) ) (let ((a0-25 (-> self skel root-channel 0))) @@ -364,7 +363,7 @@ nav-enemy-default-event-handler (joint-control-channel-group-eval! a0-26 (the-as art-joint-anim #f) num-func-seek!) ) ) - (if (logtest? (-> self nav-enemy-flags) 256) + (if (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (go-virtual nav-enemy-victory) ) (let ((a0-28 (-> self skel root-channel 0))) @@ -435,7 +434,7 @@ nav-enemy-default-event-handler ) (while #t (when (not (nav-enemy-facing-player? 2730.6667)) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (ja-channel-push! 1 60) (let ((v1-20 (-> self skel root-channel 0))) (set! (-> v1-20 frame-group) (the-as art-joint-anim (-> self draw art-group data 16))) @@ -452,7 +451,7 @@ nav-enemy-default-event-handler (joint-control-channel-group-eval! a0-14 (the-as art-joint-anim #f) num-func-loop!) ) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) ) (ja-channel-push! 1 75) (let ((a0-18 (-> self skel root-channel 0))) @@ -573,7 +572,7 @@ nav-enemy-default-event-handler ) ) ) - (logclear! (-> self nav flags) (nav-control-flags bit17 bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf17 navcf19)) (nav-enemy-get-new-patrol-point) (let ((a0-18 (-> self skel root-channel 0))) (set! (-> a0-18 frame-group) (the-as art-joint-anim (-> self draw art-group data 5))) @@ -707,7 +706,7 @@ nav-enemy-default-event-handler :use-proximity-notice #f :use-jump-blocked #t :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/goal_src/levels/misty/mistycannon.gc b/goal_src/levels/misty/mistycannon.gc index 42506eb54a..fb937322cd 100644 --- a/goal_src/levels/misty/mistycannon.gc +++ b/goal_src/levels/misty/mistycannon.gc @@ -860,7 +860,7 @@ (-> self root-override shadow-pos) 8192.0 (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) 0.0 81920.0 ) diff --git a/goal_src/levels/misty/muse.gc b/goal_src/levels/misty/muse.gc index 3690ab649b..6f1e4cacdf 100644 --- a/goal_src/levels/misty/muse.gc +++ b/goal_src/levels/misty/muse.gc @@ -368,8 +368,8 @@ nav-enemy-default-event-handler (-> self nav destination-pos) 546133.3 ) - (if (logtest? (nav-control-flags bit21) (-> self nav flags)) - (logclear! (-> self nav flags) (nav-control-flags bit10)) + (if (logtest? (nav-control-flags navcf21) (-> self nav flags)) + (logclear! (-> self nav flags) (nav-control-flags navcf10)) ) (nav-enemy-travel-post) (none) @@ -386,7 +386,7 @@ nav-enemy-default-event-handler :enter (behavior () ((-> (method-of-type nav-enemy nav-enemy-jump) enter)) - (set! (-> self nav-enemy-flags) (logand -513 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags standing-jump)) (none) ) :code @@ -596,7 +596,7 @@ nav-enemy-default-event-handler :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/goal_src/levels/misty/quicksandlurker.gc b/goal_src/levels/misty/quicksandlurker.gc index 7761c5d6d5..33d8267a52 100644 --- a/goal_src/levels/misty/quicksandlurker.gc +++ b/goal_src/levels/misty/quicksandlurker.gc @@ -380,7 +380,7 @@ (the-as vector #f) 8192.0 (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) 0.0 81920.0 ) @@ -1173,7 +1173,7 @@ (set-yaw-angle-clear-roll-pitch! (-> obj root-override) (rand-vu-float-range 0.0 65536.0)) (initialize-skeleton obj *quicksandlurker-sg* '()) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj fact) (new 'process 'fact-info-enemy obj (pickup-type eco-pill-random) (-> *FACT-bank* default-pill-inc)) ) diff --git a/goal_src/levels/ogre/ogreboss.gc b/goal_src/levels/ogre/ogreboss.gc index 3ff880704a..5db216bdd4 100644 --- a/goal_src/levels/ogre/ogreboss.gc +++ b/goal_src/levels/ogre/ogreboss.gc @@ -407,7 +407,7 @@ (-> self pickup-type) (-> *FACT-bank* eco-single-inc) #t - (the-as process-drawable *entity-pool*) + *entity-pool* t1-0 ) ) @@ -1135,7 +1135,7 @@ (the-as vector #f) (the-as float 49152.0) (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) (-> (new 'static 'array float 1 0.0) 0) (the-as float 409600.0) ) diff --git a/goal_src/levels/racer_common/racer-states.gc b/goal_src/levels/racer_common/racer-states.gc index 45ba20095a..ef3028d6d8 100644 --- a/goal_src/levels/racer_common/racer-states.gc +++ b/goal_src/levels/racer_common/racer-states.gc @@ -1070,7 +1070,7 @@ (send-event (ppointer->process (-> self manipy)) 'draw #t) (send-event (ppointer->process (-> self manipy)) 'anim-mode 'clone-anim) (target-timed-invulnerable-off self) - (set! (-> self control pat-ignore-mask) (new 'static 'pat-surface :skip #x1 :noentity #x1)) + (set! (-> self control pat-ignore-mask) (new 'static 'pat-surface :noentity #x1)) (restore-collide-with-as (-> self control)) ((-> target-racing-start exit)) (target-exit) diff --git a/goal_src/levels/robocave/cave-trap.gc b/goal_src/levels/robocave/cave-trap.gc index ea0bf03bc6..a585e1cc39 100644 --- a/goal_src/levels/robocave/cave-trap.gc +++ b/goal_src/levels/robocave/cave-trap.gc @@ -356,9 +356,9 @@ ) (process-drawable-from-entity! obj arg0) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj nav nearest-y-threshold) 409600.0) - (set! (-> obj root-override nav-flags) (logand -2 (-> obj root-override nav-flags))) + (logclear! (-> obj root-override nav-flags) (nav-flags navf0)) (set! (-> obj path) (new 'process 'path-control obj 'path 0.0)) (logior! (-> obj path flags) (path-control-flag display draw-line draw-point draw-text)) (let ((s4-1 (entity-actor-count arg0 'alt-actor))) diff --git a/goal_src/levels/rolling/rolling-lightning-mole.gc b/goal_src/levels/rolling/rolling-lightning-mole.gc index 9f2b78e7ea..dfeb95cb87 100644 --- a/goal_src/levels/rolling/rolling-lightning-mole.gc +++ b/goal_src/levels/rolling/rolling-lightning-mole.gc @@ -456,13 +456,13 @@ :virtual #t :enter (behavior () - (logior! (-> self nav flags) (nav-control-flags bit12)) + (logior! (-> self nav flags) (nav-control-flags navcf12)) ((-> (method-of-type nav-enemy nav-enemy-chase) enter)) (none) ) :exit (behavior () - (logclear! (-> self nav flags) (nav-control-flags bit12)) + (logclear! (-> self nav flags) (nav-control-flags navcf12)) (none) ) :trans @@ -1063,7 +1063,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -1091,7 +1091,7 @@ (process-drawable-from-entity! obj arg0) (initialize-skeleton obj *lightning-mole-sg* '()) (TODO-RENAME-45 obj *lightning-mole-nav-enemy-info*) - (logclear! (-> obj nav flags) (nav-control-flags bit5 bit6 bit7)) + (logclear! (-> obj nav flags) (nav-control-flags navcf5 navcf6 navcf7)) (set! (-> obj draw origin-joint-index) (the-as uint 3)) (set! (-> obj reaction-time) (seconds 0.05)) (set! (-> obj last-reflection-time) 0) diff --git a/goal_src/levels/snow/ice-cube.gc b/goal_src/levels/snow/ice-cube.gc index 323db37e3c..795f6e9148 100644 --- a/goal_src/levels/snow/ice-cube.gc +++ b/goal_src/levels/snow/ice-cube.gc @@ -114,7 +114,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -427,7 +427,7 @@ (= (-> arg0 type) target) ) (set-collide-offense (-> self collide-info) 2 (collide-offense no-offense)) - (logior! (-> self nav-enemy-flags) 256) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (level-hint-spawn (game-text-id ice-cube-hint) "sksp0350" (the-as entity #f) *entity-pool* (game-task none)) ) ) @@ -462,7 +462,7 @@ ) (set-collide-offense (-> self collide-info) 2 (collide-offense no-offense)) ;; NOTE fixed decompiler bug - (set! (-> self nav-enemy-flags) (logior (-> self nav-enemy-flags) 256)) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) ) ) ((= v1-0 'touched) @@ -689,7 +689,7 @@ (collide-kind background) (-> obj collide-info process) s4-0 - (the-as uint 1) + (new 'static 'pat-surface :noentity #x1) ) ) ) @@ -973,7 +973,7 @@ :code (behavior () (dummy-57 self) - (set! (-> self nav-enemy-flags) (logand -3 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (logclear! (-> self mask) (process-mask actor-pause)) (go ice-cube-face-player) (none) @@ -988,7 +988,7 @@ :enter (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (dummy-57 self) (logclear! (-> self mask) (process-mask actor-pause)) (if (or (not *target*) @@ -1163,7 +1163,7 @@ :enter (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (dummy-58 self) (if (or (not *target*) (logtest? (-> *target* state-flags) #x80f8) @@ -1276,7 +1276,7 @@ (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) (dummy-58 self) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (set! (-> self next-skid-sound-time) (-> *display* base-frame-counter)) (if (or (not *target*) (logtest? (-> *target* state-flags) #x80f8) @@ -1288,7 +1288,7 @@ (set! (-> self acceleration) (-> self nav-info run-acceleration)) (set! (-> self rotate-speed) (-> self nav-info run-rotate-speed)) (set! (-> self turn-time) (-> self nav-info run-turn-time)) - (logclear! (-> self nav flags) (nav-control-flags bit8)) + (logclear! (-> self nav flags) (nav-control-flags navcf8)) (set-root-prim-collide-with! (-> self collide-info) (collide-kind cak-2 cak-3 target crate enemy)) (set! (-> self track-target?) #t) (set! (-> self slow-down?) #f) @@ -1302,7 +1302,7 @@ ) :exit (behavior () - (logior! (-> self nav flags) (nav-control-flags bit8)) + (logior! (-> self nav flags) (nav-control-flags navcf8)) (set-root-prim-collide-with! (-> self collide-info) (collide-kind target)) (none) ) diff --git a/goal_src/levels/snow/snow-bunny.gc b/goal_src/levels/snow/snow-bunny.gc index f97259b980..b0f6ec0bce 100644 --- a/goal_src/levels/snow/snow-bunny.gc +++ b/goal_src/levels/snow/snow-bunny.gc @@ -100,7 +100,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -122,7 +122,7 @@ (when (send-event-function arg0 a1-5) (set! (-> self touch-time) (-> *display* base-frame-counter)) (set-collide-offense (-> self collide-info) 2 (collide-offense no-offense)) - (logior! (-> self nav-enemy-flags) 256) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (go-virtual snow-bunny-attack) ) ) @@ -254,8 +254,8 @@ (defbehavior snow-bunny-initialize-jump snow-bunny ((arg0 vector)) (nav-enemy-initialize-custom-jump arg0 #f (-> self jump-height-min) (-> self jump-height-factor) -307200.0) - (set! (-> self nav-enemy-flags) (logand -1025 (-> self nav-enemy-flags))) - (logior! (-> self nav-enemy-flags) 512) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags drop-jump)) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags standing-jump)) 0 (none) ) @@ -431,9 +431,9 @@ (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) (dummy-76 self #f) - (set! (-> self nav flags) (logior (nav-control-flags bit19) (-> self nav flags))) - (set! (-> self nav-enemy-flags) (logand -5 (-> self nav-enemy-flags))) - (logior! (-> self nav-enemy-flags) 8) + (set! (-> self nav flags) (logior (nav-control-flags navcf19) (-> self nav flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (set! (-> self state-timeout) (seconds 0.1)) (none) ) @@ -533,7 +533,7 @@ (collide-kind background) (-> obj collide-info process) s4-0 - (the-as uint 1) + (new 'static 'pat-surface :noentity #x1) ) ) ) @@ -664,8 +664,8 @@ ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 24) - (set! (-> self collide-info nav-flags) (logand -3 (-> self collide-info nav-flags))) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) + (logclear! (-> self collide-info nav-flags) (nav-flags navf1)) (none) ) :trans @@ -697,12 +697,12 @@ snow-bunny-default-event-handler :enter (behavior () - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (nav-enemy-neck-control-look-at) - (if (logtest? (-> self nav-enemy-flags) 2) + (if (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (go-virtual nav-enemy-chase) ) - (logior! (-> self nav-enemy-flags) 2) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (dummy-76 self #t) (set-vector! (-> self collide-info transv) 0.0 (nav-enemy-rnd-float-range 102400.0 131072.0) 0.0 1.0) (none) @@ -898,7 +898,7 @@ (go-virtual snow-bunny-defend) ) (when (not (dummy-52 self)) - (set! (-> self nav-enemy-flags) (logand -3 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (go-virtual nav-enemy-notice) ) (set-jump-height-factor! self 1) @@ -910,8 +910,8 @@ ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 24) - (set! (-> self collide-info nav-flags) (logand -3 (-> self collide-info nav-flags))) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) + (logclear! (-> self collide-info nav-flags) (nav-flags navf1)) (none) ) :trans @@ -1193,8 +1193,8 @@ ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 24) - (set! (-> self collide-info nav-flags) (logand -3 (-> self collide-info nav-flags))) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) + (logclear! (-> self collide-info nav-flags) (nav-flags navf1)) (none) ) :trans diff --git a/goal_src/levels/snow/snow-ram-boss.gc b/goal_src/levels/snow/snow-ram-boss.gc index 156127b702..4be24ad6e0 100644 --- a/goal_src/levels/snow/snow-ram-boss.gc +++ b/goal_src/levels/snow/snow-ram-boss.gc @@ -127,7 +127,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -180,7 +180,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -490,7 +490,7 @@ (the-as vector #f) f0-9 (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) 0.0 81920.0 ) @@ -926,7 +926,7 @@ v0-4 ) ((begin - (if (zero? (logand (-> self nav-enemy-flags) 256)) + (if (zero? (logand (-> self nav-enemy-flags) (nav-enemy-flags navenmf8))) (do-push-aways! (-> self collide-info)) ) (level-hint-spawn @@ -983,7 +983,7 @@ ) ) (('touch) - (if (zero? (logand (-> self nav-enemy-flags) 256)) + (if (zero? (logand (-> self nav-enemy-flags) (nav-enemy-flags navenmf8))) (do-push-aways! (-> self collide-info)) ) (cond @@ -1233,7 +1233,7 @@ ) (else (ja-post) - (logior! (-> self nav-enemy-flags) 2) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (go ram-boss-idle) ) ) @@ -1375,7 +1375,7 @@ ) :code (behavior () - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (while #t (clone-anim-once (ppointer->handle (-> self parent-override)) @@ -1415,7 +1415,7 @@ :enter (behavior ((arg0 basic)) (dummy-52 self) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (let ((s5-0 (new 'stack-no-clear 'vector)) (gp-0 (-> self node-list data 0 bone transform)) ) @@ -1497,7 +1497,7 @@ (-> ram-boss-jump-down event) :code (behavior () - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (activate! *camera-smush-control* 409.6 37 150 1.0 0.99) (let ((a0-1 (-> self skel root-channel 0))) (set! (-> a0-1 frame-group) (the-as art-joint-anim (-> self draw art-group data 17))) @@ -1516,7 +1516,7 @@ (joint-control-channel-group-eval! a0-2 (the-as art-joint-anim #f) num-func-seek!) ) ) - (logior! (-> self nav-enemy-flags) 2) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (go ram-boss-nav-start) (none) ) @@ -1527,7 +1527,7 @@ (defstate ram-boss-already-down (ram-boss) :code (behavior ((arg0 basic)) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (dummy-52 self) (let ((a1-0 (new 'stack-no-clear 'vector)) (a2-0 (-> self parent-override 0 node-list data 0 bone transform)) @@ -1646,7 +1646,7 @@ ) ) (cond - ((logtest? (nav-control-flags bit17) (-> self nav flags)) + ((logtest? (nav-control-flags navcf17) (-> self nav flags)) (if (>= (- (-> *display* base-frame-counter) (-> self free-time)) (seconds 1)) (go-virtual nav-enemy-patrol) ) @@ -1705,7 +1705,7 @@ (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) (set! (-> self facing-y) (quaternion-y-angle (-> self collide-info quat))) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (none) ) :trans @@ -1908,7 +1908,7 @@ :enter (behavior () (set! (-> self frustration) 0) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (none) ) :trans @@ -1948,7 +1948,7 @@ :enter (behavior () (set! (-> self frustration) 0) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (none) ) :trans @@ -2059,7 +2059,7 @@ ram-boss-on-ground-event-handler :enter (behavior () - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (let ((gp-0 (-> self child))) (while gp-0 (send-event (ppointer->process gp-0) 'launch) @@ -2128,7 +2128,7 @@ (defstate ram-boss-lose-shield (ram-boss) :enter (behavior () - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (nav-enemy-neck-control-inactive) (dummy-53 self) (TODO-RENAME-49 self *ram-boss-nav-enemy-info-no-shield*) diff --git a/goal_src/levels/snow/yeti.gc b/goal_src/levels/snow/yeti.gc index 83d317ce1a..d50f50435c 100644 --- a/goal_src/levels/snow/yeti.gc +++ b/goal_src/levels/snow/yeti.gc @@ -107,7 +107,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -229,7 +229,7 @@ (if (-> self nav-info move-to-ground) (move-to-ground (-> self collide-info) 40960.0 40960.0 #t (collide-kind background)) ) - (set! (-> self nav-enemy-flags) (logand -7 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1 navenmf2)) (set! (-> self state-timeout) (seconds 1)) (set! (-> self ground-y) (-> self collide-info trans y)) (spawn (-> self part) (-> self collide-info trans)) @@ -388,7 +388,7 @@ (joint-control-channel-group! a0-14 (the-as art-joint-anim #f) num-func-loop!) ) (ja-channel-push! 1 180) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (let ((gp-1 (nav-enemy-rnd-int-range 2 6))) (dotimes (s5-0 gp-1) (let ((a0-18 (-> self skel root-channel 0))) @@ -411,7 +411,7 @@ ) ) ) - (logior! (-> self nav-enemy-flags) 8) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (let ((a0-21 (-> self skel root-channel 0))) (set! (-> a0-21 param 0) 1.0) (joint-control-channel-group! a0-21 (the-as art-joint-anim #f) num-func-loop!) @@ -514,7 +514,7 @@ (behavior () (set! (-> self turn-time) (seconds 0.2)) (let ((f30-0 (nav-enemy-rnd-float-range 0.8 1.2))) - (when (or (logtest? (-> self nav-enemy-flags) 256) + (when (or (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (and (nav-enemy-player-vulnerable?) (nav-enemy-rnd-percent? 0.5)) ) (ja-channel-push! 1 30) @@ -536,7 +536,7 @@ ) (while #t (when (not (nav-enemy-facing-player? 2730.6667)) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((a0-9 (-> self skel root-channel 0))) (set! (-> a0-9 param 0) 1.0) (joint-control-channel-group! a0-9 (the-as art-joint-anim #f) num-func-loop!) @@ -557,7 +557,7 @@ (joint-control-channel-group-eval! a0-15 (the-as art-joint-anim #f) num-func-loop!) ) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) ) (if (not (= (if (> (-> self skel active-channels) 0) (-> self skel root-channel 0 frame-group) @@ -642,7 +642,7 @@ ) ) ) - (logclear! (-> self nav flags) (nav-control-flags bit17 bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf17 navcf19)) (nav-enemy-get-new-patrol-point) (let ((a0-12 (-> self skel root-channel 0))) (set! (-> a0-12 frame-group) (the-as art-joint-anim (-> self draw art-group data 7))) diff --git a/goal_src/levels/sunken/bully.gc b/goal_src/levels/sunken/bully.gc index 510e836a8e..868874cfd4 100644 --- a/goal_src/levels/sunken/bully.gc +++ b/goal_src/levels/sunken/bully.gc @@ -1056,7 +1056,7 @@ (initialize-skeleton obj *bully-sg* '()) (set! (-> obj draw shadow-ctrl) *bully-shadow-control*) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj part) (create-launch-control (-> *part-group-id-table* 454) obj)) (set! (-> obj fact-override) (new 'process 'fact-info-enemy obj (pickup-type eco-pill-random) (-> *FACT-bank* default-pill-inc)) diff --git a/goal_src/levels/sunken/double-lurker.gc b/goal_src/levels/sunken/double-lurker.gc index 23d4c3c5f5..c2149d8968 100644 --- a/goal_src/levels/sunken/double-lurker.gc +++ b/goal_src/levels/sunken/double-lurker.gc @@ -119,7 +119,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -173,7 +173,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -227,7 +227,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -330,8 +330,8 @@ (set! (-> v1-3 settings flags) (logand -33 (-> v1-3 settings flags))) ) 0 - (set! (-> self collide-info nav-flags) (logand -2 (-> self collide-info nav-flags))) - (logior! (-> self collide-info nav-flags) 2) + (logclear! (-> self collide-info nav-flags) (nav-flags navf0)) + (logior! (-> self collide-info nav-flags) (nav-flags navf1)) (set! (-> self nav extra-nav-sphere quad) (-> self fall-dest quad)) (set! (-> self nav extra-nav-sphere w) 9011.2) (let ((gp-0 (new 'stack-no-clear 'vector))) @@ -361,8 +361,8 @@ ) ) ) - (logior! (-> self collide-info nav-flags) 1) - (set! (-> self collide-info nav-flags) (logand -3 (-> self collide-info nav-flags))) + (logior! (-> self collide-info nav-flags) (nav-flags navf0)) + (logclear! (-> self collide-info nav-flags) (nav-flags navf1)) (TODO-RENAME-27 (-> self nav)) (go double-lurker-top-resume) (none) @@ -440,7 +440,7 @@ (defmethod dummy-51 double-lurker-top ((obj double-lurker-top)) (restore-collide-with-as (-> obj collide-info)) - (logior! (-> obj collide-info nav-flags) 1) + (logior! (-> obj collide-info nav-flags) (nav-flags navf0)) (TODO-RENAME-27 (-> obj nav)) (none) ) @@ -524,7 +524,7 @@ (set-vector! (-> obj collide-info scale) 1.0 1.0 1.0 1.0) (quaternion-copy! (-> obj collide-info quat) (-> v1-5 0 collide-info quat)) ) - (set! (-> obj collide-info nav-flags) (logand -2 (-> obj collide-info nav-flags))) + (logclear! (-> obj collide-info nav-flags) (nav-flags navf0)) (none) ) diff --git a/goal_src/levels/sunken/orbit-plat.gc b/goal_src/levels/sunken/orbit-plat.gc index 567432d3d2..39625b0548 100644 --- a/goal_src/levels/sunken/orbit-plat.gc +++ b/goal_src/levels/sunken/orbit-plat.gc @@ -553,7 +553,7 @@ (defun get-nav-point! ((arg0 vector) (arg1 orbit-plat) (arg2 vector) (arg3 float)) (set! (-> arg1 nav target-pos quad) (-> arg2 quad)) - (logclear! (-> arg1 nav flags) (nav-control-flags bit19)) + (logclear! (-> arg1 nav flags) (nav-control-flags navcf19)) (dummy-11 (-> arg1 nav) (-> arg1 nav target-pos)) (let ((f0-0 (vector-length (-> arg1 nav travel)))) (if (< arg3 f0-0) @@ -717,7 +717,7 @@ ) ) (when (>= 614.4 (vector-vector-xz-distance (-> obj basetrans) (-> obj reset-trans))) - (set! v0-11 (logior (nav-control-flags bit19) (-> obj nav flags))) + (set! v0-11 (logior (nav-control-flags navcf19) (-> obj nav flags))) (set! (-> obj nav flags) (the-as nav-control-flags v0-11)) v0-11 ) @@ -744,7 +744,7 @@ (vector-normalize! s5-2 (-> obj reset-length)) (vector+! s5-2 s5-2 s4-1) (when (not (dummy-16 (-> obj nav) s5-2)) - (logclear! (-> obj nav flags) (nav-control-flags bit19)) + (logclear! (-> obj nav flags) (nav-control-flags navcf19)) (get-rotate-point! s5-2 s4-1 (-> obj basetrans) (the-as vector (-> obj reset-length)) 0.0 40960.0) (when (not (dummy-16 (-> obj nav) s5-2)) (get-rotate-point! @@ -812,13 +812,13 @@ :code (behavior () (set! (-> self plat-status) (the-as uint 3)) - (logclear! (-> self nav flags) (nav-control-flags bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf19)) (let ((a0-3 (-> self skel root-channel 0))) (set! (-> a0-3 param 0) 0.0) (set! (-> a0-3 param 1) 1.0) (joint-control-channel-group! a0-3 (the-as art-joint-anim #f) num-func-seek!) ) - (while (zero? (logand (nav-control-flags bit19) (-> self nav flags))) + (while (zero? (logand (nav-control-flags navcf19) (-> self nav flags))) (dummy-27 self) (when (nonzero? (-> self root-override riders num-riders)) (let ((a1-1 (new 'stack-no-clear 'event-message-block))) @@ -927,7 +927,7 @@ (update-transforms! (-> obj root-override)) (dummy-21 obj) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj nav gap-event) 'blocked) (set! (-> obj other) (entity-actor-lookup arg0 'alt-actor 0)) (let ((f0-7 (res-lump-float arg0 'scale :default 1.0))) diff --git a/goal_src/levels/sunken/puffer.gc b/goal_src/levels/sunken/puffer.gc index b743df03a4..5f35c0f04d 100644 --- a/goal_src/levels/sunken/puffer.gc +++ b/goal_src/levels/sunken/puffer.gc @@ -155,7 +155,10 @@ (defmethod dummy-28 puffer ((obj puffer)) (cond - ((and (-> obj draw shadow) (zero? (-> obj draw cur-lod)) (logtest? (-> obj draw status) (draw-status was-drawn))) + ((and (-> obj draw shadow) + (zero? (-> obj draw cur-lod)) + (logtest? (-> obj draw status) (draw-status was-drawn)) + ) (let ((s5-0 (new 'stack-no-clear 'collide-tri-result)) (a1-0 (new 'stack-no-clear 'vector)) (a2-0 (new 'stack-no-clear 'vector)) @@ -1204,7 +1207,7 @@ (set! (-> obj notice-dist) (res-lump-float arg0 'notice-dist :default 57344.0)) (set! (-> obj give-up-dist) (+ 20480.0 (-> obj notice-dist))) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (TODO-RENAME-26 (-> obj nav)) (set! (-> obj path) (new 'process 'path-control obj 'path 0.0)) (logior! (-> obj path flags) (path-control-flag display draw-line draw-point draw-text)) diff --git a/goal_src/levels/swamp/billy.gc b/goal_src/levels/swamp/billy.gc index 6fce71ad4c..b374b4cdc3 100644 --- a/goal_src/levels/swamp/billy.gc +++ b/goal_src/levels/swamp/billy.gc @@ -281,7 +281,7 @@ ) ) (send-event (ppointer->process (-> self billy)) 'billy-rat-needs-destination) - (logclear! (-> self nav flags) (nav-control-flags bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf19)) (go-virtual nav-enemy-chase) (none) ) @@ -350,8 +350,8 @@ (t9-1) ) ) - (when (logtest? (nav-control-flags bit19) (-> self nav flags)) - (logclear! (-> self nav flags) (nav-control-flags bit19)) + (when (logtest? (nav-control-flags navcf19) (-> self nav flags)) + (logclear! (-> self nav flags) (nav-control-flags navcf19)) (if (rat-about-to-eat? self (-> self billy 0)) (go billy-rat-salivate) (send-event (ppointer->process (-> self billy)) 'billy-rat-needs-destination) @@ -375,7 +375,7 @@ :trans (behavior () (set! (-> self speed-scale) (-> self billy 0 rat-speed)) - (if (or (logtest? (nav-control-flags bit19) (-> self nav flags)) + (if (or (logtest? (nav-control-flags navcf19) (-> self nav flags)) (>= (- (-> *display* base-frame-counter) (-> self state-time)) (-> self chase-rest-time)) ) (go-virtual nav-enemy-victory) diff --git a/goal_src/levels/swamp/kermit.gc b/goal_src/levels/swamp/kermit.gc index bcd064e98e..95f9eec7a4 100644 --- a/goal_src/levels/swamp/kermit.gc +++ b/goal_src/levels/swamp/kermit.gc @@ -604,7 +604,7 @@ (the-as vector #f) 8192.0 (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) 0.0 81920.0 ) @@ -923,7 +923,7 @@ (defbehavior kermit-set-rotate-dir-to-nav-target kermit () (cond - ((logtest? (nav-control-flags bit19) (-> self nav flags)) + ((logtest? (nav-control-flags navcf19) (-> self nav flags)) (vector-! (-> self rotate-dir) (-> self nav target-pos) (-> self collide-info trans)) ) (else @@ -1076,7 +1076,7 @@ nav-enemy-default-event-handler (if (and (not (-> self airborne)) (nav-enemy-test-point-in-nav-mesh? (target-pos 0))) (go kermit-notice) ) - (if (logtest? (nav-control-flags bit19) (-> self nav flags)) + (if (logtest? (nav-control-flags navcf19) (-> self nav flags)) (kermit-get-new-patrol-point) ) (none) @@ -1193,7 +1193,7 @@ nav-enemy-default-event-handler (behavior () (when (not (-> self airborne)) (if (or (>= (- (-> *display* base-frame-counter) (-> self state-time)) (seconds 3)) - (and (logtest? (nav-control-flags bit19) (-> self nav flags)) + (and (logtest? (nav-control-flags navcf19) (-> self nav flags)) (>= (- (-> *display* base-frame-counter) (-> self state-time)) (seconds 0.5)) ) ) @@ -1627,7 +1627,7 @@ nav-enemy-default-event-handler :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/goal_src/levels/swamp/swamp-rat-nest.gc b/goal_src/levels/swamp/swamp-rat-nest.gc index 8d5a065e51..1e9afbc147 100644 --- a/goal_src/levels/swamp/swamp-rat-nest.gc +++ b/goal_src/levels/swamp/swamp-rat-nest.gc @@ -910,7 +910,7 @@ (set! (-> self entity) gp-0) ) (set! (-> self nav) (new 'process 'nav-control (-> self root-override) 16 40960.0)) - (logior! (-> self nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> self nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set-current-poly! (-> self nav) (find-poly (-> self nav) (-> self root-override trans))) (+! (-> self parent-process 0 hit-points) 3) (dummy-21 self) diff --git a/goal_src/levels/swamp/swamp-rat.gc b/goal_src/levels/swamp/swamp-rat.gc index c691e60c73..c1399cb8f7 100644 --- a/goal_src/levels/swamp/swamp-rat.gc +++ b/goal_src/levels/swamp/swamp-rat.gc @@ -298,7 +298,7 @@ swamp-rat-default-event-handler (set! (-> self turn-time) (seconds 0.07333333)) (let ((f30-0 (rand-vu-float-range 0.8 1.2))) (while #t - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (ja-channel-push! 1 30) (let ((a0-2 (-> self skel root-channel 0))) (set! (-> a0-2 frame-group) (the-as art-joint-anim (-> self draw art-group data 10))) @@ -321,7 +321,7 @@ swamp-rat-default-event-handler (set! (-> a0-5 param 0) 1.0) (joint-control-channel-group! a0-5 (the-as art-joint-anim #f) num-func-loop!) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((gp-0 (rand-vu-int-range 300 600)) (s5-0 (-> *display* base-frame-counter)) ) @@ -365,7 +365,7 @@ swamp-rat-default-event-handler (joint-control-channel-group-eval! a0-2 (the-as art-joint-anim #f) num-func-seek!) ) ) - (logclear! (-> self nav flags) (nav-control-flags bit17 bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf17 navcf19)) (nav-enemy-get-new-patrol-point) (let ((a0-7 (-> self skel root-channel 0))) (set! (-> a0-7 frame-group) (the-as art-joint-anim (-> self draw art-group data 4))) @@ -561,7 +561,7 @@ swamp-rat-default-event-handler :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/goal_src/levels/village1/village-obs.gc b/goal_src/levels/village1/village-obs.gc index 0a8cc9269b..2d76bb4453 100644 --- a/goal_src/levels/village1/village-obs.gc +++ b/goal_src/levels/village1/village-obs.gc @@ -739,7 +739,7 @@ :enter (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (set! (-> self nav flags) (logior (nav-control-flags bit19) (-> self nav flags))) + (set! (-> self nav flags) (logior (nav-control-flags navcf19) (-> self nav flags))) (none) ) :trans @@ -829,7 +829,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/goal_src/levels/village1/yakow.gc b/goal_src/levels/village1/yakow.gc index 42e0d52c0c..092bdc1aca 100644 --- a/goal_src/levels/village1/yakow.gc +++ b/goal_src/levels/village1/yakow.gc @@ -618,7 +618,7 @@ yakow-default-event-handler :enter (behavior ((arg0 vector)) (set! (-> self state-time) (-> *display* base-frame-counter)) - (logior! (-> self nav flags) (nav-control-flags bit10)) + (logior! (-> self nav flags) (nav-control-flags navcf10)) (set! (-> self nav destination-pos quad) (-> arg0 quad)) (set! (-> self rotate-speed) (-> *YAKOW-bank* walk-rotate-speed)) (set! (-> self turn-time) (-> *YAKOW-bank* walk-turn-time)) @@ -637,7 +637,7 @@ yakow-default-event-handler (go yakow-notice) ) (when (>= (- (-> *display* base-frame-counter) (-> self state-time)) (seconds 0.05)) - (when (or (logtest? (nav-control-flags bit19) (-> self nav flags)) + (when (or (logtest? (nav-control-flags navcf19) (-> self nav flags)) (< (vector-vector-xz-distance (-> self root-override trans) (-> self nav destination-pos)) 4096.0) ) (if (-> self in-pen) @@ -665,8 +665,8 @@ yakow-default-event-handler (-> self nav destination-pos) 131072.0 ) - (if (logtest? (nav-control-flags bit21) (-> self nav flags)) - (logclear! (-> self nav flags) (nav-control-flags bit10)) + (if (logtest? (nav-control-flags navcf21) (-> self nav flags)) + (logclear! (-> self nav flags) (nav-control-flags navcf10)) ) (yakow-post) (none) @@ -796,7 +796,7 @@ yakow-default-event-handler :enter (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (logior! (-> self nav flags) (nav-control-flags bit10)) + (logior! (-> self nav flags) (nav-control-flags navcf10)) (set! (-> self rotate-speed) (-> *YAKOW-bank* run-rotate-speed)) (set! (-> self turn-time) (-> *YAKOW-bank* run-turn-time)) (none) @@ -983,7 +983,7 @@ yakow-default-event-handler (process-drawable-from-entity! obj arg0) (set! (-> obj align) (new 'process 'align-control obj)) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj nav nearest-y-threshold) 409600.0) (set! (-> obj fact-override) (new 'process 'fact-info-enemy obj (pickup-type eco-pill-random) (-> *FACT-bank* default-pill-inc)) diff --git a/goal_src/pc/engine/ui/progress-h.gc b/goal_src/pc/engine/ui/progress-h.gc deleted file mode 100644 index dd63829d43..0000000000 --- a/goal_src/pc/engine/ui/progress-h.gc +++ /dev/null @@ -1,271 +0,0 @@ -;;-*-Lisp-*- -(in-package goal) - -;; name: progress-h.gc -;; name in dgo: progress-h -;; dgos: GAME, ENGINE - - -(defenum progress-screen - :type int64 - (invalid -1) - (fuel-cell 0) - (money 1) - (buzzer 2) - (settings 3) - (game-settings 4) - (graphic-settings 5) - (sound-settings 6) - (memcard-no-space 7) - (memcard-not-inserted 8) - (memcard-not-formatted 9) - (memcard-format 10) - (memcard-data-exists 11) - (memcard-loading 12) - (memcard-saving 13) - (memcard-formatting 14) - (memcard-creating 15) - (load-game 16) - (save-game 17) - (save-game-title 18) - (memcard-insert 19) - (memcard-error-loading 20) - (memcard-error-saving 21) - (memcard-removed 22) - (memcard-no-data 23) - (memcard-error-formatting 24) - (memcard-error-creating 25) - (memcard-auto-save-error 26) - (title 27) - (settings-title 28) - (auto-save 29) - (pal-change-to-60hz 30) - (pal-now-60hz 31) - (no-disc 32) - (bad-disc 33) - (quit 34) - ;; custom - (language-options 35) - ) - -(defun-extern activate-progress process progress-screen none) -(defun-extern hide-progress-screen none) -(defun-extern hide-progress-icons none) - -(declare-type level-tasks-info basic) - -(define-extern *level-task-data* (array level-tasks-info)) -(define-extern *level-task-data-remap* (array int32)) - -(declare-type count-info structure) - -(defun-extern get-game-count int count-info) -(defun-extern progress-allowed? symbol) -(defun-extern pause-allowed? symbol) - -(declare-type progress process) - -(defun-extern deactivate-progress none) -(defun-extern calculate-completion progress float) -(defun-extern make-current-level-available-to-progress none) - -;; DECOMP BEGINS - -(deftype count-info (structure) - ((money-count int32 :offset-assert 0) - (buzzer-count int32 :offset-assert 4) - ) - :pack-me - :method-count-assert 9 - :size-assert #x8 - :flag-assert #x900000008 - ) - - -(deftype game-count-info (basic) - ((length int32 :offset-assert 4) - (data count-info :inline :dynamic :offset-assert 8) - ) - :method-count-assert 9 - :size-assert #x8 - :flag-assert #x900000008 - ) - - -(deftype task-info-data (basic) - ((task-id game-task :offset-assert 4) - (task-name game-text-id 4 :offset-assert 8) - (text-index-when-resolved int32 :offset-assert 24) - ) - :method-count-assert 9 - :size-assert #x1c - :flag-assert #x90000001c - ) - - -(deftype level-tasks-info (basic) - ((level-name-id game-text-id :offset-assert 4) - (text-group-index int32 :offset-assert 8) - (nb-of-tasks int32 :offset-assert 12) - (buzzer-task-index int32 :offset-assert 16) - (task-info task-info-data 8 :offset-assert 20) - ) - :method-count-assert 9 - :size-assert #x34 - :flag-assert #x900000034 - ) - - -(deftype game-option (basic) - ((option-type uint64 :offset-assert 8) - (name game-text-id :offset-assert 16) - (scale basic :offset-assert 20) - (param1 float :offset-assert 24) - (param2 float :offset-assert 28) - (param3 int32 :offset-assert 32) - (value-to-modify pointer :offset-assert 36) - ) - :method-count-assert 9 - :size-assert #x28 - :flag-assert #x900000028 - ) - -;; new custom type to extend the very limited progress-menu system -;; the user can only interact with one element at a time, so a single global is sufficient -(deftype progress-menu-list-tracker (basic) - ((direction symbol :offset-assert 4) ; 'left | 'right - (transition? symbol :offset-assert 8) ; '?? - (x-offset int32 :offset-assert 12) - (selected-index int32 :offset-assert 16))) - -;; why a new global? because i dont want to modify the type below....but that would get me what i want as well! -(define *progress-menu-list-tracker* (new 'static 'progress-menu-list-tracker)) - -(deftype progress (process) - ((current-debug-string int32 :offset-assert 112) - (current-debug-language int32 :offset-assert 116) - (current-debug-group int32 :offset-assert 120) - (in-out-position int32 :offset-assert 124) - (display-state progress-screen :offset-assert 128) - (next-display-state progress-screen :offset-assert 136) - (option-index int32 :offset-assert 144) - (selected-option basic :offset-assert 148) - (completion-percentage float :offset-assert 152) - (ready-to-run basic :offset-assert 156) - (display-level-index int32 :offset-assert 160) - (next-level-index int32 :offset-assert 164) - (task-index int32 :offset-assert 168) - (in-transition basic :offset-assert 172) - (last-in-transition basic :offset-assert 176) - (force-transition basic :offset-assert 180) - (stat-transition basic :offset-assert 184) - (level-transition int32 :offset-assert 188) - (language-selection uint64 :offset-assert 192) - ; true = left | false = right - (language-direction symbol :offset-assert 200) - (language-transition symbol :offset-assert 204) - (language-x-offset int32 :offset-assert 208) - (sides-x-scale float :offset-assert 212) - (sides-y-scale float :offset-assert 216) - (left-x-offset int32 :offset-assert 220) - (right-x-offset int32 :offset-assert 224) - (button-scale float :offset-assert 228) - (slot-scale float :offset-assert 232) - (left-side-x-scale float :offset-assert 236) - (left-side-y-scale float :offset-assert 240) - (right-side-x-scale float :offset-assert 244) - (right-side-y-scale float :offset-assert 248) - (small-orb-y-offset int32 :offset-assert 252) - (big-orb-y-offset int32 :offset-assert 256) - (transition-offset int32 :offset-assert 260) - (transition-offset-invert int32 :offset-assert 264) - (transition-percentage float :offset-assert 268) - (transition-percentage-invert float :offset-assert 272) - (transition-speed float :offset-assert 276) - (total-nb-of-power-cells int32 :offset-assert 280) - (total-nb-of-orbs int32 :offset-assert 284) - (total-nb-of-buzzers int32 :offset-assert 288) - (card-info mc-slot-info :offset-assert 292) - (last-option-index-change time-frame :offset-assert 296) - (video-mode-timeout time-frame :offset-assert 304) - (display-state-stack progress-screen 5 :offset-assert 312) - (option-index-stack int32 5 :offset-assert 352) - (display-state-pos int32 :offset-assert 372) - (nb-of-icons int32 :offset-assert 376) - (icons hud-icon 6 :offset-assert 380) - (max-nb-of-particles int32 :offset-assert 404) - (nb-of-particles int32 :offset-assert 408) - (particles hud-particle 40 :offset-assert 412) - (particle-state int32 40 :offset-assert 572) - ) - :heap-base #x270 - :method-count-assert 59 - :size-assert #x2dc - :flag-assert #x3b027002dc - (:methods - (dummy-14 (_type_) none 14) - (dummy-15 (_type_) none 15) - (dummy-16 (_type_) none 16) - (draw-progress (_type_) none 17) - (dummy-18 () none 18) - (dummy-19 (_type_) symbol 19) - (hidden? (_type_) symbol 20) - (adjust-sprites (_type_) none 21) - (adjust-icons (_type_) none 22) - (adjust-ratios (_type_ symbol symbol) none 23) - (draw-fuel-cell-screen (_type_ int) none 24) - (draw-money-screen (_type_ int) none 25) - (draw-buzzer-screen (_type_ int) none 26) - (draw-notice-screen (_type_) none 27) - (draw-options (_type_ int int float) none 28) - (dummy-29 (_type_) none 29) - (respond-progress (_type_) none 30) - (dummy-31 (_type_) none 31) - (dummy-32 (_type_) symbol 32) - (initialize-icons (_type_) none 33) - (initialize-particles (_type_) none 34) - (draw-memcard-storage-error (_type_ font-context) none 35) - (draw-memcard-data-exists (_type_ font-context) none 36) - (draw-memcard-no-data (_type_ font-context) none 37) - (draw-memcard-accessing (_type_ font-context) none 38) - (draw-memcard-insert (_type_ font-context) none 39) - (draw-memcard-file-select (_type_ font-context) none 40) - (draw-memcard-auto-save-error (_type_ font-context) none 41) - (draw-memcard-removed (_type_ font-context) none 42) - (draw-memcard-error (_type_ font-context) none 43) - (dummy-44 (_type_) none 44) - (push! (_type_) none 45) - (pop! (_type_) none 46) - (dummy-47 (_type_) none 47) - (enter! (_type_ progress-screen int) none 48) - (draw-memcard-format (_type_ font-context) none 49) - (draw-auto-save (_type_ font-context) none 50) - (set-transition-progress! (_type_ int) none 51) - (set-transition-speed! (_type_) none 52) - (dummy-53 (_type_ progress-screen) progress-screen 53) - (draw-pal-change-to-60hz (_type_ font-context) none 54) - (draw-pal-now-60hz (_type_ font-context) none 55) - (draw-no-disc (_type_ font-context) none 56) - (draw-bad-disc (_type_ font-context) none 57) - (draw-quit (_type_ font-context) none 58) - ) - (:states - progress-coming-in - progress-debug - progress-going-out - progress-gone - progress-normal - progress-waiting - ) - ) - - -(define *progress-process* (the-as (pointer progress) #f)) - -(define *progress-last-task-index* 0) - -0 - - - - diff --git a/goal_src/pc/engine/ui/progress/progress-draw.gc b/goal_src/pc/engine/ui/progress/progress-draw.gc deleted file mode 100644 index 44c76589f8..0000000000 --- a/goal_src/pc/engine/ui/progress/progress-draw.gc +++ /dev/null @@ -1,2157 +0,0 @@ -;;-*-Lisp-*- -(in-package goal) - -;; name: progress-draw.gc -;; name in dgo: progress-draw -;; dgos: GAME, ENGINE - -;; DECOMP BEGINS - -(defun adjust-pos ((arg0 int) (arg1 int)) - (if (< arg0 arg1) - 0 - (- arg0 arg1) - ) - ) - -(defmethod draw-fuel-cell-screen progress ((obj progress) (arg0 int)) - (local-vars - (sv-112 int) - (sv-128 int) - (sv-144 int) - (sv-160 (function trsqv float quaternion)) - (sv-176 trsqv) - (sv-192 int) - (sv-208 int) - (sv-224 (function string float font-context int none)) - ) - (hide-progress-icons) - (let ((s5-0 (-> *level-task-data* arg0))) - (if (and (= *cheat-mode* 'debug) (cpad-hold? 0 l3)) - (format *stdcon* "fcd:~d~%" (-> *game-info* fuel-cell-deaths)) - ) - (set! (-> *progress-process* 0 particles 14 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 15 init-pos x) -320.0) - (set! (-> *progress-process* 0 icons 4 icon-x) -320) - (when (and (!= s5-0 #f) (= (-> *game-info* level-opened arg0) 1)) - (set! sv-112 (- (-> *task-egg-starting-x* (-> s5-0 nb-of-tasks)) (-> obj left-x-offset))) - (set! sv-128 (the int (* 47.0 (-> obj transition-percentage-invert)))) - 0 - (let ((s0-0 6) - (s2-0 0) - (s4-1 (if (= (-> obj level-transition) 1) - (- (-> obj transition-offset)) - (-> obj transition-offset) - ) - ) - (f30-0 (-> obj transition-percentage-invert)) - (s1-0 0) - (s3-0 #f) - ) - (when (-> obj stat-transition) - (set! sv-128 47) - (set! s2-0 (if (!= (-> obj display-state) (-> obj next-display-state)) - (- (-> obj transition-offset)) - (-> obj transition-offset) - ) - ) - (set! s4-1 0) - (set! f30-0 1.0) - ) - (set! sv-144 0) - (while (< sv-144 4) - (let ((a0-18 (-> obj icons sv-144 icon 0 root))) - (set! sv-176 a0-18) - (set! sv-160 (method-of-object sv-176 set-yaw-angle-clear-roll-pitch!)) - (let ((a1-2 (+ (y-angle a0-18) (* 182.04445 (* 0.5 (-> *display* time-adjust-ratio)))))) - (sv-160 sv-176 a1-2) - ) - ) - (set! sv-144 (+ sv-144 1)) - ) - (set! sv-192 (+ sv-112 (/ (- (* 47 (-> s5-0 nb-of-tasks)) (* sv-128 (-> s5-0 nb-of-tasks))) 2))) - (set! sv-208 0) - (while (< sv-208 (-> s5-0 nb-of-tasks)) - (let ((v0-4 (get-task-status (-> s5-0 task-info sv-208 task-id))) - (v1-59 -1) - (a0-25 #f) - ) - (set! (-> obj particle-state s0-0) 2) - (cond - ((or (= v0-4 (task-status need-hint)) (= v0-4 (task-status unknown))) - (if (= *kernel-boot-message* 'play) - (set! (-> obj particle-state s0-0) 1) - ) - ) - ((= v0-4 (task-status invalid)) - (set! v1-59 (-> s5-0 task-info sv-208 text-index-when-resolved)) - (set! (-> obj particle-state s0-0) 3) - (set! a0-25 #t) - ) - ((= v0-4 (task-status need-introduction)) - (set! v1-59 0) - ) - ((= v0-4 (task-status need-reminder-a)) - (set! v1-59 0) - ) - ((= v0-4 (task-status need-reminder)) - (set! v1-59 1) - ) - ((= v0-4 (task-status need-reward-speech)) - (set! v1-59 2) - ) - ((= v0-4 (task-status need-resolution)) - (set! v1-59 2) - ) - ) - (if (and (!= *kernel-boot-message* 'play) (= v1-59 -1)) - (set! v1-59 0) - ) - (set! (-> obj particles s0-0 init-pos x) (the float (+ sv-192 s2-0))) - (set! (-> obj particles s0-0 init-pos y) (the float (+ s4-1 204))) - (+! s0-0 1) - (when (= sv-208 (-> obj task-index)) - (set! s1-0 v1-59) - (set! s3-0 a0-25) - (set! (-> obj particles 5 init-pos x) (the float (+ sv-192 s2-0))) - (set! (-> obj particles 5 init-pos y) (the float (+ s4-1 204))) - ) - ) - (set! sv-192 (+ sv-192 sv-128)) - (set! sv-208 (+ sv-208 1)) - ) - (dotimes (v1-77 (- 8 (-> s5-0 nb-of-tasks))) - (set! (-> *progress-process* 0 particles s0-0 init-pos x) (the float (+ s2-0 -320))) - (set! (-> obj particles s0-0 init-pos y) (the float (+ s4-1 194))) - (+! s0-0 1) - ) - (when *common-text* - (when (and (!= s1-0 -1) - (> (-> s5-0 nb-of-tasks) 0) - (>= (-> obj task-index) 0) - (< (-> obj task-index) (-> s5-0 nb-of-tasks)) - ) - (let ((s0-1 (new - 'stack - 'font-context - *font-default-matrix* - (- (+ s2-0 32) (-> obj left-x-offset)) - (+ (/ s4-1 2) 125) - 8325000.0 - (font-color yellow-orange) - (font-flags shadow kerning) - ) - ) - ) - (let ((v1-91 s0-1)) - (set! (-> v1-91 width) (the float 328)) - ) - (let ((v1-92 s0-1)) - (set! (-> v1-92 height) (the float 50)) - ) - (let ((v1-93 s0-1)) - (set! (-> v1-93 scale) 0.7) - ) - (set! (-> s0-1 flags) (font-flags shadow kerning middle left large)) - (set! sv-224 print-game-text-scaled) - (let ((a0-47 (lookup-text! *common-text* (-> s5-0 task-info (-> obj task-index) task-name s1-0) #f)) - (a1-57 f30-0) - (a2-15 s0-1) - (a3-2 (the int (* 128.0 f30-0))) - ) - (sv-224 a0-47 a1-57 a2-15 a3-2) - ) - (when s3-0 - (set! (-> s0-1 origin x) (the float (- (+ s2-0 32) (-> obj left-x-offset)))) - (set! (-> s0-1 origin y) (the float (+ (/ s4-1 2) 175))) - (let ((a0-49 s0-1)) - (set! (-> a0-49 color) (font-color lighter-lighter-blue)) - ) - (let ((v1-104 s0-1)) - (set! (-> v1-104 height) (the float 15)) - ) - (let ((v1-105 s0-1)) - (set! (-> v1-105 scale) 0.5) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id task-completed) #f) - f30-0 - s0-1 - (the int (* 128.0 f30-0)) - ) - ) - ) - ) - ) - ) - ) - ) - 0 - (none) - ) - -(defmethod draw-money-screen progress ((obj progress) (arg0 int)) - (hide-progress-icons) - (let* ((v1-1 (/ (-> obj transition-offset) 16)) - (s4-0 (if (= (-> obj level-transition) 1) - (- (-> obj transition-offset)) - (-> obj transition-offset) - ) - ) - (f30-0 (-> obj transition-percentage-invert)) - (s3-0 (- v1-1)) - ) - (when (-> obj stat-transition) - (set! v1-1 (if (!= (-> obj display-state) (-> obj next-display-state)) - (- (-> obj transition-offset)) - (-> obj transition-offset) - ) - ) - (set! s3-0 v1-1) - (set! s4-0 0) - (set! f30-0 1.0) - ) - (set! (-> obj particles 15 init-pos x) (the float (- (+ v1-1 150) (-> obj left-x-offset)))) - (set! (-> obj particles 15 init-pos y) (the float (+ s4-0 214))) - (set! (-> obj icons 4 icon-x) (- (+ v1-1 148) (-> obj left-x-offset))) - (set! (-> obj icons 4 icon-y) (+ (-> obj big-orb-y-offset) s4-0)) - (let ((a0-15 (-> obj icons 4 icon 0 root))) - (set-yaw-angle-clear-roll-pitch! - a0-15 - (- (y-angle a0-15) (* 182.04445 (* 4.0 (-> *display* time-adjust-ratio)))) - ) - ) - (let ((s4-1 - (new - 'stack - 'font-context - *font-default-matrix* - (- (+ s3-0 200) (-> obj left-x-offset)) - (+ (/ s4-0 2) 96) - 8325000.0 - (font-color default) - (font-flags shadow kerning) - ) - ) - ) - (let ((v1-19 s4-1)) - (set! (-> v1-19 width) (the float 328)) - ) - (let ((v1-20 s4-1)) - (set! (-> v1-20 height) (the float 70)) - ) - (set! (-> s4-1 flags) (font-flags shadow kerning large)) - (let ((s3-1 print-game-text-scaled)) - (format - (clear *temp-string*) - "~D/~D" - (-> *game-info* money-per-level arg0) - (-> *game-counts* data arg0 money-count) - ) - (s3-1 *temp-string* f30-0 s4-1 (the int (* 128.0 f30-0))) - ) - (let ((v1-26 s4-1)) - (set! (-> v1-26 width) (the float 428)) - ) - (set! (-> s4-1 origin x) (+ -220.0 (-> s4-1 origin x))) - (set! (-> s4-1 origin y) (+ 40.0 (-> s4-1 origin y))) - (set! (-> s4-1 flags) (font-flags shadow kerning middle large)) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id total-collected) #f) - (* 0.7 f30-0) - s4-1 - (the int (* 128.0 f30-0)) - ) - (set! (-> s4-1 origin y) (+ 15.0 (-> s4-1 origin y))) - (let ((s5-2 print-game-text-scaled)) - (format (clear *temp-string*) "~D/~D" (the int (-> *game-info* money-total)) (-> obj total-nb-of-orbs)) - (s5-2 *temp-string* f30-0 s4-1 (the int (* 128.0 f30-0))) - ) - ) - ) - 0 - (none) - ) - -(defmethod draw-buzzer-screen progress ((obj progress) (arg0 int)) - (hide-progress-icons) - (let* ((v1-2 (-> *level-task-data* arg0)) - (a0-3 (/ (-> obj transition-offset) 16)) - (s4-0 (if (= (-> obj level-transition) 1) - (- (-> obj transition-offset)) - (-> obj transition-offset) - ) - ) - (f30-0 (-> obj transition-percentage-invert)) - (s3-0 (- a0-3)) - ) - (when (-> obj stat-transition) - (set! a0-3 (if (!= (-> obj display-state) (-> obj next-display-state)) - (- (-> obj transition-offset)) - (-> obj transition-offset) - ) - ) - (set! s3-0 a0-3) - (set! s4-0 0) - (set! f30-0 1.0) - ) - (set! (-> obj particles 14 init-pos x) (the float (- (+ a0-3 150) (-> obj left-x-offset)))) - (set! (-> obj particles 14 init-pos y) (the float (+ s4-0 214))) - (let ((s2-0 0)) - (let ((a1-8 (-> v1-2 buzzer-task-index))) - (if (!= a1-8 -1) - (set! s2-0 (buzzer-count *game-info* (-> v1-2 task-info a1-8 task-id))) - ) - ) - (let ((s4-1 - (new - 'stack - 'font-context - *font-default-matrix* - (- (+ s3-0 200) (-> obj left-x-offset)) - (+ (/ s4-0 2) 96) - 8325000.0 - (font-color default) - (font-flags shadow kerning) - ) - ) - ) - (let ((v1-9 s4-1)) - (set! (-> v1-9 width) (the float 328)) - ) - (let ((v1-10 s4-1)) - (set! (-> v1-10 height) (the float 70)) - ) - (set! (-> s4-1 flags) (font-flags shadow kerning large)) - (let ((s3-1 print-game-text-scaled)) - (format (clear *temp-string*) "~D/~D" s2-0 (-> *game-counts* data arg0 buzzer-count)) - (s3-1 *temp-string* f30-0 s4-1 (the int (* 128.0 f30-0))) - ) - (let ((v1-14 s4-1)) - (set! (-> v1-14 width) (the float 428)) - ) - (set! (-> s4-1 origin x) (+ -220.0 (-> s4-1 origin x))) - (set! (-> s4-1 origin y) (+ 40.0 (-> s4-1 origin y))) - (set! (-> s4-1 flags) (font-flags shadow kerning middle large)) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id total-collected) #f) - (* 0.7 f30-0) - s4-1 - (the int (* 128.0 f30-0)) - ) - (set! (-> s4-1 origin y) (+ 15.0 (-> s4-1 origin y))) - (let ((s5-2 print-game-text-scaled)) - (format (clear *temp-string*) "~D/~D" (the int (-> *game-info* buzzer-total)) (-> obj total-nb-of-buzzers)) - (s5-2 *temp-string* f30-0 s4-1 (the int (* 128.0 f30-0))) - ) - ) - ) - ) - 0 - (none) - ) - -(defmethod draw-memcard-storage-error progress ((obj progress) (arg0 font-context)) - (let ((v1-0 arg0)) - (set! (-> v1-0 scale) 0.55) - ) - (let ((v1-1 arg0)) - (set! (-> v1-1 width) (the float 265)) - ) - (let ((v1-2 arg0)) - (set! (-> v1-2 height) (the float 55)) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (let ((s4-0 (game-text-id card-not-formatted-title))) - (case (-> obj display-state) - (((progress-screen memcard-no-space)) - (set! s4-0 (game-text-id memcard-no-space)) - ) - (((progress-screen memcard-not-inserted)) - (set! s4-0 (game-text-id memcard-not-inserted)) - ) - ) - (let ((s3-0 print-game-text-scaled)) - (format (clear *temp-string*) (lookup-text! *common-text* s4-0 #f) 1) - (s3-0 *temp-string* (-> obj transition-percentage-invert) arg0 128) - ) - ) - (set! (-> arg0 origin x) (the float (- 20 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 70.0) - (let ((v1-12 arg0)) - (set! (-> v1-12 width) (the float 350)) - ) - (let ((v1-13 arg0)) - (set! (-> v1-13 height) (the float 40)) - ) - (let ((s4-1 print-game-text-scaled)) - (format - (clear *temp-string*) - (lookup-text! *common-text* (game-text-id memcard-space-requirement1) #f) - (if (-> obj card-info) - (-> obj card-info mem-required) - 0 - ) - ) - (s4-1 *temp-string* (-> obj transition-percentage-invert) arg0 128) - ) - (set! (-> arg0 origin y) 115.0) - (let ((v1-17 arg0)) - (set! (-> v1-17 height) (the float 60)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id memcard-space-requirement2) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (let ((v1-19 arg0)) - (set! (-> v1-19 scale) 0.65) - ) - (set! (-> arg0 origin y) 160.0) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id continue?) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - 0 - (none) - ) - -(defmethod draw-memcard-format progress ((obj progress) (arg0 font-context)) - (set! (-> arg0 origin y) 35.0) - (let ((v1-0 arg0)) - (set! (-> v1-0 scale) 0.55) - ) - (let ((v1-1 arg0)) - (set! (-> v1-1 width) (the float 265)) - ) - (let ((v1-2 arg0)) - (set! (-> v1-2 height) (the float 55)) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (let ((s4-0 print-game-text-scaled)) - (format (clear *temp-string*) (lookup-text! *common-text* (game-text-id card-not-formatted-title) #f) 1) - (s4-0 *temp-string* (-> obj transition-percentage-invert) arg0 128) - ) - (set! (-> arg0 origin x) (the float (- 20 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 105.0) - (let ((v1-7 arg0)) - (set! (-> v1-7 width) (the float 360)) - ) - (let ((v1-8 arg0)) - (set! (-> v1-8 height) (the float 40)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id card-not-formatted-msg) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (let ((v1-10 arg0)) - (set! (-> v1-10 scale) 0.65) - ) - (set! (-> arg0 origin y) 138.0) - (let ((v1-11 arg0)) - (set! (-> v1-11 height) (the float 60)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id format?) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - 0 - (none) - ) - -(defmethod draw-memcard-data-exists progress ((obj progress) (arg0 font-context)) - (let ((v1-0 arg0)) - (set! (-> v1-0 scale) 0.65) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (set! (-> arg0 origin x) (the float (- 20 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 55.0) - (let ((v1-4 arg0)) - (set! (-> v1-4 width) (the float 365)) - ) - (let ((v1-5 arg0)) - (set! (-> v1-5 height) (the float 75)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id save-data-already-exists) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (set! (-> arg0 origin y) 140.0) - (let ((v1-7 arg0)) - (set! (-> v1-7 width) (the float 360)) - ) - (let ((v1-8 arg0)) - (set! (-> v1-8 height) (the float 40)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id overwrite?) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - 0 - (none) - ) - -(defmethod draw-memcard-no-data progress ((obj progress) (arg0 font-context)) - (let ((v1-0 arg0)) - (set! (-> v1-0 scale) 0.65) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (set! (-> arg0 origin x) (the float (- 20 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 40.0) - (let ((v1-4 arg0)) - (set! (-> v1-4 width) (the float 365)) - ) - (let ((v1-5 arg0)) - (set! (-> v1-5 height) (the float 75)) - ) - (let ((s4-0 print-game-text-scaled)) - (format (clear *temp-string*) (lookup-text! *common-text* (game-text-id no-save-data) #f) 1) - (s4-0 *temp-string* (-> obj transition-percentage-invert) arg0 128) - ) - (set! (-> arg0 origin y) 130.0) - (let ((v1-7 arg0)) - (set! (-> v1-7 width) (the float 360)) - ) - (let ((v1-8 arg0)) - (set! (-> v1-8 height) (the float 40)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id create-save-data?) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - 0 - (none) - ) - -(defmethod draw-memcard-accessing progress ((obj progress) (arg0 font-context)) - (let ((v1-0 arg0)) - (set! (-> v1-0 scale) 1.0) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (set! (-> arg0 origin x) (the float (- 20 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 35.0) - (let ((v1-4 arg0)) - (set! (-> v1-4 width) (the float 365)) - ) - (let ((v1-5 arg0)) - (set! (-> v1-5 height) (the float 75)) - ) - (when (or (< (mod (-> *display* real-frame-counter) 300) 150) (!= (-> obj transition-percentage-invert) 1.0)) - (let ((a1-1 (game-text-id loading-data))) - (case (-> obj display-state) - (((progress-screen memcard-saving)) - (set! a1-1 (game-text-id saving-data)) - ) - (((progress-screen memcard-formatting)) - (set! a1-1 (game-text-id formatting)) - ) - (((progress-screen memcard-creating)) - (set! a1-1 (game-text-id creating-save-data)) - ) - ) - (print-game-text-scaled (lookup-text! *common-text* a1-1 #f) (-> obj transition-percentage-invert) arg0 128) - ) - ) - (let ((v1-18 arg0)) - (set! (-> v1-18 scale) 0.65) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (set! (-> arg0 origin x) (the float (- 15 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 100.0) - (let ((v1-22 arg0)) - (set! (-> v1-22 width) (the float 370)) - ) - (let ((v1-23 arg0)) - (set! (-> v1-23 height) (the float 75)) - ) - (let ((s4-1 print-game-text-scaled)) - (format (clear *temp-string*) (lookup-text! *common-text* (game-text-id do-not-remove-mem-card) #f) 1) - (s4-1 *temp-string* (-> obj transition-percentage-invert) arg0 128) - ) - 0 - (none) - ) - -(defmethod draw-memcard-insert progress ((obj progress) (arg0 font-context)) - (let ((v1-0 arg0)) - (set! (-> v1-0 scale) 0.65) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (set! (-> arg0 origin x) (the float (- 50 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 35.0) - (let ((v1-4 arg0)) - (set! (-> v1-4 width) (the float 310)) - ) - (let ((v1-5 arg0)) - (set! (-> v1-5 height) (the float 110)) - ) - (let ((s4-0 print-game-text-scaled)) - (format (clear *temp-string*) (lookup-text! *common-text* (game-text-id insert-memcard) #f) 1) - (s4-0 *temp-string* (-> obj transition-percentage-invert) arg0 128) - ) - (let ((v1-7 arg0)) - (set! (-> v1-7 scale) 0.65) - ) - (set! (-> arg0 origin y) 130.0) - (let ((v1-8 arg0)) - (set! (-> v1-8 height) (the float 60)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id back?) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - 0 - (none) - ) - -(defmethod draw-memcard-file-select progress ((obj progress) (arg0 font-context)) - (local-vars - (sv-16 (function _varargs_ object)) - (sv-32 (function _varargs_ object)) - (sv-48 (function _varargs_ object)) - (sv-64 (function _varargs_ object)) - (sv-80 (function _varargs_ object)) - (sv-96 (function _varargs_ object)) - (sv-112 (function _varargs_ object)) - (sv-128 (function _varargs_ object)) - (sv-144 (function _varargs_ object)) - ) - (let ((s4-0 (* (+ (-> obj transition-offset) -256) 2))) - (if (< s4-0 0) - (set! s4-0 0) - ) - (if (< 500 s4-0) - (set! s4-0 700) - ) - (set! (-> obj particles 19 init-pos x) (the float (- (- 202 (adjust-pos s4-0 150)) (-> obj left-x-offset)))) - (set! (-> obj particles 20 init-pos x) (the float (- (+ (adjust-pos s4-0 100) 202) (-> obj left-x-offset)))) - (set! (-> obj particles 21 init-pos x) (the float (- (- 202 (adjust-pos s4-0 50)) (-> obj left-x-offset)))) - (set! (-> obj particles 22 init-pos x) (the float (- (+ s4-0 202) (-> obj left-x-offset)))) - ) - (cond - ((= (-> *setting-control* current video-mode) 'pal) - (set! (-> obj particles 21 init-pos y) 256.0) - (set! (-> obj particles 22 init-pos y) 338.0) - ) - (else - (set! (-> obj particles 21 init-pos y) 255.0) - (set! (-> obj particles 22 init-pos y) 336.0) - ) - ) - (let ((f0-13 (* 2.0 (+ -0.5 (-> obj transition-percentage-invert))))) - 128 - (if (< f0-13 0.0) - (set! f0-13 0.0) - ) - (let ((s4-1 (the int (* 128.0 f0-13)))) - (let ((v1-29 arg0)) - (set! (-> v1-29 scale) 0.5) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (set! (-> arg0 origin x) (the float (- 102 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 5.0) - (let ((v1-33 arg0)) - (set! (-> v1-33 width) (the float 200)) - ) - (let ((v1-34 arg0)) - (set! (-> v1-34 height) (the float 20)) - ) - (print-game-text - (lookup-text! - *common-text* - (the-as game-text-id (if (= (-> obj display-state) (progress-screen load-game)) - 321 - 320 - ) - ) - #f - ) - arg0 - #f - s4-1 - 22 - ) - (set! (-> arg0 origin y) 26.0) - (let ((v1-37 arg0)) - (set! (-> v1-37 height) (the float 20)) - ) - (let ((s3-3 (-> obj card-info)) - (s2-0 23) - ) - (dotimes (s1-0 4) - (set! (-> arg0 origin x) (the float (- 41 (-> obj left-x-offset)))) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (let ((a0-17 arg0)) - (set! (-> a0-17 color) (font-color default)) - ) - (let ((v1-42 arg0)) - (set! (-> v1-42 width) (the float 320)) - ) - (cond - ((and s3-3 (= (-> s3-3 formatted) 1) (= (-> s3-3 inited) 1) (= (-> s3-3 file s1-0 present) 1)) - (set! (-> obj particles s2-0 init-pos x) (the float (- 66 (-> obj left-x-offset)))) - (let ((v1-57 arg0)) - (set! (-> v1-57 scale) 0.6) - ) - (if (and (< (-> s3-3 file s1-0 level-index) (length *level-task-data-remap*)) - (> (-> s3-3 file s1-0 level-index) 0) - ) - (print-game-text - (lookup-text! - *common-text* - (-> *level-task-data* (-> *level-task-data-remap* (+ (-> s3-3 file s1-0 level-index) -1)) level-name-id) - #f - ) - arg0 - #f - s4-1 - 22 - ) - (print-game-text "OLD SAVE GAME" arg0 #f s4-1 22) - ) - (let ((a0-28 arg0)) - (set! (-> a0-28 color) (font-color blue-white)) - ) - (cond - ((or (>= (seconds 2) (- (-> *display* real-frame-counter) (-> obj last-option-index-change))) - (or (< (mod (- (-> *display* real-frame-counter) (-> obj last-option-index-change)) 1200) 600) - (!= (-> obj option-index) s1-0) - (-> obj in-transition) - ) - ) - (let ((v1-87 arg0)) - (set! (-> v1-87 scale) 0.5) - ) - (set! (-> arg0 origin y) (+ 16.0 (-> arg0 origin y))) - (set! (-> arg0 flags) (font-flags shadow kerning middle large)) - (set! (-> arg0 origin x) (the float (- -73 (-> obj left-x-offset)))) - (let ((v1-91 arg0)) - (set! (-> v1-91 width) (the float 350)) - ) - (let ((s0-2 print-game-text)) - (set! sv-16 format) - (let ((a0-40 (clear *temp-string*)) - (a1-13 "~D") - (a2-5 (the int (-> s3-3 file s1-0 fuel-cell-count))) - ) - (sv-16 a0-40 a1-13 a2-5) - ) - (s0-2 *temp-string* arg0 #f s4-1 22) - ) - (set! (-> arg0 origin x) (the float (- 1 (-> obj left-x-offset)))) - (let ((s0-3 print-game-text)) - (set! sv-32 format) - (let ((a0-44 (clear *temp-string*)) - (a1-15 "~D") - (a2-7 (the int (-> s3-3 file s1-0 money-count))) - ) - (sv-32 a0-44 a1-15 a2-7) - ) - (s0-3 *temp-string* arg0 #f s4-1 22) - ) - (set! (-> arg0 origin x) (the float (- 79 (-> obj left-x-offset)))) - (let ((s0-4 print-game-text)) - (set! sv-48 format) - (let ((a0-48 (clear *temp-string*)) - (a1-17 "~D") - (a2-9 (the int (-> s3-3 file s1-0 buzzer-count))) - ) - (sv-48 a0-48 a1-17 a2-9) - ) - (s0-4 *temp-string* arg0 #f s4-1 22) - ) - (set! (-> arg0 origin y) (+ 1.0 (-> arg0 origin y))) - (let ((v1-108 arg0)) - (set! (-> v1-108 scale) 1.0) - ) - (set! (-> arg0 flags) (font-flags shadow kerning right large)) - (set! (-> arg0 origin x) (the float (- 352 (-> obj left-x-offset)))) - (let ((s0-5 print-game-text)) - (set! sv-64 format) - (let ((a0-52 (clear *temp-string*)) - (a1-19 "~D%") - (a2-11 (the int (-> s3-3 file s1-0 completion-percentage))) - ) - (sv-64 a0-52 a1-19 a2-11) - ) - (s0-5 *temp-string* arg0 #f s4-1 22) - ) - (let ((v1-116 arg0)) - (set! (-> v1-116 scale) 0.5) - ) - (set! (-> arg0 origin y) (+ 9.0 (-> arg0 origin y))) - (set! (-> arg0 flags) (font-flags shadow kerning large)) - (set! (-> arg0 origin x) (the float (- 85 (-> obj left-x-offset)))) - (let ((s0-6 print-game-text)) - (set! sv-80 format) - (let ((a0-56 (clear *temp-string*)) - (a1-21 "/~D") - (a2-17 (if (< 100 (the int (-> s3-3 file s1-0 fuel-cell-count))) - (-> obj total-nb-of-power-cells) - 100 - ) - ) - ) - (sv-80 a0-56 a1-21 a2-17) - ) - (s0-6 *temp-string* arg0 #f s4-1 22) - ) - (set! (-> arg0 origin x) (the float (- 150 (-> obj left-x-offset)))) - (let ((s0-7 print-game-text)) - (set! sv-96 format) - (let ((a0-60 (clear *temp-string*)) - (a1-23 "/~D") - (a2-19 (-> obj total-nb-of-orbs)) - ) - (sv-96 a0-60 a1-23 a2-19) - ) - (s0-7 *temp-string* arg0 #f s4-1 22) - ) - (set! (-> arg0 origin x) (the float (- 238 (-> obj left-x-offset)))) - (let ((s0-8 print-game-text)) - (set! sv-112 format) - (let ((a0-64 (clear *temp-string*)) - (a1-25 "/~D") - (a2-21 (-> obj total-nb-of-buzzers)) - ) - (sv-112 a0-64 a1-25 a2-21) - ) - (s0-8 *temp-string* arg0 #f s4-1 22) - ) - (set! (-> arg0 origin y) (+ 15.0 (-> arg0 origin y))) - ) - (else - (set! (-> arg0 origin y) (+ 18.0 (-> arg0 origin y))) - (set! (-> arg0 origin x) (the float (- 28 (-> obj left-x-offset)))) - (let ((v1-131 arg0)) - (set! (-> v1-131 scale) 0.8) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle large)) - (let ((v1-133 arg0)) - (set! (-> v1-133 width) (the float 350)) - ) - (cond - ((= (scf-get-territory) 1) - (let ((s0-10 print-game-text)) - (set! sv-128 format) - (let ((a0-69 (clear *temp-string*)) - (a1-27 "~X/~X/20~2X ~2X:~2X") - (a2-23 (-> s3-3 file s1-0 day)) - (a3-10 (-> s3-3 file s1-0 month)) - (t0-10 (-> s3-3 file s1-0 year)) - (t1-0 (-> s3-3 file s1-0 hour)) - (t2-0 (-> s3-3 file s1-0 minute)) - ) - (sv-128 a0-69 a1-27 a2-23 a3-10 t0-10 t1-0 t2-0) - ) - (s0-10 *temp-string* arg0 #f s4-1 22) - ) - ) - (else - (let ((s0-11 print-game-text)) - (set! sv-144 format) - (let ((a0-72 (clear *temp-string*)) - (a1-29 "~X/~X/20~2X ~2X:~2X") - (a2-25 (-> s3-3 file s1-0 month)) - (a3-12 (-> s3-3 file s1-0 day)) - (t0-12 (-> s3-3 file s1-0 year)) - (t1-1 (-> s3-3 file s1-0 hour)) - (t2-1 (-> s3-3 file s1-0 minute)) - ) - (sv-144 a0-72 a1-29 a2-25 a3-12 t0-12 t1-1 t2-1) - ) - (s0-11 *temp-string* arg0 #f s4-1 22) - ) - ) - ) - (set! (-> obj particles s2-0 init-pos x) -320.0) - (set! (-> arg0 origin y) (+ 23.0 (-> arg0 origin y))) - ) - ) - ) - (else - (set! (-> obj particles s2-0 init-pos x) -320.0) - (set! (-> arg0 origin y) (+ 12.0 (-> arg0 origin y))) - (let ((v1-173 arg0)) - (set! (-> v1-173 scale) 0.7) - ) - (print-game-text (lookup-text! *common-text* (game-text-id empty) #f) arg0 #f s4-1 22) - (set! (-> arg0 origin y) (+ 29.0 (-> arg0 origin y))) - ) - ) - (+! s2-0 1) - ) - ) - ) - ) - 0 - (none) - ) - -(defmethod draw-memcard-auto-save-error progress ((obj progress) (arg0 font-context)) - (let ((v1-0 arg0)) - (set! (-> v1-0 scale) 0.6) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (set! (-> arg0 origin x) (the float (- 70 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 5.0) - (let ((v1-4 arg0)) - (set! (-> v1-4 width) (the float 265)) - ) - (let ((v1-5 arg0)) - (set! (-> v1-5 height) (the float 35)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id error-saving) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (set! (-> arg0 origin x) (the float (- 20 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 34.0) - (let ((v1-9 arg0)) - (set! (-> v1-9 width) (the float 360)) - ) - (let ((v1-10 arg0)) - (set! (-> v1-10 height) (the float 50)) - ) - (let ((s4-1 print-game-text-scaled)) - (format (clear *temp-string*) (lookup-text! *common-text* (game-text-id check-memcard) #f) 1) - (s4-1 *temp-string* (-> obj transition-percentage-invert) arg0 128) - ) - (set! (-> arg0 origin y) 89.0) - (let ((v1-12 arg0)) - (set! (-> v1-12 width) (the float 360)) - ) - (let ((v1-13 arg0)) - (set! (-> v1-13 height) (the float 20)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id autosave-disabled-title) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (set! (-> arg0 origin y) 118.0) - (let ((v1-15 arg0)) - (set! (-> v1-15 width) (the float 360)) - ) - (let ((v1-16 arg0)) - (set! (-> v1-16 height) (the float 60)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id autosave-disabled-msg) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (let ((v1-18 arg0)) - (set! (-> v1-18 scale) 0.65) - ) - (set! (-> arg0 origin y) 160.0) - (let ((v1-19 arg0)) - (set! (-> v1-19 height) (the float 60)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id continue?) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - 0 - (none) - ) - -(defmethod draw-memcard-removed progress ((obj progress) (arg0 font-context)) - (let ((v1-0 arg0)) - (set! (-> v1-0 scale) 0.6) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (set! (-> arg0 origin x) (the float (- 70 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 10.0) - (let ((v1-4 arg0)) - (set! (-> v1-4 width) (the float 265)) - ) - (let ((v1-5 arg0)) - (set! (-> v1-5 height) (the float 55)) - ) - (let ((s4-0 print-game-text-scaled)) - (format (clear *temp-string*) (lookup-text! *common-text* (game-text-id memcard-removed) #f) 1) - (s4-0 *temp-string* (-> obj transition-percentage-invert) arg0 128) - ) - (set! (-> arg0 origin x) (the float (- 20 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 78.0) - (let ((v1-9 arg0)) - (set! (-> v1-9 width) (the float 360)) - ) - (let ((v1-10 arg0)) - (set! (-> v1-10 height) (the float 20)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id autosave-disabled-title) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (set! (-> arg0 origin y) 112.0) - (let ((v1-12 arg0)) - (set! (-> v1-12 width) (the float 360)) - ) - (let ((v1-13 arg0)) - (set! (-> v1-13 height) (the float 60)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id autosave-disabled-msg) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (let ((v1-15 arg0)) - (set! (-> v1-15 scale) 0.65) - ) - (set! (-> arg0 origin y) 160.0) - (let ((v1-16 arg0)) - (set! (-> v1-16 height) (the float 60)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id continue?) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - 0 - (none) - ) - -(defmethod draw-memcard-error progress ((obj progress) (arg0 font-context)) - (set! (-> arg0 origin y) 15.0) - (let ((v1-0 arg0)) - (set! (-> v1-0 scale) 0.7) - ) - (let ((v1-1 arg0)) - (set! (-> v1-1 width) (the float 265)) - ) - (let ((v1-2 arg0)) - (set! (-> v1-2 height) (the float 55)) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (let ((s4-0 (game-text-id error-loading))) - (case (-> obj display-state) - (((progress-screen memcard-error-saving)) - (set! s4-0 (game-text-id error-saving)) - ) - (((progress-screen memcard-error-formatting)) - (set! s4-0 (game-text-id error-formatting)) - ) - (((progress-screen memcard-error-creating)) - (set! s4-0 (game-text-id error-creating-data)) - ) - ) - (let ((s3-0 print-game-text-scaled)) - (format (clear *temp-string*) (lookup-text! *common-text* s4-0 #f) 1) - (s3-0 *temp-string* (-> obj transition-percentage-invert) arg0 128) - ) - ) - (set! (-> arg0 origin x) (the float (- 20 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 80.0) - (let ((v1-13 arg0)) - (set! (-> v1-13 width) (the float 360)) - ) - (let ((v1-14 arg0)) - (set! (-> v1-14 height) (the float 70)) - ) - (let ((s4-1 print-game-text-scaled)) - (format (clear *temp-string*) (lookup-text! *common-text* (game-text-id check-memcard-and-retry) #f) 1) - (s4-1 *temp-string* (-> obj transition-percentage-invert) arg0 128) - ) - (let ((v1-16 arg0)) - (set! (-> v1-16 scale) 0.65) - ) - (set! (-> arg0 origin y) 155.0) - (let ((v1-17 arg0)) - (set! (-> v1-17 height) (the float 60)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id continue?) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - 0 - (none) - ) - -(defmethod draw-auto-save progress ((obj progress) (arg0 font-context)) - (set! (-> arg0 origin x) (the float (- 35 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 18.0) - (let ((v1-2 arg0)) - (set! (-> v1-2 scale) 0.6) - ) - (let ((v1-3 arg0)) - (set! (-> v1-3 width) (the float 330)) - ) - (let ((v1-4 arg0)) - (set! (-> v1-4 height) (the float 60)) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id autosave-warn-title) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (set! (-> arg0 origin x) (the float (- 15 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 110.0) - (let ((v1-9 arg0)) - (set! (-> v1-9 width) (the float 370)) - ) - (let ((v1-10 arg0)) - (set! (-> v1-10 height) (the float 60)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id autosave-warn-msg) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (let ((v1-12 arg0)) - (set! (-> v1-12 scale) 0.65) - ) - (set! (-> arg0 origin y) 175.0) - (let ((v1-13 arg0)) - (set! (-> v1-13 height) (the float 20)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id continue?) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (set! (-> *progress-process* 0 particles 31 init-pos y) (the float (if (= (get-aspect-ratio) 'aspect16x9) - 170 - 180 - ) - ) - ) - (set! (-> *progress-process* 0 particles 31 init-pos x) - (the float - (- (if (or (< (mod (-> *display* real-frame-counter) 300) 270) (!= (-> obj transition-percentage-invert) 1.0)) - 205 - -320 - ) - (-> obj left-x-offset) - ) - ) - ) - 0 - (none) - ) - -(defmethod draw-pal-change-to-60hz progress ((obj progress) (arg0 font-context)) - (set! (-> arg0 origin x) (the float (- 50 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 20.0) - (let ((v1-2 arg0)) - (set! (-> v1-2 scale) 0.6) - ) - (let ((v1-3 arg0)) - (set! (-> v1-3 width) (the float 300)) - ) - (let ((v1-4 arg0)) - (set! (-> v1-4 height) (the float 40)) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id screen-change-to-60hz) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (set! (-> arg0 origin x) (the float (- 15 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 60.0) - (let ((v1-9 arg0)) - (set! (-> v1-9 width) (the float 370)) - ) - (let ((v1-10 arg0)) - (set! (-> v1-10 height) (the float 60)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id screen-60hz-warn-support) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (set! (-> arg0 origin y) 120.0) - (let ((v1-12 arg0)) - (set! (-> v1-12 height) (the float 50)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id screen-60hz-warn-timer) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (let ((v1-14 arg0)) - (set! (-> v1-14 scale) 0.65) - ) - (set! (-> arg0 origin y) 175.0) - (let ((v1-15 arg0)) - (set! (-> v1-15 height) (the float 20)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id continue?) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - 0 - (none) - ) - -(defmethod draw-no-disc progress ((obj progress) (arg0 font-context)) - (set! (-> arg0 origin x) (the float (- 50 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 50.0) - (let ((v1-2 arg0)) - (set! (-> v1-2 scale) 0.6) - ) - (let ((v1-3 arg0)) - (set! (-> v1-3 width) (the float 300)) - ) - (let ((v1-4 arg0)) - (set! (-> v1-4 height) (the float 40)) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id no-disc-title) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (set! (-> arg0 origin x) (the float (- 20 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 90.0) - (let ((v1-9 arg0)) - (set! (-> v1-9 width) (the float 360)) - ) - (let ((v1-10 arg0)) - (set! (-> v1-10 height) (the float 60)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id no-disc-msg) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (when (is-cd-in?) - (let ((v1-13 arg0)) - (set! (-> v1-13 scale) 0.65) - ) - (set! (-> arg0 origin y) 155.0) - (let ((v1-14 arg0)) - (set! (-> v1-14 height) (the float 20)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id continue?) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - ) - 0 - (none) - ) - -(defmethod draw-bad-disc progress ((obj progress) (arg0 font-context)) - (set! (-> arg0 origin x) (the float (- 50 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 50.0) - (let ((v1-2 arg0)) - (set! (-> v1-2 scale) 0.6) - ) - (let ((v1-3 arg0)) - (set! (-> v1-3 width) (the float 300)) - ) - (let ((v1-4 arg0)) - (set! (-> v1-4 height) (the float 40)) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id bad-disc-title) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (set! (-> arg0 origin x) (the float (- 20 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 90.0) - (let ((v1-9 arg0)) - (set! (-> v1-9 width) (the float 360)) - ) - (let ((v1-10 arg0)) - (set! (-> v1-10 height) (the float 60)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id bad-disc-msg) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (let ((v1-12 arg0)) - (set! (-> v1-12 scale) 0.65) - ) - (set! (-> arg0 origin y) 155.0) - (let ((v1-13 arg0)) - (set! (-> v1-13 height) (the float 20)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id continue?) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - 0 - (none) - ) - -(defmethod draw-quit progress ((obj progress) (arg0 font-context)) - (set! (-> arg0 origin x) (the float (- 50 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 70.0) - (let ((v1-2 arg0)) - (set! (-> v1-2 scale) 0.6) - ) - (let ((v1-3 arg0)) - (set! (-> v1-3 width) (the float 300)) - ) - (let ((v1-4 arg0)) - (set! (-> v1-4 height) (the float 40)) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id quit?) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - 0 - (none) - ) - -(defmethod draw-pal-now-60hz progress ((obj progress) (arg0 font-context)) - (set! (-> arg0 origin x) (the float (- 50 (-> obj left-x-offset)))) - (set! (-> arg0 origin y) 45.0) - (let ((v1-2 arg0)) - (set! (-> v1-2 scale) 0.6) - ) - (let ((v1-3 arg0)) - (set! (-> v1-3 width) (the float 300)) - ) - (let ((v1-4 arg0)) - (set! (-> v1-4 height) (the float 50)) - ) - (set! (-> arg0 flags) (font-flags shadow kerning middle left large)) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id screen-now-60hz) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - (set! (-> arg0 origin y) 95.0) - (let ((v1-7 arg0)) - (set! (-> v1-7 height) (the float 50)) - ) - (print-game-text-scaled - (lookup-text! *common-text* (game-text-id screen-60hz-keep?) #f) - (-> obj transition-percentage-invert) - arg0 - 128 - ) - 0 - (none) - ) - -(defmethod draw-notice-screen progress ((obj progress)) - (hide-progress-icons) - (when *common-text* - (let ((a1-1 (new - 'stack - 'font-context - *font-default-matrix* - (- 70 (-> obj left-x-offset)) - 10 - 0.0 - (font-color default) - (font-flags shadow kerning) - ) - ) - ) - (case (-> obj display-state) - (((progress-screen memcard-format)) - (draw-memcard-format obj a1-1) - ) - (((progress-screen memcard-no-space) - (progress-screen memcard-not-inserted) - (progress-screen memcard-not-formatted) - ) - (draw-memcard-storage-error obj a1-1) - ) - (((progress-screen memcard-data-exists)) - (draw-memcard-data-exists obj a1-1) - ) - (((progress-screen memcard-no-data)) - (draw-memcard-no-data obj a1-1) - ) - (((progress-screen memcard-loading) - (progress-screen memcard-saving) - (progress-screen memcard-formatting) - (progress-screen memcard-creating) - ) - (draw-memcard-accessing obj a1-1) - ) - (((progress-screen memcard-insert)) - (draw-memcard-insert obj a1-1) - ) - (((progress-screen load-game) (progress-screen save-game) (progress-screen save-game-title)) - (draw-memcard-file-select obj a1-1) - ) - (((progress-screen memcard-auto-save-error)) - (draw-memcard-auto-save-error obj a1-1) - ) - (((progress-screen memcard-removed)) - (draw-memcard-removed obj a1-1) - ) - (((progress-screen memcard-error-loading) - (progress-screen memcard-error-saving) - (progress-screen memcard-error-formatting) - (progress-screen memcard-error-creating) - ) - (draw-memcard-error obj a1-1) - ) - (((progress-screen auto-save)) - (draw-auto-save obj a1-1) - ) - (((progress-screen pal-change-to-60hz)) - (draw-pal-change-to-60hz obj a1-1) - ) - (((progress-screen pal-now-60hz)) - (draw-pal-now-60hz obj a1-1) - ) - (((progress-screen no-disc)) - (draw-no-disc obj a1-1) - ) - (((progress-screen bad-disc)) - (draw-bad-disc obj a1-1) - ) - (((progress-screen quit)) - (draw-quit obj a1-1) - ) - ) - ) - ) - 0 - (none) - ) - -(defun draw-percent-bar ((arg0 int) (arg1 int) (arg2 float) (arg3 int)) - (let* ((s2-0 (-> *display* frames (-> *display* on-screen) frame global-buf)) - (gp-0 (-> s2-0 base)) - ) - (draw-sprite2d-xy s2-0 arg0 arg1 255 14 (new 'static 'rgba :a #x60)) - (draw-sprite2d-xy s2-0 arg0 (+ arg1 2) (the int (* 255.0 arg2)) 10 (the-as rgba arg3)) - (let ((a3-3 (-> s2-0 base))) - (let ((v1-3 (the-as dma-packet (-> s2-0 base)))) - (set! (-> v1-3 dma) (new 'static 'dma-tag :id (dma-tag-id next))) - (set! (-> v1-3 vif0) (new 'static 'vif-tag)) - (set! (-> v1-3 vif1) (new 'static 'vif-tag)) - (set! (-> s2-0 base) (&+ (the-as pointer v1-3) 16)) - ) - (dma-bucket-insert-tag - (-> *display* frames (-> *display* on-screen) frame bucket-group) - (bucket-id sprite) - gp-0 - (the-as (pointer dma-tag) a3-3) - ) - ) - ) - 0 - (none) - ) - -(defun print-list-item-name ((arg0 int) (arg1 font-context) (arg2 int) (arg3 symbol) (name-list (array game-text-id))) - (let ((s5-0 (if arg3 - arg2 - (- arg2) - ) - ) - ) - (+! (-> arg1 origin x) (the float s5-0)) - (let ((f30-0 (- 1.0 (* 0.0033333334 (the float arg2))))) - (print-game-text-scaled - (lookup-text! *common-text* (-> name-list arg0) #f) - f30-0 - arg1 - (the int (* 128.0 f30-0)) - ) - ) - (set! (-> arg1 origin x) (- (-> arg1 origin x) (the float s5-0))) - ) - (set! (-> arg1 color) (font-color default)) - arg1 - ) - - -(defun draw-options-list ((obj progress) - (font-ctx font-context) - (something-unknown int) - (name-list (array game-text-id))) - "Given a progress object, draw it's arbitrarily sized list of options. This is option-type `1`" - (local-vars - (list-size int) - (curr-selection-index int) - (unknown-modified-index int) - (unknown-modified-index-2 int) - (unknown-modified-index-3 int) - (unknown-modified-index-4 int) - (screen-arr (array game-option))) - - (set! list-size (length name-list)) - (set! screen-arr (-> *options-remap* (-> obj display-state))) - (set! curr-selection-index (-> *progress-menu-list-tracker* selected-index)) - (if (-> *progress-menu-list-tracker* transition?) - (set! (-> *progress-menu-list-tracker* x-offset) - (seekl (-> *progress-menu-list-tracker* x-offset) - 200 - (the int (* 10.0 (-> *display* time-adjust-ratio)))))) - - (when (>= (-> *progress-menu-list-tracker* x-offset) 100) - (set! (-> *progress-menu-list-tracker* transition?) #f) - (set! (-> *progress-menu-list-tracker* x-offset) 0)) - - (set! (-> font-ctx origin y) (the float (+ something-unknown 3))) - (set! (-> font-ctx color) (font-color lighter-lighter-blue)) - (set! unknown-modified-index (mod (+ curr-selection-index 1) list-size)) - - (let ((unknown-modified-index-2 (mod (+ list-size -1 curr-selection-index) list-size)) - (unknown-modified-index-3 (mod (the-as int (+ curr-selection-index 2)) list-size))) - (set! unknown-modified-index-4 (mod (+ list-size -2 curr-selection-index) list-size)) - ; cleanup this logic, doesnt have to all be conds - (cond - ((= (-> *progress-menu-list-tracker* direction) 'left) - (let ((a2-22 (- 200 (+ (-> *progress-menu-list-tracker* x-offset) 100)))) - (print-list-item-name unknown-modified-index-2 font-ctx a2-22 #f name-list)) - (let ((a2-23 (+ (-> *progress-menu-list-tracker* x-offset) 100))) - (if (< a2-23 150) - (print-list-item-name unknown-modified-index font-ctx a2-23 #t name-list) - (print-list-item-name unknown-modified-index-4 font-ctx (- 200 (-> *progress-menu-list-tracker* x-offset)) #f name-list)))) - (else - (let ((a2-25 (+ (-> *progress-menu-list-tracker* x-offset) 100))) - (cond - ((< a2-25 150) - (print-list-item-name unknown-modified-index-2 font-ctx a2-25 #f name-list)) - (else - (let ((a2-26 (- 200 (-> *progress-menu-list-tracker* x-offset)))) - (print-list-item-name unknown-modified-index-3 font-ctx a2-26 #t name-list))))) - (let ((a2-27 (- 200 (+ (-> *progress-menu-list-tracker* x-offset) 100)))) - (print-list-item-name unknown-modified-index font-ctx a2-27 #t name-list))))) - (when (not (-> *progress-menu-list-tracker* transition?)) - (let ((a0-75 font-ctx)) - (set! (-> a0-75 color) (font-color yellow-green-2)))) - (print-list-item-name (the-as int curr-selection-index) - font-ctx - (-> *progress-menu-list-tracker* x-offset) - (-> *progress-menu-list-tracker* direction) - name-list)) - - -(defmethod draw-options progress ((obj progress) (arg0 int) (arg1 int) (arg2 float)) - (local-vars - (font-ctx font-context) - (sv-128 int) - (sv-144 int) - (sv-160 (function _varargs_ object)) - (sv-176 string) - (sv-192 string) - (sv-208 string) - (sv-224 (function _varargs_ object)) - (sv-240 string) - (sv-256 string) - (sv-272 string) - (sv-288 (function string font-context symbol int int float)) - (sv-304 (function _varargs_ object)) - (sv-320 (function _varargs_ object)) - (sv-336 string) - (sv-352 string) - (sv-368 string) - (sv-384 (function _varargs_ object)) - (sv-400 string) - (sv-416 string) - (sv-432 string) - (sv-448 uint) - (sv-464 int) - (sv-480 int) - (sv-496 int) - (sv-512 uint) - (sv-528 (function _varargs_ object)) - (sv-544 string) - (sv-560 string) - (sv-576 string) - (sv-592 (function _varargs_ object)) - (sv-608 string) - (sv-624 string) - (sv-640 string) - (sv-656 (function _varargs_ object)) - (sv-672 string) - (sv-688 string) - (sv-704 string) - (sv-720 (function _varargs_ object)) - (sv-736 string) - (sv-752 string) - (sv-768 string) - (sv-784 (function _varargs_ object)) - (sv-800 string) - (sv-816 string) - (sv-832 string) - (sv-848 (function _varargs_ object)) - (sv-864 string) - (sv-880 string) - (sv-896 string) - (sv-912 string) - ) - (let ((s3-0 (-> *options-remap* (-> obj display-state)))) - (when s3-0 - (let ((s2-1 (- arg0 (/ (* arg1 (length s3-0)) 2))) - (s1-0 0) - ) - 27 - 0 - (set! font-ctx - (new 'stack 'font-context *font-default-matrix* 0 0 0.0 (font-color default) (font-flags shadow kerning)) - ) - (let ((v1-11 font-ctx)) - (set! (-> v1-11 width) (the float 350)) - ) - (let ((v1-12 font-ctx)) - (set! (-> v1-12 height) (the float 25)) - ) - (set! (-> font-ctx flags) (font-flags shadow kerning middle left large)) - (dotimes (s0-0 (length s3-0)) - (set! sv-912 (the-as string #f)) - (set! sv-128 27) - (set! sv-144 s2-1) - (let ((v1-18 (-> s3-0 s0-0 option-type))) - (cond - ((= v1-18 7) - (cond - ((-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) - (set! sv-160 format) - (set! sv-176 (clear *temp-string*)) - (set! sv-192 "~30L~S~0L ~S") - (set! sv-208 (lookup-text! *common-text* (game-text-id yes) #f)) - (let ((a3-2 (lookup-text! *common-text* (game-text-id no) #f))) - (sv-160 sv-176 sv-192 sv-208 a3-2) - ) - (set! sv-912 *temp-string*) - sv-912 - ) - (else - (set! sv-224 format) - (set! sv-240 (clear *temp-string*)) - (set! sv-256 "~0L~S ~30L~S~1L") - (set! sv-272 (lookup-text! *common-text* (game-text-id yes) #f)) - (let ((a3-3 (lookup-text! *common-text* (game-text-id no) #f))) - (sv-224 sv-240 sv-256 sv-272 a3-3) - ) - (set! sv-912 *temp-string*) - sv-912 - ) - ) - ) - ((or (= v1-18 6) (= v1-18 8)) - (cond - ((nonzero? (-> s3-0 s0-0 name)) - (set! sv-912 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) - sv-912 - ) - (else - (set! sv-912 (the-as string #f)) - (the-as symbol sv-912) - ) - ) - ) - ((and (-> obj selected-option) (= (-> obj option-index) s0-0)) - (let ((a0-19 font-ctx)) - (set! (-> a0-19 color) (font-color default)) - ) - (set! (-> font-ctx origin x) (the float (- sv-128 (-> obj left-x-offset)))) - (case (-> s3-0 s0-0 option-type) - ((3) - (set! (-> font-ctx origin y) (the float (+ s2-1 -20))) - ) - (else - (set! (-> font-ctx origin y) (the float (+ s2-1 -8))) - ) - ) - (let ((v1-64 font-ctx)) - (set! (-> v1-64 scale) 0.6) - ) - (set! sv-288 print-game-text) - (let ((a0-23 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) - (a1-11 font-ctx) - (a2-10 #f) - (a3-4 128) - (t0-1 22) - ) - (sv-288 a0-23 a1-11 a2-10 a3-4 t0-1) - ) - (case (-> s3-0 s0-0 option-type) - ((3) - (set! sv-144 (+ s2-1 3)) - sv-144 - ) - (else - (set! sv-144 (+ s2-1 7)) - sv-144 - ) - ) - (let ((v1-81 (-> s3-0 s0-0 option-type))) - (cond - ((zero? v1-81) - (let* ((v1-82 (the-as uint #x8000ffff)) - (f0-12 (* 0.01 (-> (the-as (pointer float) (-> s3-0 s0-0 value-to-modify))))) - (a0-34 (logior (logand v1-82 -256) (shr (shl (the int (+ 64.0 (* 191.0 f0-12))) 56) 56))) - (a3-5 (logior (logand a0-34 -65281) (shr (shl (shr (shl a0-34 56) 56) 56) 48))) - ) - (draw-percent-bar (- 75 (-> obj left-x-offset)) (+ s2-1 8) f0-12 (the-as int a3-5)) - ) - (set! sv-304 format) - (let ((a0-42 (clear *temp-string*)) - (a1-13 "~D") - (a2-12 (the int (-> (the-as (pointer float) (-> s3-0 s0-0 value-to-modify))))) - ) - (sv-304 a0-42 a1-13 a2-12) - ) - (set! sv-912 *temp-string*) - (set! sv-128 (+ (the int (* 2.5 (-> (the-as (pointer float) (-> s3-0 s0-0 value-to-modify))))) -100)) - sv-128 - ) - ((or (= v1-81 2) (= v1-81 #x15)) - (cond - ((-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) - (set! sv-320 format) - (set! sv-336 (clear *temp-string*)) - (set! sv-352 "~30L~S~0L ~S") - (set! sv-368 (lookup-text! *common-text* (game-text-id on) #f)) - (let ((a3-6 (lookup-text! *common-text* (game-text-id off) #f))) - (sv-320 sv-336 sv-352 sv-368 a3-6) - ) - (set! sv-912 *temp-string*) - sv-912 - ) - (else - (set! sv-384 format) - (set! sv-400 (clear *temp-string*)) - (set! sv-416 "~0L~S ~30L~S~1L") - (set! sv-432 (lookup-text! *common-text* (game-text-id on) #f)) - (let ((a3-7 (lookup-text! *common-text* (game-text-id off) #f))) - (sv-384 sv-400 sv-416 sv-432 a3-7) - ) - (set! sv-912 *temp-string*) - sv-912 - ) - ) - ) - ;; language selection - when selected - ((= v1-81 1) - (draw-options-list obj font-ctx s2-1 *language-name-remap*)) - ((= v1-81 #x10) - (if (-> *pc-settings* use-original-aspect-ratio?) - (draw-options-list obj font-ctx s2-1 *pc-graphics-original-aspect-ratio-mode-remap*) - (draw-options-list obj font-ctx s2-1 *pc-graphics-aspect-ratio-mode-remap*))) - ((= v1-81 #x11) - (case (-> *pc-settings* aspect-ratio-mode) - (('pc-aspect-4x3 'orig-aspect-4x3) - (draw-options-list obj font-ctx s2-1 *pc-graphics-4x3-valid-resolutions-names*)) - (('pc-aspect-5x4) - (draw-options-list obj font-ctx s2-1 *pc-graphics-5x4-valid-resolutions-names*)) - (('pc-aspect-16x9 'orig-aspect-16x9) - (draw-options-list obj font-ctx s2-1 *pc-graphics-16x9-valid-resolutions-names*)) - (('pc-aspect-21x9) - (draw-options-list obj font-ctx s2-1 *pc-graphics-21x9-valid-resolutions-names*)) - (('pc-aspect-32x9) - (draw-options-list obj font-ctx s2-1 *pc-graphics-32x9-valid-resolutions-names*)))) - ((= v1-81 #x12) - (draw-options-list obj font-ctx s2-1 *pc-graphics-display-mode-remap*)) - ((= v1-81 #x13) - (draw-options-list obj font-ctx s2-1 *pc-subtitle-language-name-remap*)) - ((= v1-81 #x14) - (draw-options-list obj font-ctx s2-1 *pc-subtitle-speaker-setting-remap*)) - ((= v1-81 3) - (set! sv-912 (lookup-text! *common-text* (game-text-id move-dpad) #f)) - sv-912 - ) - ;; aspect ratio - original - ((= v1-81 4) - (cond - ((= (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) 'aspect4x3) - (format (clear *temp-string*) - "~30L~S~0L ~S" - (lookup-text! *common-text* (game-text-id 4x3) #f) - (lookup-text! *common-text* (game-text-id 16x9) #f)) - (set! sv-912 *temp-string*) - sv-912 - ) - (else - (format (clear *temp-string*) - "~0L~S ~30L~S~1L" - (lookup-text! *common-text* (game-text-id 4x3) #f) - (lookup-text! *common-text* (game-text-id 16x9) #f)) - (set! sv-912 *temp-string*) - sv-912 - ) - ) - ) - ;; pal refresh rate - ((= v1-81 5) - (cond - ((= (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) 'ntsc) - (set! sv-656 format) - (set! sv-672 (clear *temp-string*)) - (set! sv-688 "~0L~S ~30L~S~1L") - (set! sv-704 (lookup-text! *common-text* (game-text-id 50hz) #f)) - (let ((a3-17 (lookup-text! *common-text* (game-text-id 60hz) #f))) - (sv-656 sv-672 sv-688 sv-704 a3-17) - ) - (set! sv-912 *temp-string*) - sv-912 - ) - (else - (set! sv-720 format) - (set! sv-736 (clear *temp-string*)) - (set! sv-752 "~30L~S~0L ~S") - (set! sv-768 (lookup-text! *common-text* (game-text-id 50hz) #f)) - (let ((a3-18 (lookup-text! *common-text* (game-text-id 60hz) #f))) - (sv-720 sv-736 sv-752 sv-768 a3-18) - ) - (set! sv-912 *temp-string*) - sv-912 - ) - ) - ) - ) - ) - ) - (else - (let ((v1-195 (-> s3-0 s0-0 option-type))) - (cond - ;; boolean flag - ((= v1-195 2) - (set! sv-784 format) - (set! sv-800 (clear *temp-string*)) - (set! sv-816 "~S: ~S") - (set! sv-832 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) - ;; Danger -- assumes there is a value to be modified, iniitalized in progress! - (let ((a3-19 (if (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) - (lookup-text! *common-text* (game-text-id on) #f) - (lookup-text! *common-text* (game-text-id off) #f) - ) - ) - ) - (sv-784 sv-800 sv-816 sv-832 a3-19) - ) - (set! sv-912 *temp-string*) - sv-912 - ) - ;; language selection - ;; unfortunate everything is hard-coded with these ids.. - ((= v1-195 1) - (set! sv-848 format) - (set! sv-864 (clear *temp-string*)) - (set! sv-880 "~S: ~S") - (set! sv-896 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) - (let ((a3-20 (lookup-text! - *common-text* - (-> *language-name-remap* (-> (the-as (pointer uint64) (-> s3-0 s0-0 value-to-modify)))) - #f - ) - ) - ) - (sv-848 sv-864 sv-880 sv-896 a3-20) - ) - (set! sv-912 *temp-string*) - sv-912 - ) - (else - (set! sv-912 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) - sv-912) - ) - ) - ) - ) - ) - (when sv-912 - (let ((f0-23 (-> obj transition-percentage-invert))) - (let ((v1-235 font-ctx)) - (set! (-> v1-235 color) - (the-as font-color (if (and (= s0-0 (-> obj option-index)) (not (-> obj in-transition))) - 30 - 0 - ) - ) - ) - ) - (set! (-> font-ctx origin x) (the float (- sv-128 (-> obj left-x-offset)))) - (set! (-> font-ctx origin y) (the float (the int (* (the float sv-144) (if (-> s3-0 s0-0 scale) - f0-23 - 1.0 - ) - ) - ) - ) - ) - (let ((v1-246 font-ctx)) - (set! (-> v1-246 scale) (* arg2 f0-23)) - ) - (let ((t9-60 print-game-text) - (a1-64 font-ctx) - (a2-50 #f) - (a3-21 (the int (* 128.0 f0-23))) - (t0-2 22) - ) - (t9-60 sv-912 a1-64 a2-50 a3-21 t0-2) - ) - ) - ) - (+! s2-1 arg1) - (+! s1-0 1) - ) - ) - ) - ) - 0 - (none) - ) - -(defmethod draw-progress progress ((obj progress)) - (let ((f30-0 (+ -409.0 (-> obj particles 2 init-pos x) (* 0.8 (the float (-> obj left-x-offset))))) - (s5-0 (if (or (-> obj stat-transition) (nonzero? (-> obj level-transition))) - 0 - (-> obj transition-offset) - ) - ) - ) - (let ((f28-0 (if (or (-> obj stat-transition) (nonzero? (-> obj level-transition))) - 1.0 - (-> obj transition-percentage-invert) - ) - ) - ) - (let* ((s3-0 (-> *display* frames (-> *display* on-screen) frame global-buf)) - (s4-0 (-> s3-0 base)) - ) - (let ((s2-0 draw-string-xy)) - (format (clear *temp-string*) "~D" (the int (+ 0.5 (-> *target* game money)))) - (s2-0 - *temp-string* - s3-0 - (the int (+ 428.0 (the float s5-0) f30-0)) - (- 12 (the int (* 0.16666667 f30-0))) - (font-color default) - (font-flags shadow kerning large) - ) - ) - (let ((s2-1 draw-string-xy)) - (format (clear *temp-string*) "~D" (the int (+ 0.5 (-> *target* game fuel)))) - (s2-1 - *temp-string* - s3-0 - (the int (+ 456.0 (the float (adjust-pos s5-0 50)) f30-0)) - (- 48 (the int (* 0.125 f30-0))) - (font-color default) - (font-flags shadow kerning large) - ) - ) - (let ((s2-2 draw-string-xy)) - (format (clear *temp-string*) "~D" (the int (+ 0.5 (-> *target* fact-info-target buzzer)))) - (s2-2 - *temp-string* - s3-0 - (the int (+ 469.0 (the float (adjust-pos s5-0 100)) f30-0)) - 89 - (font-color default) - (font-flags shadow kerning large) - ) - ) - (let ((a3-4 (-> s3-0 base))) - (let ((v1-20 (the-as object (-> s3-0 base)))) - (set! (-> (the-as dma-packet v1-20) dma) (new 'static 'dma-tag :id (dma-tag-id next))) - (set! (-> (the-as dma-packet v1-20) vif0) (new 'static 'vif-tag)) - (set! (-> (the-as dma-packet v1-20) vif1) (new 'static 'vif-tag)) - (set! (-> s3-0 base) (&+ (the-as pointer v1-20) 16)) - ) - (dma-bucket-insert-tag - (-> *display* frames (-> *display* on-screen) frame bucket-group) - (bucket-id debug-draw0) - s4-0 - (the-as (pointer dma-tag) a3-4) - ) - ) - ) - (let ((s4-2 - (new - 'stack - 'font-context - *font-default-matrix* - (the int (+ (- 423.0 (the float (/ (-> obj left-x-offset) 2))) f30-0 (the float (adjust-pos s5-0 150)))) - 131 - 0.0 - (font-color default) - (font-flags shadow kerning) - ) - ) - ) - (let ((v1-29 s4-2)) - (set! (-> v1-29 width) (the float 100)) - ) - (let ((v1-30 s4-2)) - (set! (-> v1-30 height) (the float 15)) - ) - (let ((v1-31 s4-2)) - (set! (-> v1-31 scale) 0.5) - ) - (set! (-> s4-2 flags) (font-flags shadow kerning large)) - (print-game-text (lookup-text! *common-text* (game-text-id options) #f) s4-2 #f 128 22) - (let ((v1-34 s4-2)) - (set! (-> v1-34 width) (the float 160)) - ) - (let ((v1-35 s4-2)) - (set! (-> v1-35 height) (the float 22)) - ) - (let ((v1-36 s4-2)) - (set! (-> v1-36 scale) 1.3) - ) - (let ((a0-31 s4-2)) - (set! (-> a0-31 color) (font-color another-light-blue)) - ) - (set! (-> s4-2 origin x) - (+ (- 435.0 (the float (if (< (-> *progress-process* 0 completion-percentage) 10.0) - 93 - 80 - ) - ) - ) - f30-0 - ) - ) - (set! (-> s4-2 origin y) 180.0) - (set! (-> s4-2 flags) (font-flags shadow kerning middle left large)) - (let ((s3-3 print-game-text)) - (format (clear *temp-string*) "~2D%" (the int (-> *progress-process* 0 completion-percentage))) - (s3-3 *temp-string* s4-2 #f (the int (* 128.0 f28-0)) 22) - ) - ) - ) - 0.0 - (let ((f28-1 (+ -94.0 (-> obj particles 2 init-pos x))) - (s3-4 90) - (s4-3 224) - (s2-5 (/ s5-0 5)) - (f26-3 (-> obj button-scale)) - ) - (let ((f24-0 (* 182.04445 (- (/ -36.0 f26-3) (the float s2-5))))) - (set! (-> obj particles 27 init-pos x) (the float (+ s3-4 (the int (* f28-1 (cos f24-0)))))) - (set! (-> obj particles 27 init-pos y) (the float (+ s4-3 (the int (* f28-1 (sin f24-0)))))) - ) - (let ((f24-2 (* 182.04445 (- (/ -21.0 f26-3) (the float (adjust-pos s2-5 10)))))) - (set! (-> obj particles 28 init-pos x) (the float (+ s3-4 (the int (* f28-1 (cos f24-2)))))) - (set! (-> obj particles 28 init-pos y) (the float (+ s4-3 (the int (* f28-1 (sin f24-2)))))) - ) - (let ((f24-4 (* 182.04445 (- (/ -6.0 f26-3) (the float (adjust-pos s2-5 15)))))) - (set! (-> obj particles 29 init-pos x) (the float (+ s3-4 (the int (* f28-1 (cos f24-4)))))) - (set! (-> obj particles 29 init-pos y) (the float (+ s4-3 (the int (* f28-1 (sin f24-4)))))) - ) - (let ((f26-5 (* 182.04445 (- (/ 9.0 f26-3) (the float (adjust-pos s2-5 20)))))) - (set! (-> obj particles 30 init-pos x) (the float (+ s3-4 (the int (* f28-1 (cos f26-5)))))) - (set! (-> obj particles 30 init-pos y) (the float (+ s4-3 (the int (* f28-1 (sin f26-5)))))) - ) - ) - (when *cheat-mode* - (let ((a0-46 "AUTO SAVE OFF")) - (if (-> *setting-control* current auto-save) - (set! a0-46 "AUTO SAVE ON") - ) - (let* ((s3-5 (-> *display* frames (-> *display* on-screen) frame global-buf)) - (s4-4 (-> s3-5 base)) - ) - (draw-string-xy - a0-46 - s3-5 - (the int (+ 430.0 f30-0)) - 200 - (font-color blue-white) - (font-flags shadow kerning middle) - ) - (let ((a3-9 (-> s3-5 base))) - (let ((v1-81 (the-as object (-> s3-5 base)))) - (set! (-> (the-as dma-packet v1-81) dma) (new 'static 'dma-tag :id (dma-tag-id next))) - (set! (-> (the-as dma-packet v1-81) vif0) (new 'static 'vif-tag)) - (set! (-> (the-as dma-packet v1-81) vif1) (new 'static 'vif-tag)) - (set! (-> s3-5 base) (&+ (the-as pointer v1-81) 16)) - ) - (dma-bucket-insert-tag - (-> *display* frames (-> *display* on-screen) frame bucket-group) - (bucket-id debug-draw0) - s4-4 - (the-as (pointer dma-tag) a3-9) - ) - ) - ) - ) - ) - (let ((a0-52 (-> obj icons 5 icon 0 root))) - (set-yaw-angle-clear-roll-pitch! - a0-52 - (- (y-angle a0-52) (* 182.04445 (* 4.0 (-> *display* time-adjust-ratio)))) - ) - ) - (let* ((f28-2 (* 0.00024414062 (the float (-> *progress-process* 0 in-out-position)))) - (f30-1 (* 300.0 f28-2)) - ) - (set! (-> obj particles 18 init-pos x) - (the float (+ (the int (the float (adjust-pos s5-0 50))) 394 (the int f30-1) (-> obj right-x-offset))) - ) - (set! (-> obj particles 18 init-pos y) (the float (- 40 (the int (* 80.0 f28-2))))) - (set! (-> obj icons 5 icon-x) - (+ (the int (the float (adjust-pos s5-0 50))) 393 (the int f30-1) (-> obj right-x-offset)) - ) - (set! (-> obj icons 5 icon-y) (- (-> obj small-orb-y-offset) (the int (* 80.0 f28-2)))) - (set! (-> obj particles 16 init-pos x) - (the float (+ (the int (the float (adjust-pos s5-0 100))) 425 (the int f30-1) (-> obj right-x-offset))) - ) - (set! (-> obj particles 16 init-pos y) (the float (- 112 (the int (* 60.0 f28-2))))) - (set! (-> obj particles 17 init-pos x) (the float (+ (the int (the float (adjust-pos s5-0 150))) - 442 - (the int f30-1) - (the int (* 0.7 (the float (-> obj right-x-offset)))) - ) - ) - ) - ) - ) - (set! (-> obj particles 17 init-pos y) 193.0) - 0 - (none) - ) - - - - diff --git a/goal_src/pc/engine/ui/progress/progress-static.gc b/goal_src/pc/engine/ui/progress/progress-static.gc deleted file mode 100644 index e08952ce54..0000000000 --- a/goal_src/pc/engine/ui/progress/progress-static.gc +++ /dev/null @@ -1,1498 +0,0 @@ -;;-*-Lisp-*- -(in-package goal) - -;; name: progress-static.gc -;; name in dgo: progress-static -;; dgos: GAME, ENGINE - -;; This file contains the layouts for all of the menus. - -;; options in the start menu options -(define *main-options* - (new 'static 'boxed-array :type game-option :length 7 :allocated-length 7 - (new 'static 'game-option :option-type #x6 :name (game-text-id game-options) :scale #t :param3 4) - (new 'static 'game-option :option-type #x6 :name (game-text-id graphic-options) :scale #t :param3 5) - (new 'static 'game-option :option-type #x6 :name (game-text-id sound-options) :scale #t :param3 6) - (new 'static 'game-option :option-type #x6 :name (game-text-id load-game) :scale #t :param3 16) - (new 'static 'game-option :option-type #x6 :name (game-text-id save-game) :scale #t :param3 17) - (new 'static 'game-option :option-type #x6 :name (game-text-id quit-game) :scale #t :param3 34) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) - ) - -(define *title* - (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :option-type #x6 :name (game-text-id new-game) :scale #t :param3 18) - (new 'static 'game-option :option-type #x6 :name (game-text-id load-game) :scale #t :param3 16) - (new 'static 'game-option :option-type #x6 :name (game-text-id options) :scale #t :param3 28) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) - ) - -(define *options* - (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :option-type #x6 :name (game-text-id game-options) :scale #t :param3 4) - (new 'static 'game-option :option-type #x6 :name (game-text-id graphic-options) :scale #t :param3 5) - (new 'static 'game-option :option-type #x6 :name (game-text-id sound-options) :scale #t :param3 6) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) - ) - -(define *main-options-demo* - (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :option-type #x6 :name (game-text-id game-options) :scale #t :param3 4) - (new 'static 'game-option :option-type #x6 :name (game-text-id graphic-options) :scale #t :param3 5) - (new 'static 'game-option :option-type #x6 :name (game-text-id sound-options) :scale #t :param3 6) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) - ) - -;; param3 corresponds to the index defined in `*options-remap*` in progress.gc -;; it is the screen it should go to next, it's only used for type `6` - -(define *main-options-demo-shared* - (new 'static 'boxed-array :type game-option :length 5 :allocated-length 5 - (new 'static 'game-option :option-type #x6 :name (game-text-id game-options) :scale #t :param3 4) - (new 'static 'game-option :option-type #x6 :name (game-text-id graphic-options) :scale #t :param3 5) - (new 'static 'game-option :option-type #x6 :name (game-text-id sound-options) :scale #t :param3 6) - (new 'static 'game-option :option-type #x8 :name (game-text-id exit-demo) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) - ) - -;; TODO - option type should be an enum -;; 1 - a list? (only used by language so there might be some bad assumptions here...) -;; 2 - boolean -;; 3 - dpad input (center screen) -;; 4 - used for aspect ratio, also a list -;; 6 - go forward a screen -;; 8 - go back a screen -;; --- -;; 10 - port aspect ratio -;; 11 - port resolution -;; 12 - port window type -;; 13 - port subtitle language -;; 14 - port subtitle speaker -;; 15 - original aspect ratio - -(define *game-options* - (new 'static 'boxed-array :type game-option :length 5 :allocated-length 5 - (new 'static 'game-option :option-type #x2 :name (game-text-id vibrations) :scale #t) - (new 'static 'game-option :option-type #x2 :name (game-text-id play-hints) :scale #t) - (new 'static 'game-option :option-type #x6 :name (game-text-id progress-language-options) :scale #t :param3 35) - (new 'static 'game-option :option-type #x2 :name (game-text-id progress-discord-rpc) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) - ) - -(define *game-options-japan* - (new 'static 'boxed-array :type game-option :length 5 :allocated-length 5 - (new 'static 'game-option :option-type #x2 :name (game-text-id vibrations) :scale #t) - (new 'static 'game-option :option-type #x2 :name (game-text-id play-hints) :scale #t) - (new 'static 'game-option :option-type #x1 :name (game-text-id progress-language-options) :scale #t :param3 35) - (new 'static 'game-option :option-type #x2 :name (game-text-id progress-discord-rpc) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) - ) - -(define *game-options-demo* - (new 'static 'boxed-array :type game-option :length 5 :allocated-length 5 - (new 'static 'game-option :option-type #x2 :name (game-text-id vibrations) :scale #t) - (new 'static 'game-option :option-type #x2 :name (game-text-id play-hints) :scale #t) - (new 'static 'game-option :option-type #x1 :name (game-text-id progress-language-options) :scale #t :param3 35) - (new 'static 'game-option :option-type #x2 :name (game-text-id progress-discord-rpc) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) - ) - -(define *language-options* - (new 'static 'boxed-array :type game-option :length 5 :allocated-length 5 - (new 'static 'game-option :option-type #x1 :name (game-text-id language) :scale #t) - (new 'static 'game-option :option-type #x2 :name (game-text-id progress-subtitles) :scale #t) - (new 'static 'game-option :option-type #x13 :name (game-text-id progress-subtitles-language) :scale #t) - (new 'static 'game-option :option-type #x14 :name (game-text-id progress-subtitles-label-speaker) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - )) - -(define *graphic-options* - (new 'static 'boxed-array :type game-option :length 6 - (new 'static 'game-option :option-type #x15 :name (game-text-id progress-use-original-aspect) :scale #t) - (new 'static 'game-option :option-type #x12 :name (game-text-id progress-display-mode) :scale #t) - (new 'static 'game-option :option-type #x10 :name (game-text-id aspect-ratio) :scale #t) - (new 'static 'game-option :option-type #x11 :name (game-text-id progress-resolution) :scale #t) - (new 'static 'game-option :option-type #x2 :name (game-text-id progress-letterbox) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) - ) - -(define *graphic-title-options-pal* - (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :option-type #x3 :name (game-text-id center-screen) :scale #t) - (new 'static 'game-option :option-type #x5 :name (game-text-id video-mode) :scale #t) - (new 'static 'game-option :option-type #x4 :name (game-text-id aspect-ratio) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) - ) - -(define *sound-options* - (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :name (game-text-id sfx-volume) :scale #t :param2 100.0) - (new 'static 'game-option :name (game-text-id music-volume) :scale #t :param2 100.0) - (new 'static 'game-option :name (game-text-id speech-volume) :scale #t :param2 100.0) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) - ) - -(define *yes-no-options* - (new 'static 'boxed-array :type game-option :length 1 :allocated-length 1 - (new 'static 'game-option :option-type #x7 :scale #f) - ) - ) - -(define *ok-options* - (new 'static 'boxed-array :type game-option :length 1 :allocated-length 1 - (new 'static 'game-option :option-type #x8 :name (game-text-id ok) :scale #f) - ) - ) - -(define *load-options* - (new 'static 'boxed-array - :type game-option :length 5 :allocated-length 5 - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #f) - ) - ) - -(define *save-options* - (new 'static 'boxed-array :type game-option :length 5 :allocated-length 5 - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #f) - ) - ) - -(define *save-options-title* - (new 'static 'boxed-array - :type game-option :length 6 :allocated-length 6 - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :name (game-text-id continue-without-saving) :scale #f) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #f) - ) - ) - -;; maps options to a progress screen -(define *options-remap* - (new 'static 'boxed-array :type (array game-option) :length 0 :allocated-length 36) - ) - -;; TODO probably an enum. -;; maps "levels" to the appropriate offset in *level-task-data* -(define *level-task-data-remap* - (new 'static 'boxed-array :type int32 :length 23 :allocated-length 23 - 0 - 1 - 2 - 3 ;; jungle? - 3 ;; jungleb? - 4 - 5 - 6 - 7 ;; sunken? - 7 ;; sunkenb? - 8 - 9 - 10 - 11 - 12 - 13 ;; maincave? - 13 ;; robocave? - 13 ;; darkcave? - 14 - 15 ;; citadel? - 15 ;; finalboss? - 4 ;; demo? - 4 ;; intro? - ) - ) - -;; maps goal language ID to its name string ID -(define *language-name-remap* - (new 'static 'boxed-array :type game-text-id :length 6 :allocated-length 6 - (game-text-id english) - (game-text-id french) - (game-text-id german) - (game-text-id spanish) - (game-text-id italian) - (game-text-id japanese) - ) - ) - -(define *pc-subtitle-language-name-remap* - (new 'static 'boxed-array :type game-text-id :length 14 :allocated-length 14 - (game-text-id english) - (game-text-id french) - (game-text-id german) - (game-text-id spanish) - (game-text-id italian) - (game-text-id japanese) - (game-text-id progress-subtitle-language-uk-english) - (game-text-id progress-subtitle-language-portuguese) - (game-text-id progress-subtitle-language-finnish) - (game-text-id progress-subtitle-language-swedish) - (game-text-id progress-subtitle-language-danish) - (game-text-id progress-subtitle-language-norwegian) - (game-text-id progress-subtitle-language-korean) - (game-text-id progress-subtitle-language-russian))) - -(define *pc-subtitle-speaker-setting-remap* - (new 'static 'boxed-array :type game-text-id :length 3 :allocated-length 3 - (game-text-id progress-subtitles-label-speaker-on) - (game-text-id progress-subtitles-label-speaker-off) - (game-text-id progress-subtitles-label-speaker-auto))) - -(define *pc-graphics-display-mode-remap* - (new 'static 'boxed-array :type game-text-id :length 3 :allocated-length 3 - (game-text-id progress-display-mode-borderless) - (game-text-id progress-display-mode-fullscreen) - (game-text-id progress-display-mode-windowed))) - -(define *pc-graphics-original-aspect-ratio-mode-remap* - (new 'static 'boxed-array :type game-text-id :length 2 :allocated-length 2 - (game-text-id progress-aspect-ratio-4x3) - (game-text-id progress-aspect-ratio-16x9))) - -(define *pc-graphics-aspect-ratio-mode-remap* - (new 'static 'boxed-array :type game-text-id :length 5 :allocated-length 5 - (game-text-id progress-aspect-ratio-4x3) - (game-text-id progress-aspect-ratio-5x4) - (game-text-id progress-aspect-ratio-16x9) - (game-text-id progress-aspect-ratio-21x9) - (game-text-id progress-aspect-ratio-32x9))) - -(define *pc-graphics-4x3-valid-resolutions-names* - (new 'static 'boxed-array :type game-text-id :length 5 :allocated-length 5 - (game-text-id progress-res-4x3-640x480) - (game-text-id progress-res-4x3-800x600) - (game-text-id progress-res-4x3-1024x768) - (game-text-id progress-res-4x3-1280x960) - (game-text-id progress-res-4x3-1600x1200))) - -(define *pc-graphics-5x4-valid-resolutions-names* - (new 'static 'boxed-array :type game-text-id :length 3 :allocated-length 3 - (game-text-id progress-res-5x4-960x768) - (game-text-id progress-res-5x4-1280x1024) - (game-text-id progress-res-5x4-1500x1200))) - -(define *pc-graphics-16x9-valid-resolutions-names* - (new 'static 'boxed-array :type game-text-id :length 7 :allocated-length 7 - (game-text-id progress-res-16x9-854x480) - (game-text-id progress-res-16x9-1280x720) - (game-text-id progress-res-16x9-1920x1080) - (game-text-id progress-res-16x9-2560x1440) - (game-text-id progress-res-16x9-2880x1620) - (game-text-id progress-res-16x9-3840x2160) - (game-text-id progress-res-16x9-5120x2880))) - -(define *pc-graphics-21x9-valid-resolutions-names* - (new 'static 'boxed-array :type game-text-id :length 6 :allocated-length 6 - (game-text-id progress-res-21x9-2560x1080) - (game-text-id progress-res-21x9-3120x1440) - (game-text-id progress-res-21x9-3200x1440) - (game-text-id progress-res-21x9-3440x1440) - (game-text-id progress-res-21x9-3840x1600) - (game-text-id progress-res-21x9-5120x2160))) - -(define *pc-graphics-32x9-valid-resolutions-names* - (new 'static 'boxed-array :type game-text-id :length 1 :allocated-length 1 - (game-text-id progress-res-32x9-5120x1440))) - -;; all level tasks -(define *level-task-data* - (new 'static 'boxed-array :type level-tasks-info :length 16 :allocated-length 16 - (new 'static 'level-tasks-info - :level-name-id (game-text-id training-level-name) - :text-group-index 1 - :nb-of-tasks 4 - :buzzer-task-index 3 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task training-gimmie) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id training-gimmie-task-name) - (game-text-id training-gimmie-task-name) - (game-text-id training-gimmie-task-name) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task training-door) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id training-door-task-name) - (game-text-id training-door-task-name) - (game-text-id training-door-task-name) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task training-climb) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id training-climb-task-name) - (game-text-id training-climb-task-name) - (game-text-id training-climb-task-name) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task training-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id training-buzzer-task-name) - (game-text-id training-buzzer-task-name) - (game-text-id training-buzzer-task-name) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id village1-level-name) - :text-group-index 1 - :nb-of-tasks 6 - :buzzer-task-index 5 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task village1-mayor-money) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village1-mayor-money) - (game-text-id village1-mayor-money) - (game-text-id village1-mayor-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village1-uncle-money) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id vollage1-uncle-money) - (game-text-id vollage1-uncle-money) - (game-text-id vollage1-uncle-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village1-yakow) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village1-yakow-herd) - (game-text-id village1-yakow-herd) - (game-text-id village1-yakow-return) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village1-oracle-money1) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village1-oracle) - (game-text-id village1-oracle) - (game-text-id village1-oracle) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village1-oracle-money2) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village1-oracle) - (game-text-id village1-oracle) - (game-text-id village1-oracle) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village1-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id beach-level-name) - :text-group-index 1 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task beach-ecorocks) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-ecorocks) - (game-text-id beach-ecorocks) - (game-text-id beach-ecorocks) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task beach-flutflut) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-flutflut-push) - (game-text-id beach-flutflut-push) - (game-text-id beach-flutflut-meet) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task beach-pelican) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-pelican) - (game-text-id beach-pelican) - (game-text-id beach-pelican) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task beach-seagull) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-seagull) - (game-text-id beach-seagull) - (game-text-id beach-seagull-get) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task beach-cannon) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-cannon) - (game-text-id beach-cannon) - (game-text-id beach-cannon) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task beach-gimmie) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-gimmie) - (game-text-id beach-gimmie) - (game-text-id beach-gimmie) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task beach-sentinel) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-sentinel) - (game-text-id beach-sentinel) - (game-text-id beach-sentinel) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task beach-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id jungle-level-name) - :text-group-index 1 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task jungle-lurkerm) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id jungle-lurkerm-unblock) - (game-text-id jungle-lurkerm-connect) - (game-text-id jungle-lurkerm-return) - (game-text-id zero) - ) - :text-index-when-resolved 1 - ) - (new 'static 'task-info-data - :task-id (game-task jungle-tower) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id jungle-tower) - (game-text-id jungle-tower) - (game-text-id jungle-tower) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task jungle-eggtop) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id jungle-eggtop) - (game-text-id jungle-eggtop) - (game-text-id jungle-eggtop) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task jungle-plant) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id jungle-plant) - (game-text-id jungle-plant) - (game-text-id jungle-plant) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task jungle-fishgame) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id jungle-fishgame) - (game-text-id jungle-fishgame) - (game-text-id jungle-fishgame) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task jungle-canyon-end) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id jungle-canyon-end) - (game-text-id jungle-canyon-end) - (game-text-id jungle-canyon-end) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task jungle-temple-door) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id jungle-temple-door) - (game-text-id jungle-temple-door) - (game-text-id jungle-temple-door) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task jungle-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id misty-level-name) - :text-group-index 1 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task misty-muse) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id misty-muse-catch) - (game-text-id misty-muse-catch) - (game-text-id misty-muse-return) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task misty-boat) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id misty-boat) - (game-text-id misty-boat) - (game-text-id misty-boat) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task misty-cannon) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id misty-cannon) - (game-text-id misty-cannon) - (game-text-id misty-cannon) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task misty-warehouse) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id misty-return-to-pool) - (game-text-id misty-return-to-pool) - (game-text-id misty-return-to-pool) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task misty-bike) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id misty-find-transpad) - (game-text-id misty-balloon-lurkers) - (game-text-id misty-find-transpad) - (game-text-id zero) - ) - :text-index-when-resolved 1 - ) - (new 'static 'task-info-data - :task-id (game-task misty-bike-jump) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id misty-bike-jump) - (game-text-id misty-bike-jump) - (game-text-id misty-bike-jump) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task misty-eco-challenge) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id misty-eco-challenge) - (game-text-id misty-eco-challenge) - (game-text-id misty-eco-challenge) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task misty-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id fire-canyon-level-name) - :text-group-index 5 - :nb-of-tasks 2 - :buzzer-task-index 1 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task firecanyon-end) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id fire-canyon-end) - (game-text-id fire-canyon-end) - (game-text-id fire-canyon-end) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task firecanyon-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id fire-canyon-buzzer) - (game-text-id fire-canyon-buzzer) - (game-text-id fire-canyon-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id village2-level-name) - :text-group-index 2 - :nb-of-tasks 6 - :buzzer-task-index 5 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task village2-gambler-money) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village2-gambler-money) - (game-text-id village2-gambler-money) - (game-text-id village2-gambler-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village2-geologist-money) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village2-geologist-money) - (game-text-id village2-geologist-money) - (game-text-id village2-geologist-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village2-warrior-money) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village2-warrior-money) - (game-text-id village2-warrior-money) - (game-text-id village2-warrior-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village2-oracle-money1) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village2-oracle-money) - (game-text-id village2-oracle-money) - (game-text-id village2-oracle-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village2-oracle-money2) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village2-oracle-money) - (game-text-id village2-oracle-money) - (game-text-id village2-oracle-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village2-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id sunken-level-name) - :text-group-index 2 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task sunken-room) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id sunken-elevator-raise) - (game-text-id sunken-elevator-raise) - (game-text-id sunken-elevator-get-to-roof) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task sunken-pipe) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id sunken-pipe) - (game-text-id sunken-pipe) - (game-text-id sunken-pipe) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task sunken-slide) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id sunken-bottom) - (game-text-id sunken-bottom) - (game-text-id sunken-bottom) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task sunken-sharks) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id sunken-pool) - (game-text-id sunken-pool) - (game-text-id sunken-pool) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task sunken-platforms) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id sunken-platforms) - (game-text-id sunken-platforms) - (game-text-id sunken-platforms) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task sunken-top-of-helix) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id sunken-climb-tube) - (game-text-id sunken-climb-tube) - (game-text-id sunken-climb-tube) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task sunken-spinning-room) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id reach-center) - (game-text-id reach-center) - (game-text-id reach-center) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task sunken-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id swamp-level-name) - :text-group-index 2 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task swamp-flutflut) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id swamp-flutflut) - (game-text-id swamp-flutflut) - (game-text-id swamp-flutflut) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task swamp-billy) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id swamp-billy) - (game-text-id swamp-billy) - (game-text-id swamp-billy) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task swamp-battle) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id swamp-battle) - (game-text-id swamp-battle) - (game-text-id swamp-battle) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task swamp-tether-4) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task swamp-tether-1) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task swamp-tether-2) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task swamp-tether-3) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task swamp-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id rolling-level-name) - :text-group-index 2 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task rolling-moles) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id rolling-moles) - (game-text-id rolling-moles) - (game-text-id rolling-moles-return) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task rolling-robbers) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id rolling-robbers) - (game-text-id rolling-robbers) - (game-text-id rolling-robbers) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task rolling-race) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id rolling-race) - (game-text-id rolling-race) - (game-text-id rolling-race-return) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task rolling-lake) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id rolling-lake) - (game-text-id rolling-lake) - (game-text-id rolling-lake) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task rolling-plants) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id rolling-plants) - (game-text-id rolling-plants) - (game-text-id rolling-plants) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task rolling-ring-chase-1) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id rolling-ring-chase-1) - (game-text-id rolling-ring-chase-1) - (game-text-id rolling-ring-chase-1) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task rolling-ring-chase-2) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id rolling-ring-chase-2) - (game-text-id rolling-ring-chase-2) - (game-text-id rolling-ring-chase-2) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task rolling-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id ogre-level-name) - :text-group-index 6 - :nb-of-tasks 4 - :buzzer-task-index 3 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task ogre-boss) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id ogre-boss) - (game-text-id ogre-boss) - (game-text-id ogre-boss) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task ogre-end) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id ogre-end) - (game-text-id ogre-end) - (game-text-id ogre-end) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task ogre-secret) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id hidden-power-cell) - (game-text-id hidden-power-cell) - (game-text-id hidden-power-cell) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task ogre-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id ogre-buzzer) - (game-text-id ogre-buzzer) - (game-text-id ogre-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id village3-level-name) - :text-group-index 3 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task village3-miner-money1) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village3-miner-money2) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village3-miner-money3) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village3-miner-money4) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village3-oracle-money1) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-oracle-money) - (game-text-id village3-oracle-money) - (game-text-id village3-oracle-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village3-oracle-money2) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-oracle-money) - (game-text-id village3-oracle-money) - (game-text-id village3-oracle-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village3-extra1) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id hidden-power-cell) - (game-text-id hidden-power-cell) - (game-text-id hidden-power-cell) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village3-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-buzzer) - (game-text-id village3-buzzer) - (game-text-id village3-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id snowy-level-name) - :text-group-index 3 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task snow-eggtop) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id snow-eggtop) - (game-text-id snow-eggtop) - (game-text-id snow-eggtop) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task snow-ram) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id snow-ram-3-left) - (game-text-id snow-ram-2-left) - (game-text-id snow-ram-1-left) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task snow-bumpers) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id snow-bumpers) - (game-text-id snow-bumpers) - (game-text-id snow-bumpers) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task snow-cage) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id snow-frozen-crate) - (game-text-id snow-frozen-crate) - (game-text-id snow-frozen-crate) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task snow-fort) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id snow-fort) - (game-text-id snow-fort) - (game-text-id snow-fort) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task snow-ball) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id snow-open-door) - (game-text-id snow-open-door) - (game-text-id snow-open-door) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task snow-bunnies) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id snow-bunnies) - (game-text-id snow-bunnies) - (game-text-id snow-bunnies) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task snow-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-buzzer) - (game-text-id village3-buzzer) - (game-text-id village3-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id cave-level-name) - :text-group-index 3 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task cave-gnawers) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id cave-gnawers) - (game-text-id cave-gnawers) - (game-text-id cave-gnawers) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task cave-dark-crystals) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id cave-dark-crystals) - (game-text-id cave-dark-crystals) - (game-text-id cave-dark-crystals) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task cave-dark-climb) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id cave-dark-climb) - (game-text-id cave-dark-climb) - (game-text-id cave-dark-climb) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task cave-robot-climb) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id cave-robot-climb) - (game-text-id cave-robot-climb) - (game-text-id cave-robot-climb) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task cave-swing-poles) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id cave-swing-poles) - (game-text-id cave-swing-poles) - (game-text-id cave-swing-poles) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task cave-spider-tunnel) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id cave-spider-tunnel) - (game-text-id cave-spider-tunnel) - (game-text-id cave-spider-tunnel) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task cave-platforms) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id cave-platforms) - (game-text-id cave-platforms) - (game-text-id cave-platforms) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task cave-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-buzzer) - (game-text-id village3-buzzer) - (game-text-id village3-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id lavatube-level-name) - :text-group-index 3 - :nb-of-tasks 2 - :buzzer-task-index 1 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task lavatube-end) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id lavatube-end) - (game-text-id lavatube-end) - (game-text-id lavatube-end) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task lavatube-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id lavatube-buzzer) - (game-text-id lavatube-buzzer) - (game-text-id lavatube-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id citadel-level-name) - :text-group-index 4 - :nb-of-tasks 5 - :buzzer-task-index 4 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task citadel-sage-blue) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id citadel-sage-blue) - (game-text-id citadel-sage-blue) - (game-text-id citadel-sage-blue) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task citadel-sage-red) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id citadel-sage-red) - (game-text-id citadel-sage-red) - (game-text-id citadel-sage-red) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task citadel-sage-yellow) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id citadel-sage-yellow) - (game-text-id citadel-sage-yellow) - (game-text-id citadel-sage-yellow) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task citadel-sage-green) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id citadel-sage-green) - (game-text-id citadel-sage-green) - (game-text-id citadel-sage-green) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task citadel-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id citadel-buzzer) - (game-text-id citadel-buzzer) - (game-text-id citadel-buzzer) - (game-text-id zero) - ) - ) - ) - ) - ) - ) - -;; goes down by 24 or 23 every time -(define *task-egg-starting-x* - (new 'static 'boxed-array :type int32 :length 9 :allocated-length 9 - 218 - 194 - 171 - 147 - 124 - 100 - 77 - 53 - 30 - ) - ) - -(define *game-counts* (the-as game-count-info #f)) - - - - diff --git a/goal_src/pc/engine/ui/progress/progress.gc b/goal_src/pc/engine/ui/progress/progress.gc deleted file mode 100644 index 1fd0ac0f71..0000000000 --- a/goal_src/pc/engine/ui/progress/progress.gc +++ /dev/null @@ -1,2762 +0,0 @@ -;;-*-Lisp-*- -(in-package goal) - -;; name: progress.gc -;; name in dgo: progress -;; dgos: GAME, ENGINE - -;; DECOMP BEGINS - -(deftype progress-global-state (basic) - ((aspect-ratio-choice symbol :offset-assert 4) - (video-mode-choice symbol :offset-assert 8) - (yes-no-choice symbol :offset-assert 12) - (which int32 :offset-assert 16) - (starting-state progress-screen :offset-assert 24) - (last-slot-saved int32 :offset-assert 32) - (slider-backup float :offset-assert 36) - (language-backup int64 :offset-assert 40) - (on-off-backup symbol :offset-assert 48) - (center-x-backup int32 :offset-assert 52) - (center-y-backup int32 :offset-assert 56) - (aspect-ratio-backup symbol :offset-assert 60) - (last-slider-sound time-frame :offset-assert 64) - ) - :method-count-assert 9 - :size-assert #x48 - :flag-assert #x900000048 - ) - -(define *progress-state* - (new 'static 'progress-global-state - :yes-no-choice #f - :which -1 - :last-slot-saved -1 - ) - ) - - -(defun get-game-count ((arg0 int)) - (-> *game-counts* data arg0) - ) - -(defun progress-allowed? () - (not (or (-> *setting-control* current talking) - (-> *setting-control* current movie) - (movie?) - (handle->process (-> *game-info* pov-camera-handle)) - (handle->process (-> *game-info* other-camera-handle)) - (< (-> *display* base-frame-counter) (-> *game-info* letterbox-time)) - (< (-> *display* base-frame-counter) (-> *game-info* blackout-time)) - (!= (-> *setting-control* current bg-a) 0.0) - (!= (-> *setting-control* current bg-a-force) 0.0) - (not (-> *setting-control* current allow-progress)) - (or (and (handle->process (-> *game-info* auto-save-proc)) - (not (send-event (handle->process (-> *game-info* auto-save-proc)) 'progress-allowed?)) - ) - (not *target*) - ) - ) - ) - ) - -(defun pause-allowed? () - (not (or (< (-> *display* base-frame-counter) (-> *game-info* blackout-time)) - (!= (-> *setting-control* current bg-a) 0.0) - (!= (-> *setting-control* current bg-a-force) 0.0) - (not (-> *setting-control* current allow-pause)) - (handle->process (-> *game-info* auto-save-proc)) - (not *target*) - ) - ) - ) - -(defun init-game-options ((obj progress)) - "Set the options for all of the menus." - - ;; start off by making them all invalid - (dotimes (i (-> *options-remap* allocated-length)) - (set! (-> *options-remap* i) #f) - ) - - ;; main menu - (set! (-> *options-remap* 3) - (case *kernel-boot-message* - (('demo) - ;; game demo - *main-options-demo* - ) - (('demo-shared) - ;; game demo with external launcher - *main-options-demo-shared* - ) - (else - ;; normal game - *main-options* - ) - ) - ) - (set! (-> *options-remap* 4) - (cond - ((!= *kernel-boot-message* 'play) - (if (= (scf-get-territory) GAME_TERRITORY_SCEE) - *game-options* - *game-options-demo* - ) - ) - ((and (= (scf-get-territory) GAME_TERRITORY_SCEI) - (not (and (= *progress-cheat* 'language) (cpad-hold? 0 l2) (cpad-hold? 0 r2)))) - ;; if ntsc-j and we're not using language cheat (needs l2+r2) - *game-options-japan* - ) - (else - *game-options* - ) - ) - ) - (set! (-> *options-remap* 5) - (if (and (= (-> *progress-state* starting-state) 27) - (or (= (scf-get-territory) GAME_TERRITORY_SCEE) - (and (= *progress-cheat* 'pal) - (logtest? (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons l2)) - (logtest? (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons r2)) - ) - ) - ) - ;; (only if we came from title) if PAL or we're using the PAL cheat (needs l2+r2) - *graphic-title-options-pal* - *graphic-options* - ) - ) - (set! (-> *options-remap* 6) *sound-options*) - (set! (-> *options-remap* 7) *ok-options*) - (set! (-> *options-remap* 8) *ok-options*) - (set! (-> *options-remap* 9) *ok-options*) - (set! (-> *options-remap* 10) *yes-no-options*) - (set! (-> *options-remap* 11) *yes-no-options*) - (set! (-> *options-remap* 19) *ok-options*) - (set! (-> *options-remap* 16) *load-options*) - (set! (-> *options-remap* 17) *save-options*) - (set! (-> *options-remap* 18) *save-options-title*) - (set! (-> *options-remap* 20) *ok-options*) - (set! (-> *options-remap* 21) *ok-options*) - (set! (-> *options-remap* 24) *ok-options*) - (set! (-> *options-remap* 25) *ok-options*) - (set! (-> *options-remap* 26) *ok-options*) - (set! (-> *options-remap* 22) *ok-options*) - (set! (-> *options-remap* 23) *yes-no-options*) - (set! (-> *options-remap* 27) *title*) - (set! (-> *options-remap* 28) *options*) - (set! (-> *options-remap* 29) *ok-options*) - (set! (-> *options-remap* 30) *yes-no-options*) - (set! (-> *options-remap* 31) *yes-no-options*) - (set! (-> *options-remap* 32) *ok-options*) - (set! (-> *options-remap* 33) *ok-options*) - (set! (-> *options-remap* 34) *yes-no-options*) - (set! (-> *progress-state* video-mode-choice) (get-video-mode)) - (set! (-> *progress-state* yes-no-choice) #f) - (set! (-> *game-options* 0 value-to-modify) (&-> *setting-control* default vibration)) - (set! (-> *game-options* 1 value-to-modify) (&-> *setting-control* default play-hints)) - (set! (-> *game-options-japan* 0 value-to-modify) (&-> *setting-control* default vibration)) - (set! (-> *game-options-japan* 1 value-to-modify) (&-> *setting-control* default play-hints)) - (set! (-> *game-options-demo* 0 value-to-modify) (&-> *setting-control* default vibration)) - (set! (-> *game-options-demo* 1 value-to-modify) (&-> *setting-control* default play-hints)) - (set! (-> *graphic-title-options-pal* 1 value-to-modify) (&-> *progress-state* video-mode-choice)) - (set! (-> *graphic-title-options-pal* 2 value-to-modify) (&-> *progress-state* aspect-ratio-choice)) - (set! (-> *sound-options* 0 value-to-modify) (&-> *setting-control* default sfx-volume)) - (set! (-> *sound-options* 1 value-to-modify) (&-> *setting-control* default music-volume)) - (set! (-> *sound-options* 2 value-to-modify) (&-> *setting-control* default dialog-volume)) - (set! (-> *yes-no-options* 0 value-to-modify) (&-> *progress-state* yes-no-choice)) - - ;; new stuff - (set! (-> *options-remap* 35) *language-options*) - (set! (-> *game-options* 3 value-to-modify) (&-> *pc-settings* discord-rpc?)) - (set! (-> *language-options* 0 value-to-modify) (&-> *setting-control* default language)) - (set! (-> *language-options* 1 value-to-modify) (&-> *pc-settings* subtitles?)) - (set! (-> *language-options* 2 value-to-modify) (&-> *pc-settings* subtitle-language)) - (set! (-> *language-options* 3 value-to-modify) (&-> *pc-settings* subtitle-speaker?)) ;; TODO - refactor this like i did with display-mode - (set! (-> *graphic-options* 0 value-to-modify) (&-> *progress-state* aspect-ratio-choice)) - (set! (-> *graphic-options* 1 value-to-modify) (&-> *pc-settings* display-mode)) - (set! (-> *graphic-options* 2 value-to-modify) (&-> *pc-settings* aspect-ratio-mode)) - (set! (-> *graphic-options* 3 value-to-modify) (&-> *pc-settings* resolution)) - (set! (-> *graphic-options* 4 value-to-modify) (&-> *pc-settings* letterbox?)) - - (none) - ) - -(defun make-current-level-available-to-progress () - "exactly what it says on the tin." - - (when (and *target* (-> *level* border?)) - (let* ((cur-lev (-> *target* current-level)) - (lev-idx (+ (-> cur-lev info index) -1)) - ) - (if (and (>= lev-idx 0) - (< lev-idx (-> *level-task-data-remap* length)) - (zero? (-> *game-info* level-opened (-> *level-task-data-remap* lev-idx))) - (or (= *kernel-boot-message* 'play) (= (-> cur-lev nickname) 'mis)) - ) - (set! (-> *game-info* level-opened (-> *level-task-data-remap* lev-idx)) (the-as uint 1)) - ) - ) - ) - 0 - (none) - ) - -(defun make-levels-with-tasks-available-to-progress () - "Open levels that have tasks to do!" - - ;; go through EVERY LEVEL'S TASKS - (dotimes (i (length *level-task-data*)) - ;; level tasks - (let ((tasks (-> *level-task-data* i))) - ;; unless there's no tasks or the level is already open... - (unless (or (= tasks #f) (= (-> *game-info* level-opened i) 1)) - (cond - ((!= *kernel-boot-message* 'play) - (if (= (-> tasks level-name-id) (game-text-id misty-level-name)) - (set! (-> *game-info* level-opened i) (the-as uint 1)) - ) - ) - (*cheat-mode* - (set! (-> *game-info* level-opened i) (the-as uint 1)) - ) - (else - (dotimes (ii (-> tasks nb-of-tasks)) - (if (and (zero? (-> *game-info* level-opened ii)) - (!= ii (-> tasks buzzer-task-index)) - (task-known? (-> tasks task-info ii task-id)) - ) - (set! (-> *game-info* level-opened ii) (the-as uint 1)) - ) - ) - ) - ) - ) - ) - ) - 0 - (none) - ) - -(defun get-next-task-up ((cur-task-idx int) (lev-idx int)) - "find next available task. skips over unknown tasks and doesn't do anything if none are found" - - (let ((gp-0 cur-task-idx)) - (let ((s4-0 (+ cur-task-idx 1)) - (s3-0 (-> *level-task-data* lev-idx)) - ) - (while (and (< s4-0 (-> s3-0 nb-of-tasks)) (= gp-0 cur-task-idx)) - (if (or *cheat-mode* (task-known? (-> s3-0 task-info s4-0 task-id))) - (set! gp-0 s4-0) - ) - (+! s4-0 1) - ) - ) - gp-0 - ) - ) - -(defun get-next-task-down ((cur-task-idx int) (lev-idx int)) - "find previous available task. skips over unknown tasks and doesn't do anything if none are found" - - (let ((gp-0 cur-task-idx)) - (let ((s4-0 (+ cur-task-idx -1)) - (s3-0 (-> *level-task-data* lev-idx)) - ) - (while (and (>= s4-0 0) (= gp-0 cur-task-idx)) - (if (or *cheat-mode* (task-known? (-> s3-0 task-info s4-0 task-id))) - (set! gp-0 s4-0) - ) - (+! s4-0 -1) - ) - ) - gp-0 - ) - ) - -(defun get-next-level-up ((lev-idx int)) - (let ((gp-0 lev-idx)) - (let ((s4-0 (+ lev-idx 1))) - (while (and (< s4-0 (length *level-task-data*)) (= gp-0 lev-idx)) - (if (= (-> *game-info* level-opened s4-0) 1) - (set! gp-0 s4-0) - ) - (+! s4-0 1) - ) - ) - gp-0 - ) - ) - -(defun get-next-level-down ((lev-idx int)) - (let ((v0-0 lev-idx)) - (let ((v1-0 (+ lev-idx -1))) - (while (and (>= v1-0 0) (= v0-0 lev-idx)) - (if (= (-> *game-info* level-opened v1-0) 1) - (set! v0-0 v1-0) - ) - (+! v1-0 -1) - ) - ) - v0-0 - ) - ) - -(defun calculate-completion ((the-progress progress)) - "Updates counters and calculates game completion. - Cells are tallied 80% - Buzzers are tallied 10% - Orbs are tallied 10%" - - (local-vars - (current-cells int) - (current-buzzers int) - (current-orbs int) - (total-cells int) - (total-buzzers int) - (total-orbs int) - ) - (set! current-cells 0) - (set! current-buzzers 0) - (set! current-orbs 0) - (set! total-cells 0) - (set! total-buzzers 0) - (set! total-orbs 0) - (dotimes (s5-0 (length *level-task-data*)) - (let ((s4-0 (-> *level-task-data* s5-0))) - (when (!= s4-0 #f) - (when (or (= *kernel-boot-message* 'play) (= (-> s4-0 level-name-id) (game-text-id misty-level-name))) - (dotimes (s3-0 (-> s4-0 nb-of-tasks)) - (if (= (get-task-status (-> s4-0 task-info s3-0 task-id)) (task-status invalid)) - (set! current-cells (+ current-cells 1)) - ) - ) - (set! total-cells (+ total-cells (-> s4-0 nb-of-tasks))) - (set! current-orbs (+ current-orbs (-> *game-info* money-per-level s5-0))) - (set! total-orbs (+ total-orbs (-> *game-counts* data s5-0 money-count))) - (let ((v1-20 (-> s4-0 buzzer-task-index))) - (when (!= v1-20 -1) - (set! current-buzzers (+ current-buzzers (buzzer-count *game-info* (-> s4-0 task-info v1-20 task-id)))) - (set! total-buzzers (+ total-buzzers (-> *game-counts* data s5-0 buzzer-count))) - ) - ) - ) - ) - ) - ) - (when the-progress - (set! (-> the-progress total-nb-of-power-cells) total-cells) - (set! (-> the-progress total-nb-of-buzzers) total-buzzers) - (set! (-> the-progress total-nb-of-orbs) total-orbs) - ) - (+ (/ (* 80.0 (the float current-cells)) (the float total-cells)) - (/ (* 10.0 (the float current-orbs)) (the float total-orbs)) - (/ (* 10.0 (the float current-buzzers)) (the float total-buzzers)) - ) - ) - -(define *progress-save-info* (new 'global 'mc-slot-info)) - -(defmacro progress-make-manipy-icon (obj &key skel - &key x - &key y - &key z - &key scale-x - &key scale-y - ) - `(when (< (-> ,obj nb-of-icons) 6) - (let ((icon-idx (-> ,obj nb-of-icons))) - (set! (-> ,obj icons icon-idx) (new 'static 'hud-icon)) - (let ((new-manipy (make-init-process manipy manipy-init (new 'static 'vector :w 1.0) #f ,skel #f - :to ,obj - :stack *scratch-memory-top* - ))) - (when new-manipy - (set! (-> (-> new-manipy) draw dma-add-func) dma-add-process-drawable-hud) - (set-vector! (-> (-> new-manipy) root trans) 0.0 0.0 0.0 1.0) - (set-vector! (-> (-> new-manipy) root scale) ,scale-x ,scale-y ,scale-x 1.0) - (when #f - (send-event (ppointer->process new-manipy) 'trans-hook #f) - ) - ) - (set! (-> ,obj icons icon-idx icon) new-manipy) - (when new-manipy - (logior! (-> new-manipy 0 mask) (process-mask pause)) - (logclear! (-> new-manipy 0 mask) (process-mask menu progress)) - (set! (-> (-> new-manipy) root trans z) ,z) - (set! (-> ,obj icons icon-idx icon-x) ,x) - (set! (-> ,obj icons icon-idx icon-y) ,y) - (set! (-> ,obj icons icon-idx icon-z) 0) - (set! (-> ,obj icons icon-idx scale-x) ,scale-x) - (set! (-> ,obj icons icon-idx scale-y) ,scale-y) - ) - ) - ) - (+! (-> ,obj nb-of-icons) 1) - ) - ) - -(defmethod initialize-icons progress ((obj progress)) - (progress-make-manipy-icon obj :skel *fuelcell-naked-sg* - :x 256 - :y 77 - :z (meters 0.5) - :scale-x 0.006 - :scale-y 0.006 - ) - (progress-make-manipy-icon obj :skel *fuelcell-naked-sg* - :x 256 - :y 77 - :z (meters 0.5) - :scale-x 0.006 - :scale-y 0.006 - ) - (progress-make-manipy-icon obj :skel *fuelcell-naked-sg* - :x 256 - :y 77 - :z (meters 0.5) - :scale-x 0.006 - :scale-y 0.006 - ) - (progress-make-manipy-icon obj :skel *fuelcell-naked-sg* - :x 256 - :y 77 - :z (meters 0.5) - :scale-x 0.006 - :scale-y 0.006 - ) - (progress-make-manipy-icon obj :skel *money-sg* - :x -320 - :y 253 - :z (meters 17) - :scale-x 0.013 - :scale-y -0.015 - ) - (progress-make-manipy-icon obj :skel *money-sg* - :x -320 - :y 253 - :z (meters 0.25) - :scale-x 0.008 - :scale-y -0.009 - ) - (send-event (ppointer->process (-> obj icons 1 icon)) 'set-frame-num 2.5) - (send-event (ppointer->process (-> obj icons 2 icon)) 'set-frame-num 10.0) - (send-event (ppointer->process (-> obj icons 3 icon)) 'set-frame-num 15.5) - 0 - (none) - ) - -(defmethod enter! progress ((obj progress) (screen progress-screen) (option int)) - (when (!= (-> obj display-state) screen) - (set! (-> *progress-state* yes-no-choice) #f) - (set! (-> obj selected-option) #f) - (set! (-> obj option-index) option) - (set! (-> obj last-option-index-change) (-> *display* real-frame-counter)) - (set! (-> obj display-state) screen) - (set! (-> obj next-display-state) screen) - (set-transition-speed! obj) - (case (-> obj display-state) - (((progress-screen memcard-creating)) - (auto-save-command 'create-file 0 0 obj) - ) - (((progress-screen memcard-loading)) - (set! (-> *progress-state* last-slot-saved) (-> *progress-state* which)) - (sound-volume-off) - (auto-save-command 'restore 0 (-> *progress-state* which) obj) - ) - (((progress-screen memcard-saving)) - (set! (-> *progress-state* last-slot-saved) (-> *progress-state* which)) - (auto-save-command 'save 0 (-> *progress-state* which) obj) - ) - (((progress-screen memcard-formatting)) - (auto-save-command 'format-card 0 0 obj) - ) - (((progress-screen save-game) (progress-screen load-game)) - (set! (-> obj option-index) (max 0 (-> *progress-state* last-slot-saved))) - ) - (((progress-screen memcard-removed)) - (set! (-> *progress-state* last-slot-saved) 0) - 0 - ) - ) - ) - 0 - (none) - ) - -(defmethod push! progress ((obj progress)) - (let ((v1-0 (-> obj display-state-pos))) - (cond - ((< v1-0 5) - (set! (-> obj display-state-stack v1-0) (-> obj display-state)) - (set! (-> obj option-index-stack v1-0) (-> obj option-index)) - (set! (-> obj display-state-pos) (+ v1-0 1)) - ) - (else - (format #t "ERROR: Can't push any more states on the display-state-stack.~%") - ) - ) - ) - 0 - (none) - ) - -(defmethod pop! progress ((obj progress)) - (let ((v1-0 (-> obj display-state-pos))) - (cond - ((> v1-0 0) - (let ((a2-0 (+ v1-0 -1))) - (set! (-> obj display-state-pos) a2-0) - (enter! obj (-> obj display-state-stack a2-0) (-> obj option-index-stack a2-0)) - ) - ) - (else - (set-master-mode 'game) - ) - ) - ) - 0 - (none) - ) - -(defmethod set-transition-progress! progress ((obj progress) (arg0 int)) - (set! (-> obj transition-offset) arg0) - (set! (-> obj transition-offset-invert) (- 512 arg0)) - (set! (-> obj transition-percentage) (* 0.001953125 (the float arg0))) - (set! (-> obj transition-percentage-invert) (- 1.0 (-> obj transition-percentage))) - 0 - (none) - ) - -(defmethod set-transition-speed! progress ((obj progress)) - (case (-> obj display-state) - (((progress-screen fuel-cell) - (progress-screen money) - (progress-screen buzzer) - (progress-screen load-game) - (progress-screen save-game) - (progress-screen save-game-title) - ) - (set! (-> obj transition-speed) 15.0) - ) - (else - (set! (-> obj transition-speed) 45.0) - ) - ) - 0 - (none) - ) - -(defbehavior progress-init-by-other progress () - (logclear! (-> self mask) (process-mask menu progress)) - (set! (-> self nb-of-particles) 0) - (set! (-> self max-nb-of-particles) 40) - (set! (-> self nb-of-icons) 0) - (set! (-> self in-out-position) 4096) - (set! (-> self current-debug-string) 0) - (set! (-> self current-debug-group) 0) - (set! (-> self display-level-index) 0) - (set! (-> self next-level-index) 0) - (set! (-> self option-index) 0) - (set! (-> self selected-option) #f) - (set! (-> self card-info) #f) - (set! (-> self last-option-index-change) (-> *display* real-frame-counter)) - (set! (-> self display-state-pos) 0) - (set! (-> self in-transition) #f) - (set! (-> self force-transition) #f) - (set! (-> self stat-transition) #f) - (set! (-> self level-transition) 0) - (set! (-> self left-side-x-scale) 0.0) - (set! (-> self left-side-y-scale) 0.0) - (set! (-> self right-side-x-scale) 0.0) - (set! (-> self right-side-y-scale) 0.0) - (dotimes (v1-6 5) - (set! (-> self display-state-stack v1-6) (progress-screen fuel-cell)) - ) - (init-game-options self) - (initialize-icons self) - (initialize-particles self) - (set! (-> self particle-state 0) 0) - (set! (-> self particle-state 1) 0) - (set! (-> self particle-state 2) 0) - (set! (-> self particle-state 3) 0) - (set! (-> self particle-state 4) 0) - (set! (-> self particle-state 5) 0) - (set! (-> self particle-state 6) 1) - (set! (-> self particle-state 7) 1) - (set! (-> self particle-state 8) 1) - (set! (-> self particle-state 9) 1) - (set! (-> self particle-state 10) 1) - (set! (-> self particle-state 11) 1) - (set! (-> self particle-state 12) 1) - (set! (-> self particle-state 13) 1) - (set! (-> self particle-state 14) 0) - (set! (-> self particle-state 15) 0) - (set! (-> self particle-state 16) 3) - (set! (-> self particle-state 17) 0) - (set! (-> self particle-state 18) 0) - (set! (-> self particle-state 19) 0) - (set! (-> self particle-state 20) 0) - (set! (-> self particle-state 21) 0) - (set! (-> self particle-state 22) 0) - (set! (-> self particle-state 23) 0) - (set! (-> self particle-state 24) 0) - (set! (-> self particle-state 25) 0) - (set! (-> self particle-state 26) 0) - (set! (-> self particle-state 27) 0) - (set! (-> self particle-state 28) 0) - (set! (-> self particle-state 29) 0) - (set! (-> self particle-state 30) 0) - (set! (-> self particle-state 31) 0) - (let ((gp-0 (new 'stack-no-clear 'quaternion))) - (quaternion-axis-angle! gp-0 0.0 1.0 0.0 16384.0) - (quaternion*! (-> self icons 0 icon 0 root quat) gp-0 (-> self icons 0 icon 0 root quat)) - (quaternion-axis-angle! gp-0 0.0 1.0 0.0 32768.0) - (quaternion*! (-> self icons 1 icon 0 root quat) gp-0 (-> self icons 1 icon 0 root quat)) - (quaternion-axis-angle! gp-0 0.0 1.0 0.0 49152.0) - (quaternion*! (-> self icons 2 icon 0 root quat) gp-0 (-> self icons 2 icon 0 root quat)) - (quaternion-axis-angle! gp-0 0.0 1.0 0.0 0.0) - (quaternion*! (-> self icons 3 icon 0 root quat) gp-0 (-> self icons 3 icon 0 root quat)) - ) - (adjust-ratios self (get-aspect-ratio) (get-video-mode)) - (adjust-icons self) - (set! (-> self event-hook) (-> progress-waiting event)) - (go progress-waiting) - (none) - ) - -(define *progress-stack* (the-as (pointer uint8) (malloc 'global #x3800))) -(defconstant *progress-stack-top* (&-> *progress-stack* #x3800)) - -(defun activate-progress ((creator process) (screen progress-screen)) - (when *target* - (cond - ((not *progress-process*) - (when (progress-allowed?) - (hide-hud) - (make-levels-with-tasks-available-to-progress) - (disable-level-text-file-loading) - (set! (-> *progress-state* starting-state) screen) - (let ((s4-0 (get-process *default-dead-pool* progress #x4000))) - (set! *progress-process* - (the-as (pointer progress) (when s4-0 - (let ((t9-5 (method-of-type progress activate))) - (t9-5 (the-as progress s4-0) creator 'progress (&-> *progress-stack* 14336)) - ) - (run-now-in-process s4-0 progress-init-by-other) - (-> s4-0 ppointer) - ) - ) - ) - ) - (let ((s5-1 *progress-process*)) - (set! (-> s5-1 0 completion-percentage) (calculate-completion (-> s5-1 0))) - (set! *master-mode* 'progress) - (let ((s4-1 (-> *target* current-level))) - (cond - ((!= *kernel-boot-message* 'play) - (set! (-> s5-1 0 display-level-index) 4) - ) - ((or (= s4-1 #f) (< (length *level-task-data-remap*) (-> s4-1 info index))) - (set! (-> s5-1 0 display-level-index) 0) - 0 - ) - (else - (set! (-> s5-1 0 display-level-index) (-> *level-task-data-remap* (+ (-> s4-1 info index) -1))) - ) - ) - ) - (set! (-> s5-1 0 next-level-index) (-> s5-1 0 display-level-index)) - (set! (-> s5-1 0 display-state) (progress-screen invalid)) - (set-transition-progress! (-> s5-1 0) 512) - (set! (-> s5-1 0 task-index) (get-next-task-up -1 (-> s5-1 0 display-level-index))) - ) - ) - (when *progress-process* - (enter! (-> *progress-process* 0) screen 0) - (set! (-> *progress-process* 0 card-info) #f) - ) - ) - (else - (push! (-> *progress-process* 0)) - (set! (-> *progress-process* 0 next-display-state) screen) - (set! (-> *progress-process* 0 card-info) #f) - ) - ) - ) - 0 - (none) - ) - -(defun deactivate-progress () - (when (and *progress-process* (= (-> *progress-process* 0 next-state name) 'progress-gone)) - (copy-settings-from-target! *setting-control*) - (dotimes (gp-0 (-> *progress-process* 0 nb-of-particles)) - (kill-and-free-particles (-> *progress-process* 0 particles gp-0 part)) - (set! (-> *progress-process* 0 particles gp-0 part matrix) -1) - ) - (set! (-> *progress-process* 0 nb-of-particles) 0) - (deactivate (-> *progress-process* 0)) - (set! *progress-process* (the-as (pointer progress) #f)) - (enable-level-text-file-loading) - ) - 0 - (none) - ) - -(defun hide-progress-screen () - "shoo!" - - (if *progress-process* - (send-event (ppointer->process *progress-process*) 'go-away) - ) - 0 - (none) - ) - -(defun hide-progress-icons () - (let ((v1-0 6)) - (dotimes (a0-0 8) - (set! (-> *progress-process* 0 particles v1-0 init-pos x) -320.0) - (+! v1-0 1) - ) - ) - (set! (-> *progress-process* 0 particles 5 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 14 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 15 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 19 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 20 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 21 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 22 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 23 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 24 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 25 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 26 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 27 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 28 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 29 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 30 init-pos x) -320.0) - (set! (-> *progress-process* 0 particles 31 init-pos x) -320.0) - (set! (-> *progress-process* 0 icons 4 icon-x) -320) - 0 - (none) - ) - -(defmethod relocate game-count-info ((obj game-count-info) (arg0 int)) - "Load in the game-count-info. This is a bit of a hack." - (set! *game-counts* obj) - ) - -(defmethod relocate progress ((obj progress) (arg0 int)) - (dotimes (v1-0 (-> obj nb-of-particles)) - (when (-> obj particles v1-0 part) - (if (nonzero? (-> obj particles v1-0 part)) - (set! (-> obj particles v1-0 part) - (the-as sparticle-launch-control (&+ (the-as pointer (-> obj particles v1-0 part)) arg0)) - ) - ) - ) - ) - (the-as progress ((method-of-type process relocate) obj arg0)) - ) - -(defmethod adjust-sprites progress ((obj progress)) - (let ((f0-1 (* (1/ METER_LENGTH) (the float (-> obj in-out-position))))) - (set! (-> obj particles 2 init-pos x) (the float (+ (-> obj right-x-offset) 409 (the int (* 301.5 f0-1))))) - (set! (-> obj particles 1 init-pos x) (the float (+ (-> obj left-x-offset) 59))) - (set! (-> obj left-side-x-scale) (meters (+ (/ 3.5 (-> obj sides-x-scale)) (* 10.0 f0-1)))) - (set! (-> obj left-side-y-scale) (meters (+ (-> obj sides-y-scale) (* 10.0 f0-1)))) - (set! (-> obj right-side-x-scale) (meters (+ (/ 6.0 (-> obj sides-x-scale)) (* 4.0 f0-1)))) - (set! (-> obj right-side-y-scale) (meters (+ (-> obj sides-y-scale) (* 4.0 f0-1)))) - ) - (dotimes (s5-0 (-> obj nb-of-particles)) - (set! (-> obj particles s5-0 pos x) (+ -256.0 (-> obj particles s5-0 init-pos x))) - (set! (-> obj particles s5-0 pos y) - (* 0.5 (- (* (-> obj particles s5-0 init-pos y) (-> *video-parms* relative-y-scale)) - (the float (-> *video-parms* screen-sy)) - ) - ) - ) - (set! (-> obj particles s5-0 pos z) (-> obj particles s5-0 init-pos z)) - (if (> (-> obj particles s5-0 part matrix) 0) - (set-vector! (sprite-get-user-hvdf (-> obj particles s5-0 part matrix)) - (the float (+ (the int (-> obj particles s5-0 pos x)) 2048)) - (the float (+ (the int (-> obj particles s5-0 pos y)) 2048)) - (- (-> *math-camera* hvdf-off z) (* 1024.0 (-> obj particles s5-0 pos z))) - (-> *math-camera* hvdf-off w) - ) - ) - (spawn (-> obj particles s5-0 part) *null-vector*) - ) - 0 - (none) - ) - -(defmethod adjust-icons progress ((obj progress)) - (dotimes (v1-0 (-> obj nb-of-icons)) - (when (>= v1-0 4) - (set-vector! (-> obj icons v1-0 icon 0 root scale) - (* (-> obj icons v1-0 scale-x) (-> *video-parms* relative-x-scale)) - (* (-> obj icons v1-0 scale-y) (-> *video-parms* relative-y-scale)) - (* (-> obj icons v1-0 scale-x) (-> *video-parms* relative-x-scale)) - 1.0 - ) - (set! (-> obj icons v1-0 icon 0 root trans x) (the float (+ (-> obj icons v1-0 icon-x) -256))) - (set! (-> obj icons v1-0 icon 0 root trans y) - (* (-> *video-parms* relative-y-scale) - (- (* (-> *video-parms* relative-y-scale) (the float (-> obj icons v1-0 icon-y))) - (the float (-> *video-parms* screen-sy)) - ) - ) - ) - ) - ) - 0 - (none) - ) - -(defmethod adjust-ratios progress ((obj progress) (aspect symbol) (video-mode symbol)) - (case aspect - (('aspect4x3) - (set! (-> obj sides-x-scale) 1.0) - (set! (-> obj sides-y-scale) 13.0) - (set! (-> obj left-x-offset) 0) - (set! (-> obj right-x-offset) 0) - (set! (-> obj button-scale) 1.0) - (set! (-> obj slot-scale) 8192.0) - (set! (-> obj small-orb-y-offset) 58) - (set! (-> obj icons 5 scale-x) 0.008) - (set! (-> obj icons 5 scale-y) -0.009) - (set! (-> obj big-orb-y-offset) 243) - (set! (-> obj icons 4 scale-x) 0.013) - (set! (-> obj icons 4 scale-y) -0.015) - ) - (('aspect16x9) - (set! (-> obj sides-x-scale) 1.2) - (set! (-> obj sides-y-scale) 9.8) - (set! (-> obj left-x-offset) -10) - (set! (-> obj right-x-offset) 17) - (set! (-> obj button-scale) 1.05) - (set! (-> obj slot-scale) 6144.0) - (set! (-> obj small-orb-y-offset) 59) - (set! (-> obj icons 5 scale-x) 0.008) - (set! (-> obj icons 5 scale-y) -0.0098) - (set! (-> obj big-orb-y-offset) 255) - (set! (-> obj icons 4 scale-x) 0.017) - (set! (-> obj icons 4 scale-y) -0.0205) - ) - ) - (when (= video-mode 'pal) - (set! (-> obj icons 5 scale-y) (* 1.15 (-> obj icons 5 scale-y))) - (set! (-> obj icons 4 scale-x) (* 1.05 (-> obj icons 4 scale-x))) - (set! (-> obj icons 4 scale-y) (* (-> obj icons 4 scale-y) (the-as float (if (= aspect 'aspect16x9) - 1.18 - 1.15 - ) - ) - ) - ) - (+! (-> obj big-orb-y-offset) (if (= aspect 'aspect16x9) - 3 - 2 - ) - ) - ) - 0 - (none) - ) - -(defmethod dummy-32 progress ((obj progress)) - (let ((v1-2 (-> *progress-process* 0 display-state)) - (a1-1 (-> *progress-state* starting-state)) - ) - (and (= (-> obj next-state name) 'progress-normal) - (not (-> obj in-transition)) - (not (-> obj selected-option)) - (or (= v1-2 (progress-screen fuel-cell)) - (= v1-2 (progress-screen money)) - (= v1-2 (progress-screen buzzer)) - (and (or (= a1-1 (progress-screen fuel-cell)) - (= a1-1 (progress-screen money)) - (= a1-1 (progress-screen buzzer)) - (= a1-1 (progress-screen title)) - ) - (or (= v1-2 (progress-screen settings)) - (= v1-2 (progress-screen game-settings)) - (= v1-2 (progress-screen graphic-settings)) - (= v1-2 (progress-screen sound-settings)) - (= v1-2 (progress-screen title)) - (= v1-2 (progress-screen settings-title)) - (= v1-2 (progress-screen language-options)) - ) - ) - ) - ) - ) - ) - -(defmethod dummy-19 progress ((obj progress)) - (the-as symbol (and *progress-process* (zero? (-> *progress-process* 0 in-out-position)))) - ) - -(defmethod hidden? progress ((obj progress)) - (or (not *progress-process*) (= (-> *progress-process* 0 in-out-position) 4096)) - ) - -(defstate progress-waiting (progress) - :event - (behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) - (case arg2 - (('go-away) - (go progress-gone) - ) - ) - ) - :code - (behavior () - (loop - (when (hud-hidden?) - (dotimes (gp-0 (-> self nb-of-particles)) - (if (= (-> self particles gp-0 part matrix) -1) - (set! (-> self particles gp-0 part matrix) (sprite-allocate-user-hvdf)) - ) - ) - (set-setting! *setting-control* self 'common-page 'set 0.0 1) - (suspend) - (go progress-coming-in) - ) - (suspend) - ) - (none) - ) - ) - -(defstate progress-gone (progress) - :code - (behavior () - (clear-pending-settings-from-process *setting-control* self 'process-mask) - (copy-settings-from-target! *setting-control*) - (logior! (-> self mask) (process-mask sleep)) - (suspend) - 0 - (none) - ) - ) - -(defmethod dummy-53 progress ((obj progress) (arg0 progress-screen)) - "Changes the next progress screen if need be for saving related reasons" - (let ((s4-0 (-> obj card-info)) - (gp-0 arg0) - ) - (when s4-0 - (case arg0 - (((progress-screen memcard-no-space) - (progress-screen memcard-not-inserted) - (progress-screen memcard-not-formatted) - ) - (cond - ((zero? (-> s4-0 handle)) - (set! gp-0 (progress-screen memcard-not-inserted)) - ) - ((zero? (-> s4-0 formatted)) - (cond - ((or (zero? (-> obj display-state-pos)) - (and (!= (-> *progress-state* starting-state) 27) (nonzero? (-> *progress-state* starting-state))) - ) - (set-master-mode 'game) - ) - (else - (if (!= arg0 (progress-screen memcard-not-formatted)) - (set! gp-0 (progress-screen memcard-format)) - ) - ) - ) - ) - ((and (zero? (-> s4-0 inited)) (< (-> s4-0 mem-actual) (-> s4-0 mem-required))) - (set! gp-0 (progress-screen memcard-no-space)) - ) - ((or (zero? (-> obj display-state-pos)) - (and (!= (-> *progress-state* starting-state) 27) (nonzero? (-> *progress-state* starting-state))) - ) - (set-master-mode 'game) - ) - (else - (set! gp-0 (progress-screen save-game)) - ) - ) - ) - (((progress-screen memcard-insert)) - (if (= (-> s4-0 inited) 1) - (set! gp-0 (progress-screen load-game)) - ) - ) - ) - (cond - ((zero? (-> s4-0 handle)) - (cond - ((-> *setting-control* current auto-save) - (set! gp-0 (progress-screen memcard-removed)) - ) - (else - (cond - ((= arg0 (progress-screen load-game)) - (set! gp-0 (progress-screen memcard-insert)) - ) - ((or (= arg0 (progress-screen memcard-format)) - (= arg0 (progress-screen memcard-no-space)) - (= arg0 (progress-screen memcard-not-formatted)) - (= arg0 (progress-screen save-game)) - (= arg0 (progress-screen save-game-title)) - (= arg0 (progress-screen memcard-no-data)) - (= arg0 (progress-screen memcard-data-exists)) - ) - (set! gp-0 (progress-screen memcard-not-inserted)) - ) - ) - ) - ) - ) - ((zero? (-> s4-0 formatted)) - (case arg0 - (((progress-screen load-game)) - (set! gp-0 (progress-screen memcard-insert)) - ) - (((progress-screen save-game) (progress-screen save-game-title)) - (set! gp-0 (progress-screen memcard-format)) - ) - ) - ) - ((zero? (-> s4-0 inited)) - (case arg0 - (((progress-screen save-game) (progress-screen save-game-title)) - (if (>= (-> s4-0 mem-actual) (-> s4-0 mem-required)) - (set! gp-0 (progress-screen memcard-no-data)) - (set! gp-0 (progress-screen memcard-no-space)) - ) - ) - (((progress-screen load-game)) - (set! gp-0 (progress-screen memcard-insert)) - ) - ) - ) - ) - ) - gp-0 - ) - ) - -(defmethod dummy-31 progress ((obj progress)) - (let ((s5-0 (-> obj card-info))) - (when (and s5-0 (not (-> obj in-transition))) - (when (or (cpad-pressed? 0 x) (cpad-pressed? 0 circle)) - (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons x)) - (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons x)) - (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons circle)) - (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons circle)) - (case (-> obj display-state) - (((progress-screen load-game)) - (cond - ((< (-> obj option-index) 4) - (when (nonzero? (-> s5-0 file (-> obj option-index) present)) - (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> *progress-state* which) (-> obj option-index)) - (set! (-> obj next-display-state) (progress-screen memcard-loading)) - ) - ) - (else - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj next-display-state) (progress-screen invalid)) - ) - ) - ) - (((progress-screen save-game) (progress-screen save-game-title)) - (cond - ((< (-> obj option-index) 4) - (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> *progress-state* which) (-> obj option-index)) - (if (zero? (-> s5-0 file (-> obj option-index) present)) - (set! (-> obj next-display-state) (progress-screen memcard-saving)) - (set! (-> obj next-display-state) (progress-screen memcard-data-exists)) - ) - ) - ((and (= (-> obj display-state) (progress-screen save-game-title)) (= (-> obj option-index) 4)) - (sound-play-by-name (static-sound-name "starts-options") (new-sound-id) 1024 0 0 1 #t) - (sound-volume-off) - (set! (-> *game-info* mode) 'play) - (initialize! *game-info* 'game (the-as game-save #f) "intro-start") - (set-master-mode 'game) - ) - (else - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj next-display-state) (progress-screen invalid)) - ) - ) - ) - (((progress-screen memcard-insert)) - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj next-display-state) (progress-screen invalid)) - ) - (((progress-screen memcard-data-exists)) - (cond - ((-> *progress-state* yes-no-choice) - (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj next-display-state) (progress-screen memcard-saving)) - ) - ((begin - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - (= (-> obj display-state-stack 0) (progress-screen title)) - ) - (set! (-> obj next-display-state) (progress-screen save-game-title)) - ) - (else - (set! (-> obj next-display-state) (progress-screen save-game)) - ) - ) - ) - (((progress-screen memcard-no-data)) - (cond - ((-> *progress-state* yes-no-choice) - (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj next-display-state) (progress-screen memcard-creating)) - ) - (else - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - (sound-volume-off) - (set! (-> *game-info* mode) 'play) - (initialize! *game-info* 'game (the-as game-save #f) "intro-start") - (set-master-mode 'game) - ) - ) - ) - (((progress-screen memcard-no-space) - (progress-screen memcard-not-inserted) - (progress-screen memcard-not-formatted) - ) - (cond - ((= (-> obj display-state-stack 0) (progress-screen title)) - (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) - (sound-volume-off) - (set! (-> *game-info* mode) 'play) - (initialize! *game-info* 'game (the-as game-save #f) "intro-start") - (set-master-mode 'game) - ) - ((nonzero? (-> obj display-state-stack 0)) - (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) - (set-master-mode 'game) - ) - (else - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj next-display-state) (progress-screen invalid)) - ) - ) - ) - (((progress-screen memcard-error-loading) - (progress-screen memcard-error-saving) - (progress-screen memcard-error-formatting) - (progress-screen memcard-error-creating) - (progress-screen memcard-auto-save-error) - (progress-screen memcard-removed) - (progress-screen auto-save) - ) - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj next-display-state) (progress-screen invalid)) - ) - (((progress-screen pal-change-to-60hz)) - (cond - ((-> *progress-state* yes-no-choice) - (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> *setting-control* default video-mode) (-> *progress-state* video-mode-choice)) - (set! (-> obj video-mode-timeout) (-> *display* real-frame-counter)) - (set! (-> obj next-display-state) (progress-screen pal-now-60hz)) - ) - (else - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> *progress-state* video-mode-choice) 'pal) - (set! (-> obj next-display-state) (progress-screen invalid)) - ) - ) - ) - (((progress-screen pal-now-60hz)) - (cond - ((not (-> *progress-state* yes-no-choice)) - (set! (-> *progress-state* video-mode-choice) 'pal) - (set! (-> *setting-control* default video-mode) (-> *progress-state* video-mode-choice)) - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - ) - (else - (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) - ) - ) - (set! (-> obj next-display-state) (progress-screen invalid)) - ) - (((progress-screen no-disc) (progress-screen bad-disc)) - (when (is-cd-in?) - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj next-display-state) (progress-screen invalid)) - ) - ) - (((progress-screen quit)) - (cond - ((-> *progress-state* yes-no-choice) - (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) - (sound-volume-off) - (set! (-> *game-info* mode) 'play) - (initialize! *game-info* 'game (the-as game-save #f) "title-start") - ) - (else - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj next-display-state) (progress-screen invalid)) - ) - ) - ) - (((progress-screen memcard-format)) - (cond - ((-> *progress-state* yes-no-choice) - (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj next-display-state) (progress-screen memcard-formatting)) - ) - ((= (-> obj display-state-stack 0) (progress-screen title)) - (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) - (sound-volume-off) - (set! (-> *game-info* mode) 'play) - (initialize! *game-info* 'game (the-as game-save #f) "intro-start") - (set-master-mode 'game) - ) - (else - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj next-display-state) (progress-screen invalid)) - ) - ) - ) - ) - ) - ) - ) - 0 - (none) - ) - -(defmethod dummy-29 progress ((obj progress)) - (mc-get-slot-info 0 *progress-save-info*) - (set! (-> obj card-info) *progress-save-info*) - (let ((s5-0 (-> *options-remap* (-> obj display-state)))) - (when (and s5-0 (not (-> obj in-transition))) - (cond - ((cpad-hold? 0 up) - (cond - ((cpad-pressed? 0 up) - (when (not (-> obj selected-option)) - (if (!= (length s5-0) 1) - (sound-play-by-name (static-sound-name "cursor-up-down") (new-sound-id) 1024 0 0 1 #t) - ) - (set! (-> obj last-option-index-change) (-> *display* real-frame-counter)) - (if (> (-> obj option-index) 0) - (+! (-> obj option-index) -1) - (set! (-> obj option-index) (+ (length s5-0) -1)) - ) - ) - ) - (else - (when (-> obj selected-option) - (let ((v1-34 #f)) - (case (-> s5-0 (-> obj option-index) option-type) - ((3) - (when (< -48 (-> *setting-control* current screeny)) - (set! v1-34 #t) - (+! (-> *setting-control* default screeny) -1) - ) - ) - ) - (when v1-34 - (when (< (seconds 0.3) (- (-> *display* real-frame-counter) (-> *progress-state* last-slider-sound))) - (set! (-> *progress-state* last-slider-sound) (-> *display* real-frame-counter)) - (sound-play-by-name (static-sound-name "slider2001") (new-sound-id) 1024 0 0 1 #t) - ) - ) - ) - ) - ) - ) - ) - ((cpad-hold? 0 down) - (cond - ((cpad-pressed? 0 down) - (when (not (-> obj selected-option)) - (if (!= (length s5-0) 1) - (sound-play-by-name (static-sound-name "cursor-up-down") (new-sound-id) 1024 0 0 1 #t) - ) - (set! (-> obj last-option-index-change) (-> *display* real-frame-counter)) - (cond - ((< (-> obj option-index) (+ (length s5-0) -1)) - (+! (-> obj option-index) 1) - ) - (else - (set! (-> obj option-index) 0) - 0 - ) - ) - ) - ) - (else - (when (-> obj selected-option) - (let ((v1-69 #f)) - (case (-> s5-0 (-> obj option-index) option-type) - ((3) - (when (< (-> *setting-control* current screeny) 48) - (set! v1-69 #t) - (+! (-> *setting-control* default screeny) 1) - ) - ) - ) - (when v1-69 - (when (< (seconds 0.3) (- (-> *display* real-frame-counter) (-> *progress-state* last-slider-sound))) - (set! (-> *progress-state* last-slider-sound) (-> *display* real-frame-counter)) - (sound-play-by-name (static-sound-name "slider2001") (new-sound-id) 1024 0 0 1 #t) - ) - ) - ) - ) - ) - ) - ) - ((cpad-hold? 0 left) - (cond - ((cpad-pressed? 0 left) - (when (or (-> obj selected-option) (= (-> s5-0 (-> obj option-index) option-type) 7)) - (let ((play-sound? #f)) - (case (-> s5-0 (-> obj option-index) option-type) - ((2 7) - (when (not (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)))) - (set! play-sound? #t) - (if (= (-> s5-0 (-> obj option-index) value-to-modify) (&-> *setting-control* current vibration)) - (cpad-set-buzz! (-> *cpad-list* cpads 0) 1 255 (seconds 0.3)) - ) - ) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) #t) - ) - ((4) - (set! play-sound? (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'aspect16x9)) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'aspect4x3) - ) - ((5) - (set! play-sound? (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'ntsc)) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'pal) - ) - ((#x15) - (set! play-sound? (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) #f)) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) #t)) - ;; arbitrary list options - ((1 #x10 #x11 #x12 #x13 #x14) - ;; every list moves the same way, common logic - (set! (-> *progress-menu-list-tracker* transition?) #t) - (set! (-> *progress-menu-list-tracker* direction) 'left) - (set! play-sound? #t) - ;; now the per menu logic...this should all be refactored and made easier but...must resist - (case (-> s5-0 (-> obj option-index) option-type) - ;; language selection - ((1) - (if (= (-> *progress-menu-list-tracker* selected-index) 0) - (set! (-> *progress-menu-list-tracker* selected-index) (dec (length *language-name-remap*))) - (set! (-> *progress-menu-list-tracker* selected-index) (dec (-> *progress-menu-list-tracker* selected-index)))) - (set! (-> (the-as (pointer int64) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> *progress-menu-list-tracker* selected-index))) - ;; display mode setting - ((#x12) - ;; get the current selected item - (let ((curr-val (-> *pc-graphics-display-mode-symbol-options* - (-> *progress-menu-list-tracker* selected-index)))) - (if (= curr-val (first-arr *pc-graphics-display-mode-symbol-options*)) - ;; if we've hit the beginning, wrap around to the end - (set! (-> *progress-menu-list-tracker* selected-index) - (last-idx-arr *pc-graphics-display-mode-symbol-options*)) - ;; else just move left - (set! (-> *progress-menu-list-tracker* selected-index) - (dec (-> *progress-menu-list-tracker* selected-index)))))) - ;; aspect ratio setting - ((#x10) - (if (-> *pc-settings* use-original-aspect-ratio?) - (let ((curr-val (-> *pc-graphics-original-aspect-ratio-options* - (-> *progress-menu-list-tracker* selected-index)))) - (if (= curr-val (first-arr *pc-graphics-original-aspect-ratio-options*)) - (set! (-> *progress-menu-list-tracker* selected-index) - (last-idx-arr *pc-graphics-original-aspect-ratio-options*)) - (set! (-> *progress-menu-list-tracker* selected-index) - (dec (-> *progress-menu-list-tracker* selected-index))))) - (let ((curr-val (-> *pc-graphics-aspect-ratio-options* - (-> *progress-menu-list-tracker* selected-index)))) - (if (= curr-val (first-arr *pc-graphics-aspect-ratio-options*)) - (set! (-> *progress-menu-list-tracker* selected-index) - (last-idx-arr *pc-graphics-aspect-ratio-options*)) - (set! (-> *progress-menu-list-tracker* selected-index) - (dec (-> *progress-menu-list-tracker* selected-index))))))) - ;; resolution setting - ;; this is a little more sophisticated -- only display the ones related to the aspect ratio - ((#x11) - (let ((curr-idx (-> *progress-menu-list-tracker* selected-index)) - (new-idx (dec (-> *progress-menu-list-tracker* selected-index)))) - (case (-> *pc-settings* aspect-ratio-mode) - (('orig-aspect-4x3) - (when (= (-> *pc-graphics-4x3-valid-resolutions* curr-idx) - (first-arr *pc-graphics-4x3-valid-resolutions*)) - (set! new-idx (last-idx-arr *pc-graphics-4x3-valid-resolutions*)))) - (('orig-aspect-16x9) - (when (= (-> *pc-graphics-16x9-valid-resolutions* curr-idx) - (first-arr *pc-graphics-16x9-valid-resolutions*)) - (set! new-idx (last-idx-arr *pc-graphics-16x9-valid-resolutions*)))) - (('pc-aspect-4x3) - (when (= (-> *pc-graphics-4x3-valid-resolutions* curr-idx) - (first-arr *pc-graphics-4x3-valid-resolutions*)) - (set! new-idx (last-idx-arr *pc-graphics-4x3-valid-resolutions*)))) - (('pc-aspect-5x4) - (when (= (-> *pc-graphics-5x4-valid-resolutions* curr-idx) - (first-arr *pc-graphics-5x4-valid-resolutions*)) - (set! new-idx (last-idx-arr *pc-graphics-5x4-valid-resolutions*)))) - (('pc-aspect-16x9) - (when (= (-> *pc-graphics-16x9-valid-resolutions* curr-idx) - (first-arr *pc-graphics-16x9-valid-resolutions*)) - (set! new-idx (last-idx-arr *pc-graphics-16x9-valid-resolutions*)))) - (('pc-aspect-21x9) - (when (= (-> *pc-graphics-21x9-valid-resolutions* curr-idx) - (first-arr *pc-graphics-21x9-valid-resolutions*)) - (set! new-idx (last-idx-arr *pc-graphics-21x9-valid-resolutions*)))) - (('pc-aspect-32x9) - (when (= (-> *pc-graphics-32x9-valid-resolutions* curr-idx) - (first-arr *pc-graphics-32x9-valid-resolutions*)) - (set! new-idx (last-idx-arr *pc-graphics-32x9-valid-resolutions*))))) - (set! (-> *progress-menu-list-tracker* selected-index) new-idx))) - ;; subtitle language selection - ((#x13) - (if (= (-> *progress-menu-list-tracker* selected-index) 0) - (set! (-> *progress-menu-list-tracker* selected-index) (dec (length *pc-subtitle-language-name-remap*))) - (set! (-> *progress-menu-list-tracker* selected-index) (dec (-> *progress-menu-list-tracker* selected-index))))) - ((#x14) - ;; get the current selected item - (let ((curr-val (-> *pc-subtitle-speaker-valid-options* - (-> *progress-menu-list-tracker* selected-index)))) - (if (= curr-val (first-arr *pc-subtitle-speaker-valid-options*)) - (set! (-> *progress-menu-list-tracker* selected-index) - (last-idx-arr *pc-subtitle-speaker-valid-options*)) - (set! (-> *progress-menu-list-tracker* selected-index) - (dec (-> *progress-menu-list-tracker* selected-index))))))) - (format 0 "VAS: Moving Left. New Index: ~D~%" (-> *progress-menu-list-tracker* selected-index)))) - (if play-sound? - (sound-play-by-name (static-sound-name "cursor-l-r") (new-sound-id) 1024 0 0 1 #t))))) - (else - (when (-> obj selected-option) - (let ((v1-157 #f)) - (let ((a0-101 (-> s5-0 (-> obj option-index) option-type))) - (cond - ((zero? a0-101) - (cond - ((>= (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (+ 1.0 (-> s5-0 (-> obj option-index) param1)) - ) - (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (+ -1.0 (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - (set! v1-157 #t) - ) - ((< (-> s5-0 (-> obj option-index) param1) - (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - ) - (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> s5-0 (-> obj option-index) param1) - ) - (set! v1-157 #t) - ) - ) - ) - ((= a0-101 3) - (when (< -96 (-> *setting-control* default screenx)) - (set! v1-157 #t) - (+! (-> *setting-control* default screenx) -1) - ) - ) - ) - ) - (when v1-157 - (let ((f30-0 100.0)) - (case (-> s5-0 (-> obj option-index) name) - (((game-text-id music-volume) (game-text-id speech-volume)) - (set! f30-0 (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - ) - (when (< (seconds 0.3) (- (-> *display* real-frame-counter) (-> *progress-state* last-slider-sound))) - (set! (-> *progress-state* last-slider-sound) (-> *display* real-frame-counter)) - (sound-play-by-name (static-sound-name "slider2001") (new-sound-id) (the int (* 10.24 f30-0)) 0 0 1 #t) - ) - ) - ) - ) - ) - ) - ) - ) - ((cpad-hold? 0 right) - (cond - ((cpad-pressed? 0 right) - (when (or (-> obj selected-option) (= (-> s5-0 (-> obj option-index) option-type) 7)) - (let ((play-sound? #f)) - (case (-> s5-0 (-> obj option-index) option-type) - ((2 7) - (set! play-sound? (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)))) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) #f) - ) - ((4) - (set! play-sound? (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'aspect4x3)) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'aspect16x9) - ) - ((5) - (set! play-sound? (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'pal)) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) 'ntsc) - ) - ((#x15) - (set! play-sound? (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) #t)) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) #f)) - ;; arbitrary list options - ((1 #x10 #x11 #x12 #x13 #x14) - ;; every list moves the same way, common logic - (set! (-> *progress-menu-list-tracker* transition?) #t) - (set! (-> *progress-menu-list-tracker* direction) 'right) - (set! play-sound? #t) - ;; now the per menu logic...this should all be refactored and made easier but...must resist - (case (-> s5-0 (-> obj option-index) option-type) - ;; language selection - ((1) - (if (= (-> *progress-menu-list-tracker* selected-index) (dec (length *language-name-remap*))) - (set! (-> *progress-menu-list-tracker* selected-index) 0) - (set! (-> *progress-menu-list-tracker* selected-index) (inc (-> *progress-menu-list-tracker* selected-index)))) - (set! (-> (the-as (pointer int64) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> *progress-menu-list-tracker* selected-index))) - ;; display mode setting - ((#x12) - ;; get the current selected item - (let ((curr-val (-> *pc-graphics-display-mode-symbol-options* - (-> *progress-menu-list-tracker* selected-index)))) - (if (= curr-val (last-arr *pc-graphics-display-mode-symbol-options*)) - ;; if we've hit the end, wrap around to the beginning - (set! (-> *progress-menu-list-tracker* selected-index) 0) - ;; else just move right - (set! (-> *progress-menu-list-tracker* selected-index) - (inc (-> *progress-menu-list-tracker* selected-index)))))) - ;; aspect ratio setting - ((#x10) - (if (-> *pc-settings* use-original-aspect-ratio?) - (let ((curr-val (-> *pc-graphics-original-aspect-ratio-options* - (-> *progress-menu-list-tracker* selected-index)))) - (if (= curr-val (last-arr *pc-graphics-original-aspect-ratio-options*)) - (set! (-> *progress-menu-list-tracker* selected-index) 0) - (set! (-> *progress-menu-list-tracker* selected-index) - (inc (-> *progress-menu-list-tracker* selected-index))))) - (let ((curr-val (-> *pc-graphics-aspect-ratio-options* - (-> *progress-menu-list-tracker* selected-index)))) - (if (= curr-val (last-arr *pc-graphics-aspect-ratio-options*)) - (set! (-> *progress-menu-list-tracker* selected-index) 0) - (set! (-> *progress-menu-list-tracker* selected-index) - (inc (-> *progress-menu-list-tracker* selected-index))))))) - ;; resolution setting - ;; this is a little more sophisticated -- only display the ones related to the aspect ratio - ((#x11) - (let ((curr-idx (-> *progress-menu-list-tracker* selected-index)) - (new-idx (inc (-> *progress-menu-list-tracker* selected-index)))) - (case (-> *pc-settings* aspect-ratio-mode) - (('orig-aspect-4x3) - (when (= (-> *pc-graphics-4x3-valid-resolutions* curr-idx) - (last-arr *pc-graphics-4x3-valid-resolutions*)) - (set! new-idx 0))) - (('orig-aspect-16x9) - (when (= (-> *pc-graphics-16x9-valid-resolutions* curr-idx) - (last-arr *pc-graphics-16x9-valid-resolutions*)) - (set! new-idx 0))) - (('pc-aspect-4x3) - (when (= (-> *pc-graphics-4x3-valid-resolutions* curr-idx) - (last-arr *pc-graphics-4x3-valid-resolutions*)) - (set! new-idx 0))) - (('pc-aspect-5x4) - (when (= (-> *pc-graphics-5x4-valid-resolutions* curr-idx) - (last-arr *pc-graphics-5x4-valid-resolutions*)) - (set! new-idx 0))) - (('pc-aspect-16x9) - (when (= (-> *pc-graphics-16x9-valid-resolutions* curr-idx) - (last-arr *pc-graphics-16x9-valid-resolutions*)) - (set! new-idx 0))) - (('pc-aspect-21x9) - (when (= (-> *pc-graphics-21x9-valid-resolutions* curr-idx) - (last-arr *pc-graphics-21x9-valid-resolutions*)) - (set! new-idx 0))) - (('pc-aspect-32x9) - (when (= (-> *pc-graphics-32x9-valid-resolutions* curr-idx) - (last-arr *pc-graphics-32x9-valid-resolutions*)) - (set! new-idx 0)))) - (set! (-> *progress-menu-list-tracker* selected-index) new-idx))) - ;; subtitle language selection - ((#x13) - (if (= (-> *progress-menu-list-tracker* selected-index) (dec (length *pc-subtitle-language-name-remap*))) - (set! (-> *progress-menu-list-tracker* selected-index) 0) - (set! (-> *progress-menu-list-tracker* selected-index) (inc (-> *progress-menu-list-tracker* selected-index))))) - ((#x14) - ;; get the current selected item - (let ((curr-val (-> *pc-subtitle-speaker-valid-options* - (-> *progress-menu-list-tracker* selected-index)))) - (if (= curr-val (last-arr *pc-subtitle-speaker-valid-options*)) - (set! (-> *progress-menu-list-tracker* selected-index) 0) - (set! (-> *progress-menu-list-tracker* selected-index) - (inc (-> *progress-menu-list-tracker* selected-index))))))) - (format 0 "VAS: Moving Right. New Index: ~D~%" (-> *progress-menu-list-tracker* selected-index)))) - (if play-sound? - (sound-play-by-name (static-sound-name "cursor-l-r") (new-sound-id) 1024 0 0 1 #t))))) - (else - (when (-> obj selected-option) - (let ((v1-263 #f)) - (let ((a0-177 (-> s5-0 (-> obj option-index) option-type))) - (cond - ((zero? a0-177) - (cond - ((>= (+ -1.0 (-> s5-0 (-> obj option-index) param2)) - (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - ) - (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (+ 1.0 (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - (set! v1-263 #t) - ) - ((< (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> s5-0 (-> obj option-index) param2) - ) - (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> s5-0 (-> obj option-index) param2) - ) - (set! v1-263 #t) - ) - ) - ) - ((= a0-177 3) - (when (< (-> *setting-control* default screenx) 96) - (set! v1-263 #t) - (+! (-> *setting-control* default screenx) 1) - ) - ) - ) - ) - (when v1-263 - (let ((f30-1 100.0)) - (case (-> s5-0 (-> obj option-index) name) - (((game-text-id music-volume) (game-text-id speech-volume)) - (set! f30-1 (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - ) - (when (< (seconds 0.3) (- (-> *display* real-frame-counter) (-> *progress-state* last-slider-sound))) - (set! (-> *progress-state* last-slider-sound) (-> *display* real-frame-counter)) - (sound-play-by-name (static-sound-name "slider2001") (new-sound-id) (the int (* 10.24 f30-1)) 0 0 1 #t) - ) - ) - ) - ) - ) - ) - ) - ) - ((or (cpad-pressed? 0 square) (cpad-pressed? 0 triangle)) - (cond - ((-> obj selected-option) - (let ((v1-319 (-> s5-0 (-> obj option-index) option-type))) - (cond - ((zero? v1-319) - (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> *progress-state* slider-backup) - ) - ) - ((= v1-319 1) - (set! (-> (the-as (pointer int64) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> *progress-state* language-backup) - ) - ) - ((= v1-319 2) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> *progress-state* on-off-backup) - ) - ) - ((= v1-319 3) - (set! (-> *setting-control* default screenx) (-> *progress-state* center-x-backup)) - (set! (-> *setting-control* default screeny) (-> *progress-state* center-y-backup)) - ) - ((or (= v1-319 4) (= v1-319 5)) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> *progress-state* aspect-ratio-backup) - ) - ) - ) - ) - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj selected-option) #f) - ) - ((or (dummy-32 obj) - (= (-> obj display-state) (progress-screen load-game)) - (= (-> obj display-state) (progress-screen save-game)) - (= (-> obj display-state) (progress-screen save-game-title)) - ) - (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons square)) - (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons square)) - (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons triangle)) - (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons triangle)) - (if (= (-> obj display-state) (progress-screen settings)) - (sound-play-by-name (static-sound-name "menu-stats") (new-sound-id) 1024 0 0 1 #t) - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - ) - (load-level-text-files (-> *level-task-data* (-> obj display-level-index) text-group-index)) - (set! (-> obj next-display-state) (progress-screen invalid)) - ) - ) - ) - ;; confirm selection - ((or (cpad-pressed? 0 x) (cpad-pressed? 0 circle)) - (cond - ((not (-> obj selected-option)) - (cond - ((= (-> s5-0 (-> obj option-index) option-type) 6) - (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons x)) - (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons x)) - (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons circle)) - (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons circle)) - (push! obj) - (sound-play-by-name (static-sound-name "select-option") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj next-display-state) (the-as progress-screen (-> s5-0 (-> obj option-index) param3))) - (case (-> obj next-display-state) - (((progress-screen load-game) - (progress-screen save-game) - (progress-screen save-game-title)) - (set! (-> obj next-display-state) - (dummy-53 obj (-> obj next-display-state))) - ) - ) - ) - ((= (-> s5-0 (-> obj option-index) option-type) 8) - (cond - ((= (-> s5-0 (-> obj option-index) name) (game-text-id exit-demo)) - (set! *master-exit* 'force) - (set-master-mode 'game) - ) - ((= (-> s5-0 (-> obj option-index) name) (game-text-id back)) - (if (= (-> obj display-state) (progress-screen settings)) - (sound-play-by-name (static-sound-name "menu-stats") (new-sound-id) 1024 0 0 1 #t) - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - ) - (load-level-text-files (-> *level-task-data* (-> obj display-level-index) text-group-index)) - (set! (-> obj next-display-state) (progress-screen invalid)) - ) - ) - ) - ((!= (-> s5-0 (-> obj option-index) option-type) 7) - (let ((v1-427 (-> s5-0 (-> obj option-index) option-type))) - (cond - ((zero? v1-427) - (set! (-> *progress-state* slider-backup) - (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - ) - ) - ((= v1-427 1) - (set! (-> *progress-state* language-backup) - (the-as int (-> (the-as (pointer uint64) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - ) - ((= v1-427 2) - (set! (-> *progress-state* on-off-backup) - (the-as symbol (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - ) - ((= v1-427 3) - (set! (-> *progress-state* center-x-backup) (-> *setting-control* default screenx)) - (set! (-> *progress-state* center-y-backup) (-> *setting-control* default screeny)) - ) - ((= v1-427 #x15) - (set! (-> *progress-state* aspect-ratio-choice) (-> *pc-settings* use-original-aspect-ratio?))))) - (sound-play-by-name (static-sound-name "select-option") (new-sound-id) 1024 0 0 1 #t) - (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons x)) - (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons x)) - (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons circle)) - (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons circle)) - (set! (-> obj selected-option) #t) - ;; arbitrary sized list options, they always scroll in the same manner - (when (or (= (-> s5-0 (-> obj option-index) option-type) 1) - (= (-> s5-0 (-> obj option-index) option-type) #x10) - (= (-> s5-0 (-> obj option-index) option-type) #x11) - (= (-> s5-0 (-> obj option-index) option-type) #x12) - (= (-> s5-0 (-> obj option-index) option-type) #x13) - (= (-> s5-0 (-> obj option-index) option-type) #x14)) - (format 0 "VAS: list option opened~%") - ;; reset tracker to defaults ;; defaults to left? - (set! (-> *progress-menu-list-tracker* direction) 'left) - (set! (-> *progress-menu-list-tracker* transition?) #f) - (set! (-> *progress-menu-list-tracker* x-offset) 0) - ;; each one has a slightly different handling though - ;; set the currently selected item - (case (-> s5-0 (-> obj option-index) option-type) - ((1) - (set! (-> *progress-menu-list-tracker* selected-index) - (the-as int (-> *setting-control* current language)))) - ((#x10) - (if (-> *pc-settings* use-original-aspect-ratio?) - (set! (-> *progress-menu-list-tracker* selected-index) - (arr-idx-of *pc-graphics-original-aspect-ratio-options* (-> *pc-settings* aspect-ratio-mode) 0)) - (set! (-> *progress-menu-list-tracker* selected-index) - (arr-idx-of *pc-graphics-aspect-ratio-options* (-> *pc-settings* aspect-ratio-mode) 0)))) - ((#x11) - (case (-> *pc-settings* aspect-ratio-mode) - (('orig-aspect-4x3) - (set! (-> *progress-menu-list-tracker* selected-index) - (arr-idx-of *pc-graphics-4x3-valid-resolutions* (-> *pc-settings* resolution) 0))) - (('orig-aspect-16x9) - (set! (-> *progress-menu-list-tracker* selected-index) - (arr-idx-of *pc-graphics-16x9-valid-resolutions* (-> *pc-settings* resolution) 0))) - (('pc-aspect-4x3) - (set! (-> *progress-menu-list-tracker* selected-index) - (arr-idx-of *pc-graphics-4x3-valid-resolutions* (-> *pc-settings* resolution) 0))) - (('pc-aspect-5x4) - (set! (-> *progress-menu-list-tracker* selected-index) - (arr-idx-of *pc-graphics-5x4-valid-resolutions* (-> *pc-settings* resolution) 0))) - (('pc-aspect-16x9) - (set! (-> *progress-menu-list-tracker* selected-index) - (arr-idx-of *pc-graphics-16x9-valid-resolutions* (-> *pc-settings* resolution) 0))) - (('pc-aspect-21x9) - (set! (-> *progress-menu-list-tracker* selected-index) - (arr-idx-of *pc-graphics-21x9-valid-resolutions* (-> *pc-settings* resolution) 0))) - (('pc-aspect-32x9) - (set! (-> *progress-menu-list-tracker* selected-index) - (arr-idx-of *pc-graphics-32x9-valid-resolutions* (-> *pc-settings* resolution) 0))))) - ((#x12) - (set! (-> *progress-menu-list-tracker* selected-index) - (arr-idx-of *pc-graphics-display-mode-symbol-options* (-> *pc-settings* display-mode) 0))) - ((#x13) - (set! (-> *progress-menu-list-tracker* selected-index) - (the-as int (-> *pc-settings* subtitle-language)))) - ((#x14) - (set! (-> *progress-menu-list-tracker* selected-index) - (arr-idx-of *pc-subtitle-speaker-valid-options* (-> *pc-settings* subtitle-speaker?) 0))))) - ) - ) - ) - (else - (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj selected-option) #f) - (format 0 "VAS: list selection confirmed!~%") - (case (-> s5-0 (-> obj option-index) option-type) - ((#x15) - (use-orig-aspect-ratio! *pc-settings* (-> *progress-state* aspect-ratio-choice))) - ((5) - (case (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify))) - (('pal) - (set! (-> *setting-control* default video-mode) - (the-as symbol (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - ) - (('ntsc) - (push! obj) - (set! (-> obj next-display-state) (progress-screen pal-change-to-60hz)) - ) - ) - ) - ((1) - (when (not (-> *progress-menu-list-tracker* transition?)) - (load-level-text-files (-> obj display-level-index)))) - ((#x10) - (if (-> *pc-settings* use-original-aspect-ratio?) - (set-aspect-ratio-mode! *pc-settings* - (-> *pc-graphics-original-aspect-ratio-options* (-> *progress-menu-list-tracker* selected-index))) - (set-aspect-ratio-mode! *pc-settings* - (-> *pc-graphics-aspect-ratio-options* (-> *progress-menu-list-tracker* selected-index))))) - ((#x11) - (case (-> *pc-settings* aspect-ratio-mode) - (('orig-aspect-4x3) - (set-resolution! *pc-settings* - (-> *pc-graphics-4x3-valid-resolutions* (-> *progress-menu-list-tracker* selected-index)))) - (('orig-aspect-16x9) - (set-resolution! *pc-settings* - (-> *pc-graphics-16x9-valid-resolutions* (-> *progress-menu-list-tracker* selected-index)))) - (('pc-aspect-4x3) - (set-resolution! *pc-settings* - (-> *pc-graphics-4x3-valid-resolutions* (-> *progress-menu-list-tracker* selected-index)))) - (('pc-aspect-5x4) - (set-resolution! *pc-settings* - (-> *pc-graphics-5x4-valid-resolutions* (-> *progress-menu-list-tracker* selected-index)))) - (('pc-aspect-16x9) - (set-resolution! *pc-settings* - (-> *pc-graphics-16x9-valid-resolutions* (-> *progress-menu-list-tracker* selected-index)))) - (('pc-aspect-21x9) - (set-resolution! *pc-settings* - (-> *pc-graphics-21x9-valid-resolutions* (-> *progress-menu-list-tracker* selected-index)))) - (('pc-aspect-32x9) - (set-resolution! *pc-settings* - (-> *pc-graphics-32x9-valid-resolutions* (-> *progress-menu-list-tracker* selected-index)))))) - ((#x12) - (set-display-mode! *pc-settings* - (-> *pc-graphics-display-mode-symbol-options* (-> *progress-menu-list-tracker* selected-index)))) - ((#x13) - (set! (-> *pc-settings* subtitle-language) - (the pc-subtitle-lang (-> *progress-menu-list-tracker* selected-index)))) - ((#x14) - (set! (-> *pc-settings* subtitle-speaker?) - (-> *pc-subtitle-speaker-valid-options* (-> *progress-menu-list-tracker* selected-index)))) - ) - ;; persist pc-settings - (commit-to-file *pc-settings*) - ) - ) - ) - ) - ) - ) - 0 - (none) - ) - -(defmethod respond-progress progress ((obj progress)) - (when (not (-> obj in-transition)) - (cond - ((cpad-pressed? 0 up) - (let ((s5-0 (-> obj display-level-index))) - (set! (-> obj next-level-index) (get-next-level-down s5-0)) - (when (!= s5-0 (-> obj next-level-index)) - (sound-play-by-name (static-sound-name "cursor-up-down") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj level-transition) 2) - ) - ) - ) - ((cpad-pressed? 0 down) - (let ((s5-2 (-> obj next-level-index))) - (set! (-> obj next-level-index) (get-next-level-up s5-2)) - (when (!= s5-2 (-> obj next-level-index)) - (sound-play-by-name (static-sound-name "cursor-up-down") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj level-transition) 1) - ) - ) - ) - ((cpad-pressed? 0 square) - (when (nonzero? (-> obj display-state)) - (sound-play-by-name (static-sound-name "select-option") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj next-display-state) (progress-screen fuel-cell)) - (set! (-> obj stat-transition) #t) - ) - ) - ((cpad-pressed? 0 x) - (when (!= (-> obj display-state) (progress-screen money)) - (sound-play-by-name (static-sound-name "select-option") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj next-display-state) (progress-screen money)) - (set! (-> obj stat-transition) #t) - ) - ) - ((cpad-pressed? 0 triangle) - (when (!= (-> obj display-state) (progress-screen buzzer)) - (sound-play-by-name (static-sound-name "select-option") (new-sound-id) 1024 0 0 1 #t) - (set! (-> obj next-display-state) (progress-screen buzzer)) - (set! (-> obj stat-transition) #t) - ) - ) - ((cpad-pressed? 0 circle) - (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons circle)) - (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons circle)) - (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) - (push! obj) - (set! (-> obj next-display-state) (progress-screen settings)) - ) - ((= (-> obj display-state) (progress-screen fuel-cell)) - (cond - ((cpad-pressed? 0 left) - (let ((s5-8 (-> obj task-index))) - (set! (-> obj task-index) (get-next-task-down (-> obj task-index) (-> obj display-level-index))) - (if (!= s5-8 (-> obj task-index)) - (sound-play-by-name (static-sound-name "cursor-l-r") (new-sound-id) 1024 0 0 1 #t) - ) - ) - ) - ((cpad-pressed? 0 right) - (let ((s5-10 (-> obj task-index))) - (set! (-> obj task-index) (get-next-task-up (-> obj task-index) (-> obj display-level-index))) - (if (!= s5-10 (-> obj task-index)) - (sound-play-by-name (static-sound-name "cursor-l-r") (new-sound-id) 1024 0 0 1 #t) - ) - ) - ) - ) - ) - ) - ) - 0 - (none) - ) - -(defstate progress-normal (progress) - :event - (behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) - (local-vars (v0-0 none)) - (let ((v1-0 arg2)) - (the-as object (cond - ((= v1-0 'go-away) - (go progress-going-out) - ) - ((= v1-0 'notify) - (cond - ((= (-> arg3 param 0) 'done) - (case (-> self display-state) - (((progress-screen memcard-saving)) - (cond - ((= (-> self display-state-stack 0) (progress-screen title)) - (let ((gp-1 (-> *setting-control* default auto-save))) - (sound-volume-off) - (set! (-> *game-info* mode) 'play) - (initialize! *game-info* 'game (the-as game-save #f) "intro-start") - (set! (-> *setting-control* default auto-save) gp-1) - ) - (set-master-mode 'game) - ) - (else - (set! v0-0 (the-as none -1)) - (set! (-> self next-display-state) (the-as progress-screen v0-0)) - v0-0 - ) - ) - ) - (((progress-screen memcard-formatting)) - (set! (-> self force-transition) #t) - (set! v0-0 (the-as none 15)) - (set! (-> self next-display-state) (the-as progress-screen v0-0)) - v0-0 - ) - (((progress-screen memcard-creating)) - (cond - ((= (-> self display-state-stack 0) (progress-screen title)) - (set! v0-0 (the-as none 18)) - (set! (-> self next-display-state) (the-as progress-screen v0-0)) - ) - (else - (set! v0-0 (the-as none 17)) - (set! (-> self next-display-state) (the-as progress-screen v0-0)) - ) - ) - v0-0 - ) - ) - ) - ((= (-> arg3 param 0) 'error) - (let ((t9-4 format) - (a0-17 #t) - (a1-2 "ERROR NOTIFY: ~S ~D~%") - (v1-13 (-> arg3 param 1)) - ) - (t9-4 - a0-17 - a1-2 - (cond - ((= v1-13 17) - "no-auto-save" - ) - ((= v1-13 16) - "no-process" - ) - ((= v1-13 15) - "bad-version" - ) - ((= v1-13 14) - "no-space" - ) - ((= v1-13 13) - "no-save" - ) - ((= v1-13 12) - "no-file" - ) - ((= v1-13 11) - "no-format" - ) - ((= v1-13 10) - "no-last" - ) - ((= v1-13 9) - "no-card" - ) - ((= v1-13 8) - "no-memory" - ) - ((= v1-13 7) - "new-game" - ) - ((= v1-13 6) - "read-error" - ) - ((= v1-13 5) - "write-error" - ) - ((= v1-13 4) - "internal-error" - ) - ((= v1-13 3) - "format-failed" - ) - ((= v1-13 2) - "bad-handle" - ) - ((= v1-13 1) - "ok" - ) - ((zero? v1-13) - "busy" - ) - (else - "*unknown*" - ) - ) - (-> self display-state) - ) - ) - (case (-> arg3 param 1) - ((14) - (set! v0-0 (the-as none 7)) - (set! (-> self next-display-state) (the-as progress-screen v0-0)) - v0-0 - ) - (else - (case (-> self display-state) - (((progress-screen memcard-formatting)) - (set! v0-0 (the-as none 24)) - (set! (-> self next-display-state) (the-as progress-screen v0-0)) - v0-0 - ) - (((progress-screen memcard-creating)) - (set! v0-0 (the-as none 25)) - (set! (-> self next-display-state) (the-as progress-screen v0-0)) - v0-0 - ) - (((progress-screen memcard-saving)) - (set! v0-0 (the-as none 21)) - (set! (-> self next-display-state) (the-as progress-screen v0-0)) - v0-0 - ) - (((progress-screen memcard-loading)) - (set! v0-0 (the-as none 20)) - (set! (-> self next-display-state) (the-as progress-screen v0-0)) - v0-0 - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - :code - (behavior () - (loop - (when (and (cpad-hold? 0 l1) (cpad-hold? 0 r1) *cheat-mode*) - (when (and (< (-> self task-index) (-> *level-task-data* (-> self display-level-index) nb-of-tasks)) - (>= (-> self task-index) 0) - ) - (let ((gp-0 (-> *level-task-data* (-> self display-level-index) task-info (-> self task-index) task-id))) - (close-specific-task! gp-0 (task-status need-resolution)) - (send-event *target* 'get-pickup 6 (the float gp-0)) - ) - ) - ) - (if (and (= (-> self display-state) (-> self next-display-state)) - (= (-> self display-level-index) (-> self next-level-index)) - ) - (set! (-> self transition-offset) - (seekl - (-> self transition-offset) - 0 - (* (the int (* (-> self transition-speed) (-> *display* time-adjust-ratio))) - (if (or (-> self stat-transition) (nonzero? (-> self level-transition))) - 2 - 1 - ) - ) - ) - ) - (set! (-> self transition-offset) - (seekl - (-> self transition-offset) - 512 - (* (the int (* (-> self transition-speed) (-> *display* time-adjust-ratio))) - (if (or (-> self stat-transition) (nonzero? (-> self level-transition))) - 2 - 1 - ) - ) - ) - ) - ) - (set-transition-progress! self (-> self transition-offset)) - (set! (-> self in-transition) (or (-> self force-transition) (nonzero? (-> self transition-offset)))) - (when (and (not (handle->process (-> *game-info* auto-save-proc))) - (or (-> self force-transition) (-> self in-transition)) - (>= (-> self transition-offset) (if (and (zero? (-> self level-transition)) - (nonzero? (-> self next-display-state)) - (!= (-> self next-display-state) 1) - (!= (-> self next-display-state) 2) - ) - 512 - 256 - ) - ) - ) - (if (>= (the-as int (-> self next-display-state)) 0) - ;; transition to the next menu - (enter! self (-> self next-display-state) 0) - (pop! self) - ) - (set! (-> self display-level-index) (-> self next-level-index)) - (when (nonzero? (-> self level-transition)) - (set! (-> self task-index) (get-next-task-up -1 (-> self display-level-index))) - (case (-> self level-transition) - ((1) - (set! (-> self level-transition) 2) - ) - ((2) - (set! (-> self level-transition) 1) - ) - ) - ) - (set! (-> self force-transition) #f) - ) - (when (zero? (-> self transition-offset)) - (set! (-> self stat-transition) #f) - (set! (-> self level-transition) 0) - 0 - ) - (let ((gp-1 #f)) - (let ((v1-62 #f)) - (case (-> self display-state) - (((progress-screen fuel-cell) (progress-screen money) (progress-screen buzzer)) - (let ((s5-0 (-> self display-level-index))) - (when (and (< (mod (-> *display* real-frame-counter) 60) 30) - (zero? (-> *progress-process* 0 in-out-position)) - (not (-> self in-transition)) - (zero? (-> self transition-offset)) - ) - (set! gp-1 (!= s5-0 (get-next-level-up s5-0))) - (set! v1-62 (!= s5-0 (get-next-level-down s5-0))) - ) - ) - ) - ) - (set! (-> self particles 3 init-pos x) (the float (if v1-62 - (- 195 (-> *progress-process* 0 left-x-offset)) - -320 - ) - ) - ) - ) - (set! (-> self particles 4 init-pos x) (the float (if gp-1 - (- 195 (-> *progress-process* 0 left-x-offset)) - -320 - ) - ) - ) - ) - (dummy-29 self) - (set! (-> self next-display-state) - (dummy-53 self (-> self next-display-state))) - (let ((v1-74 (-> self display-state))) - (cond - ((or (= v1-74 (progress-screen fuel-cell)) - (or (= v1-74 (progress-screen money)) (= v1-74 (progress-screen buzzer))) - ) - (respond-progress self) - ) - ((or (= v1-74 (progress-screen memcard-no-space)) - (= v1-74 (progress-screen memcard-format)) - (= v1-74 (progress-screen memcard-data-exists)) - (= v1-74 (progress-screen memcard-insert)) - (= v1-74 (progress-screen load-game)) - (= v1-74 (progress-screen save-game)) - (= v1-74 (progress-screen save-game-title)) - (= v1-74 (progress-screen memcard-error-loading)) - (= v1-74 (progress-screen memcard-error-saving)) - (= v1-74 (progress-screen memcard-error-formatting)) - (= v1-74 (progress-screen memcard-error-creating)) - (= v1-74 (progress-screen memcard-auto-save-error)) - (= v1-74 (progress-screen memcard-removed)) - (= v1-74 (progress-screen memcard-no-data)) - (= v1-74 (progress-screen memcard-not-inserted)) - (= v1-74 (progress-screen memcard-not-formatted)) - (= v1-74 (progress-screen auto-save)) - (= v1-74 (progress-screen pal-change-to-60hz)) - (= v1-74 (progress-screen pal-now-60hz)) - (= v1-74 (progress-screen no-disc)) - (= v1-74 (progress-screen bad-disc)) - (= v1-74 (progress-screen quit)) - ) - (dummy-31 self) - ) - ) - ) - (suspend) - ) - (none) - ) - :post - (behavior () - (let* ((a1-0 (-> self display-level-index)) - (gp-0 (-> *level-task-data* a1-0)) - ) - #t - (let ((s5-0 #f)) - (case (-> self display-state) - (((progress-screen fuel-cell)) - (set! s5-0 #t) - (draw-fuel-cell-screen self a1-0) - ) - (((progress-screen money)) - (set! s5-0 #t) - (draw-money-screen self a1-0) - ) - (((progress-screen buzzer)) - (set! s5-0 #t) - (draw-buzzer-screen self a1-0) - ) - (((progress-screen game-settings) (progress-screen settings)) - (hide-progress-icons) - (draw-options self 115 30 0.82) - ) - (((progress-screen graphic-settings) - (progress-screen sound-settings) - (progress-screen settings-title) - (progress-screen title) - (progress-screen language-options) - ) - (hide-progress-icons) - (draw-options self 115 30 0.82) - ) - (((progress-screen memcard-removed) (progress-screen memcard-auto-save-error)) - (draw-notice-screen self) - (draw-options self 192 0 0.82) - ) - (((progress-screen memcard-no-data)) - (draw-notice-screen self) - (draw-options self 165 0 0.82) - ) - (((progress-screen memcard-format)) - (draw-notice-screen self) - (draw-options self 172 0 0.82) - ) - (((progress-screen memcard-no-space) - (progress-screen memcard-not-inserted) - (progress-screen memcard-not-formatted) - ) - (draw-notice-screen self) - (draw-options self 195 0 0.82) - ) - (((progress-screen memcard-error-loading) - (progress-screen memcard-error-saving) - (progress-screen memcard-error-formatting) - (progress-screen memcard-error-creating) - (progress-screen memcard-auto-save-error) - ) - (draw-notice-screen self) - (draw-options self 190 0 0.82) - ) - (((progress-screen pal-change-to-60hz)) - (draw-notice-screen self) - (draw-options self 190 0 0.82) - ) - (((progress-screen pal-now-60hz)) - (when (< (seconds 10) (- (-> *display* real-frame-counter) (-> self video-mode-timeout))) - (set! (-> *progress-state* video-mode-choice) 'pal) - (set! (-> *setting-control* default video-mode) (-> *progress-state* video-mode-choice)) - (set! (-> self next-display-state) (progress-screen invalid)) - ) - (draw-notice-screen self) - (draw-options self 140 0 0.82) - ) - (((progress-screen no-disc) (progress-screen bad-disc)) - (draw-notice-screen self) - (if (is-cd-in?) - (draw-options self 170 0 0.82) - ) - ) - (((progress-screen quit)) - (draw-notice-screen self) - (draw-options self 110 0 0.82) - ) - (((progress-screen auto-save)) - (draw-notice-screen self) - (draw-options self 190 0 0.82) - ) - (((progress-screen memcard-insert)) - (draw-notice-screen self) - (draw-options self 165 0 0.82) - ) - (((progress-screen memcard-data-exists)) - (draw-notice-screen self) - (draw-options self 168 0 0.82) - ) - (((progress-screen memcard-loading) - (progress-screen memcard-saving) - (progress-screen memcard-formatting) - (progress-screen memcard-creating) - ) - (draw-notice-screen self) - ) - (((progress-screen load-game) (progress-screen save-game)) - (draw-notice-screen self) - (draw-options self 190 0 0.82) - ) - (((progress-screen save-game-title)) - (draw-notice-screen self) - (draw-options self 169 15 0.6) - ) - ) - (when s5-0 - (let* ((v1-98 (cond - ((-> self stat-transition) - 0 - ) - ((= (-> self level-transition) 1) - (- (-> self transition-offset)) - ) - (else - (-> self transition-offset) - ) - ) - ) - (f30-0 (the-as float (if (-> self stat-transition) - 1.0 - (-> self transition-percentage-invert) - ) - ) - ) - (s5-1 - (new - 'stack - 'font-context - *font-default-matrix* - (- 32 (-> self left-x-offset)) - (the int (* (+ 42.0 (the float (/ v1-98 2))) f30-0)) - 8325000.0 - (font-color lighter-lighter-blue) - (font-flags shadow kerning) - ) - ) - ) - (let ((v1-103 s5-1)) - (set! (-> v1-103 width) (the float 328)) - ) - (let ((v1-104 s5-1)) - (set! (-> v1-104 height) (the float 45)) - ) - (set! (-> s5-1 flags) (font-flags shadow kerning middle left large)) - (print-game-text-scaled - (lookup-text! *common-text* (-> gp-0 level-name-id) #f) - f30-0 - s5-1 - (the int (* 128.0 f30-0)) - ) - ) - ) - ) - ) - (case (-> self display-state) - (((progress-screen fuel-cell) (progress-screen money) (progress-screen buzzer)) - (draw-progress self) - ) - ) - (adjust-sprites self) - (adjust-icons self) - (none) - ) - ) - -(defstate progress-coming-in (progress) - :event - (-> progress-waiting event) - :enter - (behavior () - (sound-group-pause (the-as uint 255)) - (logclear! (-> *setting-control* default process-mask) (process-mask pause menu)) - (push-setting! *setting-control* self 'process-mask 'set 0.0 16) - (copy-settings-from-target! *setting-control*) - (sound-play-by-name (static-sound-name "select-menu") (new-sound-id) 1024 0 0 1 #t) - (set-blackout-frames 0) - (set! *pause-lock* #f) - (none) - ) - :code - (behavior () - (loop - (set! (-> self in-out-position) - (seekl (-> self in-out-position) 0 (the int (* 170.0 (-> *display* time-adjust-ratio)))) - ) - (when (< (-> self in-out-position) 2867) - (set! (-> self transition-offset) (seekl - (-> self transition-offset) - 0 - (the int (* (-> self transition-speed) (-> *display* time-adjust-ratio))) - ) - ) - (set-transition-progress! self (-> self transition-offset)) - ) - (if (zero? (-> self in-out-position)) - (go progress-normal) - ) - (suspend) - ) - (none) - ) - :post - (-> progress-normal post) - ) - -(defstate progress-going-out (progress) - :enter - (behavior () - (sound-play-by-name (static-sound-name "menu-close") (new-sound-id) 1024 0 0 1 #t) - (hide-progress-icons) - (set! (-> self particles 3 init-pos x) -320.0) - (set! (-> self particles 4 init-pos x) -320.0) - (case (-> self display-state) - (((progress-screen load-game) (progress-screen save-game) (progress-screen save-game-title)) - (set! (-> self transition-speed) 30.0) - ) - ) - (none) - ) - :code - (behavior () - (loop - (set! (-> self transition-offset) (seekl - (-> self transition-offset) - 512 - (the int (* (-> self transition-speed) (-> *display* time-adjust-ratio))) - ) - ) - (set-transition-progress! self (-> self transition-offset)) - (when (< 153 (-> self transition-offset)) - (set! (-> self in-out-position) - (seekl (-> self in-out-position) 4096 (the int (* 170.0 (-> *display* time-adjust-ratio)))) - ) - (if (= (-> self in-out-position) 4096) - (go progress-gone) - ) - ) - (suspend) - ) - (none) - ) - :post - (-> progress-normal post) - ) - -(defstate progress-debug (progress) - :event - (behavior ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block)) - (case arg2 - (('go-away) - (go progress-going-out) - ) - ) - ) - :code - (behavior () - (loop - (cond - ((cpad-pressed? 0 left) - (if (> (-> self current-debug-string) 0) - (+! (-> self current-debug-string) -1) - ) - ) - ((cpad-pressed? 0 right) - (if (< (-> self current-debug-string) (+ (-> *common-text* length) -1)) - (+! (-> self current-debug-string) 1) - ) - ) - ((cpad-pressed? 0 up) - (when (> (-> self current-debug-group) 0) - (+! (-> self current-debug-group) -1) - (set! (-> self current-debug-string) 0) - 0 - ) - ) - ((cpad-pressed? 0 down) - (when (< (-> self current-debug-group) (+ (-> *text-group-names* length) -1)) - (+! (-> self current-debug-group) 1) - (set! (-> self current-debug-string) 0) - 0 - ) - ) - ((cpad-pressed? 0 l1) - (if (> (the-as int (-> *setting-control* default language)) 0) - (+! (-> *setting-control* default language) -1) - ) - ) - ((cpad-pressed? 0 r1) - (if (< (the-as int (-> *setting-control* default language)) 6) - (+! (-> *setting-control* default language) 1) - ) - ) - ((cpad-pressed? 0 l2) - (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons l2)) - (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons l2)) - (go progress-normal) - ) - ) - (load-game-text-info (-> *text-group-names* (-> self current-debug-group)) '*common-text* *common-text-heap*) - (suspend) - ) - (none) - ) - :post - (behavior () - (let* ((s5-0 (-> *display* frames (-> *display* on-screen) frame global-buf)) - (gp-0 (-> s5-0 base)) - ) - (let ((s4-0 draw-string-xy)) - (let ((s3-0 format) - (a0-4 (clear *temp-string*)) - (a1-0 "TEXT DEBUG: LANGUAGE ~S ID 0x~X") - (v1-4 (-> *setting-control* current language)) - ) - (s3-0 - a0-4 - a1-0 - (cond - ((= v1-4 (language-enum uk-english)) - "uk-english" - ) - ((= v1-4 (language-enum japanese)) - "japanese" - ) - ((= v1-4 (language-enum italian)) - "italian" - ) - ((= v1-4 (language-enum spanish)) - "spanish" - ) - ((= v1-4 (language-enum german)) - "german" - ) - ((= v1-4 (language-enum french)) - "french" - ) - ((= v1-4 (language-enum english)) - "english" - ) - (else - "*unknown*" - ) - ) - (-> *common-text* data (-> self current-debug-string) id) - ) - ) - (s4-0 *temp-string* s5-0 40 40 (font-color default) (font-flags shadow kerning)) - ) - (let ((a3-4 (-> s5-0 base))) - (let ((v1-7 (the-as dma-packet (-> s5-0 base)))) - (set! (-> v1-7 dma) (new 'static 'dma-tag :id (dma-tag-id next))) - (set! (-> v1-7 vif0) (new 'static 'vif-tag)) - (set! (-> v1-7 vif1) (new 'static 'vif-tag)) - (set! (-> s5-0 base) (&+ (the-as pointer v1-7) 16)) - ) - (dma-bucket-insert-tag - (-> *display* frames (-> *display* on-screen) frame bucket-group) - (bucket-id debug-draw0) - gp-0 - (the-as (pointer dma-tag) a3-4) - ) - ) - ) - (let* ((s5-1 (-> *display* frames (-> *display* on-screen) frame global-buf)) - (gp-1 (-> s5-1 base)) - ) - (let ((s4-1 draw-string-xy)) - (format (clear *temp-string*) "USE LEFT/RIGHT TO SELECT STRING") - (s4-1 *temp-string* s5-1 40 155 (font-color default) (font-flags shadow kerning)) - ) - (let ((a3-6 (-> s5-1 base))) - (let ((v1-16 (the-as dma-packet (-> s5-1 base)))) - (set! (-> v1-16 dma) (new 'static 'dma-tag :id (dma-tag-id next))) - (set! (-> v1-16 vif0) (new 'static 'vif-tag)) - (set! (-> v1-16 vif1) (new 'static 'vif-tag)) - (set! (-> s5-1 base) (the-as pointer (the-as dma-packet (&+ v1-16 16)))) - ) - (dma-bucket-insert-tag - (-> *display* frames (-> *display* on-screen) frame bucket-group) - (bucket-id debug-draw0) - gp-1 - (the-as (pointer dma-tag) a3-6) - ) - ) - ) - (let* ((s5-2 (-> *display* frames (-> *display* on-screen) frame global-buf)) - (gp-2 (-> s5-2 base)) - ) - (let ((s4-2 draw-string-xy)) - (format (clear *temp-string*) "USE UP/DOWN TO SELECT GROUP") - (s4-2 *temp-string* s5-2 40 165 (font-color default) (font-flags shadow kerning)) - ) - (let ((a3-8 (-> s5-2 base))) - (let ((v1-25 (the-as dma-packet (-> s5-2 base)))) - (set! (-> v1-25 dma) (new 'static 'dma-tag :id (dma-tag-id next))) - (set! (-> v1-25 vif0) (new 'static 'vif-tag)) - (set! (-> v1-25 vif1) (new 'static 'vif-tag)) - (set! (-> s5-2 base) (the-as pointer (the-as dma-packet (&+ v1-25 16)))) - ) - (dma-bucket-insert-tag - (-> *display* frames (-> *display* on-screen) frame bucket-group) - (bucket-id debug-draw0) - gp-2 - (the-as (pointer dma-tag) a3-8) - ) - ) - ) - (let* ((s5-3 (-> *display* frames (-> *display* on-screen) frame global-buf)) - (gp-3 (-> s5-3 base)) - ) - (let ((s4-3 draw-string-xy)) - (format (clear *temp-string*) "USE L1/R1 TO SELECT LANGUAGE") - (s4-3 *temp-string* s5-3 40 175 (font-color default) (font-flags shadow kerning)) - ) - (let ((a3-10 (-> s5-3 base))) - (let ((v1-34 (the-as dma-packet (-> s5-3 base)))) - (set! (-> v1-34 dma) (new 'static 'dma-tag :id (dma-tag-id next))) - (set! (-> v1-34 vif0) (new 'static 'vif-tag)) - (set! (-> v1-34 vif1) (new 'static 'vif-tag)) - (set! (-> s5-3 base) (the-as pointer (the-as dma-packet (&+ v1-34 16)))) - ) - (dma-bucket-insert-tag - (-> *display* frames (-> *display* on-screen) frame bucket-group) - (bucket-id debug-draw0) - gp-3 - (the-as (pointer dma-tag) a3-10) - ) - ) - ) - (let ((gp-4 (new - 'stack - 'font-context - *font-default-matrix* - 32 - 50 - 0.0 - (font-color default) - (font-flags shadow kerning) - ) - ) - ) - (let ((v1-42 gp-4)) - (set! (-> v1-42 width) (the float 328)) - ) - (let ((v1-43 gp-4)) - (set! (-> v1-43 height) (the float 100)) - ) - (logior! (-> gp-4 flags) (font-flags shadow kerning large)) - (draw-debug-text-box gp-4) - (print-game-text (-> *common-text* data (-> self current-debug-string) text) gp-4 #f 128 22) - ) - (none) - ) - ) - - diff --git a/goal_src/pc/engine/ui/text-h.gc b/goal_src/pc/engine/ui/text-h.gc deleted file mode 100644 index 753b58b036..0000000000 --- a/goal_src/pc/engine/ui/text-h.gc +++ /dev/null @@ -1,562 +0,0 @@ -;;-*-Lisp-*- -(in-package goal) - -;; name: text-h.gc -;; name in dgo: text-h -;; dgos: GAME, ENGINE - -;; This file contains types related to game text. -;; Each game string is assigned an ID number. -;; This ID is used to lookup the string for the currently selected language. -;; These ID's are shared with short spoken audio clips (daxter hints) -;; most (all?) of the daxter clips don't have text strings. - -(defenum game-text-id - :type uint32 - :bitfield #f -;; GAME-TEXT-ID ENUM BEGINS - (zero 0) - (one 1) - (confirm #x103) - (press-to-talk #x104) - (press-to-use #x105) - (confirm-play #x106) - (play-again? #x107) - (quit #x108) - (pause #x109) - (sfx-volume #x10a) - (music-volume #x10b) - (speech-volume #x10c) - (language #x10d) - (vibrations #x10e) - (play-hints #x10f) - (center-screen #x110) - (on #x111) - (off #x112) - (move-dpad #x113) - (english #x114) - (french #x115) - (german #x116) - (spanish #x117) - (italian #x118) - (japanese #x119) - (press-to-trade-money #x11a) - (press-to-trade-money-oracle #x11b) - (press-to-warp #x11c) - (press-to-exit #x11d) - (press-to-talk-to-sage #x123) - (press-to-talk-to-assistant #x124) - (aspect-ratio #x125) - (video-mode #x126) - (game-options #x127) - (graphic-options #x128) - (sound-options #x129) - (4x3 #x12a) - (16x9 #x12b) - (60hz #x12c) - (50hz #x12d) - (game-title #x12e) - (hidden-power-cell #x12f) ;; why is this here?? - (memcard-no-space #x130) - (memcard-not-inserted #x131) - (card-not-formatted-title #x132) - (memcard-space-requirement1 #x133) - (memcard-space-requirement2 #x134) - (card-not-formatted-msg #x135) - (saving-data #x136) - (loading-data #x137) - (do-not-remove-mem-card #x138) - (overwrite? #x139) - (format? #x13a) - - (yes #x13c) - (no #x13d) - (back #x13e) - (continue-without-saving #x13f) - (select-file-to-save #x140) - (select-file-to-load #x141) - (save-data-already-exists #x142) - (insert-memcard #x143) - (continue? #x144) - (load-game #x14b) - (save-game #x14c) - (formatting #x14d) - (creating-save-data #x14e) - (empty #x14f) - (options #x150) - (error-loading #x151) - (error-saving #x152) - (error-formatting #x153) - (error-creating-data #x154) - (memcard-removed #x156) - (autosave-disabled-title #x157) - (autosave-disabled-msg #x158) - (no-save-data #x159) - (create-save-data? #x15a) - (check-memcard #x15b) - (new-game #x15c) - (back? #x15d) - (ok #x15e) - (exit-demo #x15f) - (autosave-warn-title #x160) - (autosave-warn-msg #x161) - (task-completed #x162) - (check-memcard-and-retry #x163) - (screen-change-to-60hz #x164) - (screen-60hz-warn-support #x165) - (screen-60hz-warn-timer #x166) - (screen-now-60hz #x167) - (screen-60hz-keep? #x168) - (warp-gate-use-dpad #x169) - (no-disc-title #x16a) - (no-disc-msg #x16b) - (bad-disc-title #x16c) - (bad-disc-msg #x16d) - (press-start #x16e) - (quit-game #x16f) - (quit? #x170) - (total-collected #x171) - - (village1-mayor-money #x200) - (vollage1-uncle-money #x201) - (village1-yakow-herd #x202) - (village1-yakow-return #x203) - (village1-oracle #x204) - (beach-ecorocks #x205) - (beach-flutflut-push #x206) - (beach-flutflut-meet #x207) - (beach-pelican #x208) - (beach-seagull #x209) - (beach-cannon #x20a) - (beach-buzzer #x20b) - (jungle-lurkerm-connect #x20c) - (jungle-tower #x20d) - (jungle-eggtop #x20e) - (jungle-plant #x20f) - (jungle-fishgame #x210) - (misty-muse-catch #x211) - (misty-muse-return #x212) - (misty-boat #x213) - (misty-cannon #x214) - (misty-return-to-pool #x215) ;; task name?? - (misty-find-transpad #x216) ;; task name? - (misty-balloon-lurkers #x217) - - (village1-level-name #x220) - (beach-level-name #x221) - (jungle-level-name #x222) - (misty-level-name #x223) - - (beach-seagull-get #x22e) - - (jungle-lurkerm-unblock #x22f) - (jungle-lurkerm-return #x230) - - (MISSING-orb-hint #x233) - - (beach-eco-rock-increment #x239) - - (jungle-maindoor-hint #x23c) - - (firecanyon-not-enough-cells #x24f) - - (sidekick-hint-orb-cache-top #x251) - - (jungle-precursorbridge-hint #x25b) - (daxter-launcher-no-eco #x25c) - - (jungle-mirrors-completion-talk-to-mayor #x25e) - - (beach-gimmie #x262) - (beach-sentinel #x263) - (jungle-canyon-end #x264) - (jungle-temple-door #x265) - (misty-bike-jump #x266) - (misty-eco-challenge #x267) - (beach-seagull-chased-one #x268) - (beach-seagull-chased-two #x26a) - (beach-seagull-chased-three #x26b) - (beach-seagull-chased-four #x26c) - - (misty-daxter-scared #x26f) - - (beach-seagulls-avalanche #x273) - - (beach-pelican-quick-get-cell #x274) - - (beach-flutflutegg-hint #x275) - - (sidekick-hint-fish-powerup #x278) - (misty-racer-hit-the-ballon-lurkers #x27e) - (misty-daxter-hit-lurkers-not-mines #x27f) - - (sidekick-speech-hint-crate-darkeco1 #x281) - (sidekick-speech-crate-steel-break1 #x283) - (sidekick-speech-hint-crate-iron #x284) - (sidekick-speech-hint-crate-steel #x285) - (beach-collectors-unblocked #x288) - (misty-stopped-lurkers-at-silo #x28a) - (misty-stopped-balloon-lurkers #x28b) - (jungleb-eco-vents-opened #x289) - (sidekick-speech-crate-steel-break2 #x28e) - (sidekick-speech-hint-crate-darkeco2 #x28f) - - (daxter-screaming-jump #x290) - (daxter-wahoo-jump #x291) - (daxter-get-some #x292) - - (collectables-scout-flies-red-boxes #x295) - (found-all-scout-flies #x296) - (yakow-owed-powercell #x297) - - (jungle-mirrors-tutorial #x29c) - (jungle-mirrors-break-the-mirror-jak #x29d) - (jungle-mirrors-go-to-the-next-tower #x29f) - (jungle-mirrors-follow-the-beam #x2a0) - - (misty-teetertotter-bonk-dax-tutorial #x2a4) - (sidekick-hint-misty-get-red-eco #x2a5) - - (red-eco-tutorial #x2a6) - - (daxter-blue-eco-plat-tutorial #x2a7) - - (fish? #x2a9) - - (misty-bone-bridge-hint #x2aa) - - (beach-grottopole-increment #x2af) - - (firecanyon-collect-cells-collected #x2b1) - (firecanyon-collect-cells-collected-reminder #x2b2) - (firecanyon-collect-cells-text #x2b3) - (caught #x2b4) - (missed #x2b5) - (lose! #x2b6) - - (village2-gambler-money #x300) - (village2-geologist-money #x301) - (village2-warrior-money #x302) - (village2-oracle-money #x303) - (swamp-tether #x304) - - (swamp-flutflut #x307) - - (swamp-billy #x309) - - (sunken-elevator-raise #x30a) - (sunken-elevator-get-to-roof #x30b) - (sunken-pipe #x30c) - (sunken-climb-tube #x30d) ;; task name? - (sunken-pool #x30e) ;; task name? - (sunken-platforms #x30f) - - (rolling-moles #x310) - (rolling-moles-return #x311) - (rolling-robbers #x312) - (rolling-race #x313) - (rolling-race-return #x314) - (rolling-lake #x315) - (rolling-plants #x316) - - (unknown-buzzers #x317) - - (village2-level-name #x319) - - (rolling-level-name #x31b) - (swamp-level-name #x31c) - (sunken-level-name #x31d) - (ogre-level-name #x31e) - - (swamp-battle #x321) - (sunken-bottom #x322) ;; task name? - (reach-center #x323) ;; task name? - (rolling-ring-chase-1 #x324) - (rolling-ring-chase-2 #x325) - (sunken-kiera-you-raised-a-piece-of-lpc #x326) - (rolling-beat-lurkers #x327) - (swamp-finished-with-flutflut #x328) - (rolling-race-beat-record #x335) - (sidekick-speech-hint-rolling-crate-darkeco #x336) - (rolling-lightning-moles-completion #x338) - (rolling-dark-plants-location-hint #x339) - (rolling-dark-plants-hint #x33a) - (rolling-flying-lurker-intro #x33c) - (rolling-ring-hint-one-ring-down #x33f) - (rolling-ring-hint-be-quick-to-next #x340) - (rolling-ring-hint-be-quick-all #x341) - - (sunken-pipegame-follow-it #x343) - (sunken-helix-daxter-bad-feeling #x344) - (sunken-blue-eco-charger-hint #x345) - (sunken-double-lurker-hint #x347) - (sunken-helix-daxter-eco-rising #x348) - (sunken-qbert-plat-hint #x34a) - (sunken-bully-dive-hint #x34b) - (sunken-take-it-easy-hot-pipes #x34e) - - (sunken-blue-eco-charger-all-hint #x34d) - - (swamp-tethers-advice-hint #x352) - - (kermit-break-tongue #x357) - (swamp-rats-nest-hint #x358) - (daxter-you-can-shoot-with-yellow-eco #x359) - - (kermit-run-away-jak #x35f) - - (swamp-bats-hint #x364) ;; maybe we can duck the bats - (swamp-tethers-three-to-go #x365) - (swamp-tethers-two-to-go #x366) - (swamp-tethers-lefts-find-the-last #x367) - (flutflut-reminder #x368) - - (sage-golfclap-i-have-low-expectations #x36a) ;; where was this said? - - (swamp-tethers-completion-sage-precursor-arm #x36b) - - (village2-warp-gate-reminder #x36f) - (village2-warp-gate-reminder-annoyed #x370) - (village2-warp-gate-reminder-very-annoyed #x371) - - (village2-not-enough-cells-levitator #x36c) - (villlage2-levitator-cell-req-text #x372) - - (rolling-race-time-string-prefix #x373) - (rolling-race-record-string-prefix #x374) - (rolling-race-new-record-string-prefix #x375) - (rolling-race-try-again-string #x376) - (rolling-race-start-race-aborted #x377) ;; double check this - - (village3-miner-money #x400) - (village3-oracle-money #x401) - (snow-ram-3-left #x402) - (snow-ram-2-left #x403) - (snow-ram-1-left #x404) - (snow-fort #x405) - (snow-bunnies #x406) - (snow-open-door #x408) ;; task name? - - (cave-robot-climb #x40e) - (cave-dark-climb #x40f) ;; destroy crystals - - (cave-gnawers #x410) - (cave-dark-crystals #x411) - - (village3-buzzer #x413) - - (village3-level-name #x415) - - (snowy-level-name #x417) - - (cave-level-name #x419) - - (lavatube-level-name #x41b) - - (snow-eggtop #x421) - - (cave-spider-tunnel #x423) - (cave-platforms #x424) - - (cave-swing-poles #x426) - - (assistant-lavatube-powercell-hint #x428) - (village3-gondola-malfunctioning #x429) - (village3-gondola-reactivated #x42a) - - (snow-frozen-crate #x42b) ;; task name? - (snow-bumpers #x42c) - - (dark-crystal-last-one #x432) - (daxter-maybe-you-can-shoot-better-goggles #x433) - - (darkcave-light-crystal-low-light-hint #x437) - (darkcave-light-crystal-hint #x438) - (dark-crystal-run-away #x439) - (cave-trap-nest-hint #x440) - (snow-fort-reminder #x443) - (ram-boss-red-eco-hint #x444) - - (ice-cube-hint #x448) - - (snowy-turned-on-yellow-vents #x44c) - - (village3-warp-gate-reminder #x452) - (village3-warp-gate-reminder=annoyed #x453) - (village3-warp-gate-reminder-very-annoyed #x454) - (lavatube-powercell-req-text #x455) - - (fire-canyon-end #x500) - (fire-canyon-buzzer #x501) - - (daxter-maybe-i-should-drive #x506) - (daxter-you-are-trying-to-avoid-dark-eco #x507) - - (fire-canyon-level-name #x50c) - - (fire-canyon-we-made-it #x515) - - (collectables-theres-scout-flys-here-too #x516) - - (ogre-end #x600) - (ogre-buzzer #x601) - (ogre-boss #x603) - (ogre-boss-killed #x604) - - (assistant-voicebox-intro-ogre-race #x605) - - (sidekick-speech-hint-ogre-race #x61c) - (assistant-finished-mountain-pass-race #x61d) - - (lavatube-end #x700) - (lavatube-buzzer #x701) - - (lavatube-shoot-the-spheres #x70d) - - (lavatube-spheres-door-open #x710) - - (citadel-buzzer #x800) - (citadel-level-name #x801) - (citadel-sage-blue #x802) - (citadel-sage-red #x803) - (citadel-sage-yellow #x804) - (citadel-sage-green #x805) - (citadel-break-generator-hint #x806) - (citadel-lurker-bunny-alert #x808) - (citadel-break-generators-reminder #x809) - (citadel-climb-plat-hint #x80c) - - (daxter-dont-miss-the-next-launcher #x80d) - - (daxter-land-on-the-next-launcher #x812) - (misty-battle-finished #x813) - - (training-precursor-orbs #x901) - (training-power-cells #x902) - (training-assistant-found-scout-fly #x903) - (training-assistant-found-scout-fly-cell #x904) - (training-blue-eco-vent #x907) - (training-eco-green #x908) - (training-eco-blue #x909) - (training-more-eco-more-time #x90a) - (training-precursor-door #x90b) - (training-eco-opened-door #x90c) - (training-double-jump #x90e) - - (sage-voicebox-hint-crate-iron #x917) - (training-warp-gate-blocked #x919) - (training-warp-gate-reminder #x91a) - - (training-gimmie-task-name #x91b) - (training-buzzer-task-name #x91c) - (training-door-task-name #x91d) - (training-climb-task-name #x91e) - (training-level-name #x91f) - - (inc #xf10) - (europe #xf11) -;; GAME-TEXT-ID ENUM ENDS - - ; PC Port TEXT - (progress-resolution #x1000) - (progress-display-mode #x1001) - (progress-letterbox #x1002) - (progress-subtitles #x1003) - (progress-subtitles-label-speaker #x1004) - (progress-discord-rpc #x1005) - (progress-language-options #x1006) - ;; subtitle languages - (progress-subtitles-language #x1007) - (progress-subtitle-language-uk-english #x1008) - (progress-subtitle-language-portuguese #x1009) - (progress-subtitle-language-finnish #x1010) - (progress-subtitle-language-swedish #x1011) - (progress-subtitle-language-danish #x1012) - (progress-subtitle-language-norwegian #x1013) - (progress-subtitle-language-korean #x1014) - (progress-subtitle-language-russian #x1015) - (progress-subtitles-label-speaker-on #x1016) - (progress-subtitles-label-speaker-off #x1017) - (progress-subtitles-label-speaker-auto #x1018) - ;; display modes - (progress-display-mode-borderless #x1019) - (progress-display-mode-fullscreen #x1020) - (progress-display-mode-windowed #x1021) - ;; aspect ratios - (progress-aspect-ratio-4x3 #x1022) - (progress-aspect-ratio-5x4 #x1023) - (progress-aspect-ratio-16x9 #x1024) - (progress-aspect-ratio-21x9 #x1025) - (progress-aspect-ratio-32x9 #x1026) - ;; 4:3 resolutions - (progress-res-4x3-640x480 #x1027) - (progress-res-4x3-800x600 #x1028) - (progress-res-4x3-1024x768 #x1029) - (progress-res-4x3-1280x960 #x1030) - (progress-res-4x3-1600x1200 #x1031) - ;; 5:4 resolutions - (progress-res-5x4-960x768 #x1032) - (progress-res-5x4-1280x1024 #x1033) - (progress-res-5x4-1500x1200 #x1034) - ;; 16:9 resolutions - (progress-res-16x9-854x480 #x1035) - (progress-res-16x9-1280x720 #x1036) - (progress-res-16x9-1920x1080 #x1037) - (progress-res-16x9-2560x1440 #x1038) - (progress-res-16x9-2880x1620 #x1039) - (progress-res-16x9-3840x2160 #x1040) - (progress-res-16x9-5120x2880 #x1041) - ;; 21:9 resolutions - (progress-res-21x9-2560x1080 #x1042) - (progress-res-21x9-3120x1440 #x1043) - (progress-res-21x9-3200x1440 #x1044) - (progress-res-21x9-3440x1440 #x1045) - (progress-res-21x9-3840x1600 #x1046) - (progress-res-21x9-5120x2160 #x1047) - ;; 32:9 resolutions - (progress-res-32x9-5120x1440 #x1048) - ;; original aspect ratio - (progress-use-original-aspect #x1049) - ) - -;; an individual string. -(deftype game-text (structure) - ((id game-text-id :offset-assert 0) - (text string :offset-assert 4) - ) - :pack-me - :method-count-assert 9 - :size-assert #x8 - :flag-assert #x900000008 - ) - -;; A table of all strings. -(deftype game-text-info (basic) - ((length int32 :offset-assert 4) - (language-id int32 :offset-assert 8) - (group-name string :offset-assert 12) - (data game-text :inline :dynamic :offset-assert 16) - ) - :method-count-assert 10 - :size-assert #x10 - :flag-assert #xa00000010 - (:methods - (lookup-text! (_type_ game-text-id symbol) string 9) - ) - ) - -;; all text is stored in the COMMON text files (one file per language). -;; in theory, you could have multiple text files that are only loaded when needed, but they didn't do this. -(define *text-group-names* (new 'static 'boxed-array :type string :length 1 "common")) - -;; The heap for storing text -(define *common-text-heap* (new 'global 'kheap)) - -;; will store the COMMON text when it is loaded. -(define *common-text* (the-as game-text-info #f)) - - -(defun-extern print-game-text string font-context symbol int int float) - - - diff --git a/goal_src/pc/pckernel-h.gc b/goal_src/pc/pckernel-h.gc index c40f8803d5..8e56ca668c 100644 --- a/goal_src/pc/pckernel-h.gc +++ b/goal_src/pc/pckernel-h.gc @@ -32,9 +32,9 @@ (defglobalconstant PC_KERNEL_VERSION_BUILD #x0001) -(defglobalconstant PC_KERNEL_VERSION_REVISION #x0002) +(defglobalconstant PC_KERNEL_VERSION_REVISION #x0003) -(defglobalconstant PC_KERNEL_VERSION_MINOR #x0000) +(defglobalconstant PC_KERNEL_VERSION_MINOR #x0001) (defglobalconstant PC_KERNEL_VERSION_MAJOR #x0001) (defglobalconstant PC_KERNEL_VERSION (logior (ash PC_KERNEL_VERSION_MAJOR 48) @@ -55,33 +55,6 @@ (defconstant PC_SETTINGS_FILE_NAME "game_config/pc-settings.txt") -(define *pc-subtitle-speaker-valid-options* - (new 'static 'boxed-array :type symbol :length 3 :allocated-length 3 #t #f 'auto)) - -(define *pc-graphics-display-mode-symbol-options* - (new 'static 'boxed-array :type symbol :length 3 :allocated-length 3 'borderless 'fullscreen 'windowed)) - -(define *pc-graphics-original-aspect-ratio-options* - (new 'static 'boxed-array :type symbol :length 2 :allocated-length 2 'orig-aspect-4x3 'orig-aspect-16x9)) - -(define *pc-graphics-aspect-ratio-options* - (new 'static 'boxed-array :type symbol :length 5 :allocated-length 5 'pc-aspect-4x3 'pc-aspect-5x4 'pc-aspect-16x9 'pc-aspect-21x9 'pc-aspect-32x9)) - -(define *pc-graphics-4x3-valid-resolutions* - (new 'static 'boxed-array :type symbol :length 5 :allocated-length 5 '640x480 '800x600 '1024x768 '1280x960 '1600x1200)) - -(define *pc-graphics-5x4-valid-resolutions* - (new 'static 'boxed-array :type symbol :length 3 :allocated-length 3 '960x768 '1280x1024 '1500x1200)) - -(define *pc-graphics-16x9-valid-resolutions* - (new 'static 'boxed-array :type symbol :length 7 :allocated-length 7 '854x480 '1280x720 '1920x1080 '2560x1440 '2880x1620 '3840x2160 '5120x2880)) - -(define *pc-graphics-21x9-valid-resolutions* - (new 'static 'boxed-array :type symbol :length 6 :allocated-length 6 '2560x1080 '3120x1440 '3200x1440 '3440x1440 '3840x1600 '5120x2160)) - -(define *pc-graphics-32x9-valid-resolutions* - (new 'static 'boxed-array :type symbol :length 1 :allocated-length 1 '5120x1440)) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; types and enums ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -227,14 +200,11 @@ (win-height int32) (dpi-x float) ;; DPI width scale (dpi-y float) ;; DPI height scale - (use-original-aspect-ratio? symbol) - (aspect-ratio-auto? symbol) ;; if on, aspect ratio is calculated automatically. + (aspect-ratio-auto? symbol) ;; if on, aspect ratio is calculated automatically based on game display size. (aspect-ratio float) ;; the desired aspect ratio. set auto to off and then this to 4/3 to force 4x3 aspect. (aspect-ratio-scale float) ;; aspect ratio compared to 4x3 - (aspect-ratio-reciprocal float) ;; aspect ratio compared to 3x4 - (resolution symbol) ;; selected resolution + (aspect-ratio-reciprocal float) ;; reciprocal of that (display-mode symbol) ;; display mode. can be windowed, fullscreen or borderless - (aspect-ratio-mode symbol) ;; explicit vetted aspect ratios - 4:3 | 5:4 | 16:9 | 21:9 | 32:9 (letterbox? symbol) ;; letterbox. #f = stretched (vsync? symbol) ;; vsync. (font-scale float) ;; font scaling. @@ -252,6 +222,8 @@ (display-bug-report symbol) (display-heap-status symbol) (display-actor-counts symbol) + (display-text-box symbol) + (display-sha symbol) (mood-override? symbol) (mood-overrides float 8) (movie? symbol) @@ -274,6 +246,7 @@ (gfx-renderer pc-gfx-renderer) ;; the renderer to use (gfx-resolution float) ;; for supersampling (gfx-anisotropy float) ;; for anisotropy + (gfx-msaa int) ;; for MSAA ;; ps2 settings (ps2-read-speed? symbol) ;; emulate DVD loads @@ -333,10 +306,7 @@ (reset-fixes (_type_) none) (reset-extra (_type_) none) (draw (_type_ dma-buffer) none) - (use-orig-aspect-ratio! (_type_ symbol) none) - (set-display-mode! (_type_ symbol) none) - (set-aspect-ratio-mode! (_type_ symbol) none) - (set-resolution! (_type_ symbol) none) + (set-display-mode! (_type_ symbol) int) (set-size! (_type_ int int) none) (set-aspect! (_type_ int int) none) (set-aspect-ratio! (_type_ float) none) @@ -345,6 +315,7 @@ (actor-force-visible? (_type_) symbol) (update-cheats (_type_) int) (commit-to-file (_type_) none) + (load-settings (_type_) int) ) ) @@ -397,6 +368,8 @@ (set! (-> obj display-bug-report) #f) (set! (-> obj display-heap-status) #f) (set! (-> obj display-actor-counts) #f) + (set! (-> obj display-text-box) #f) + (set! (-> obj display-sha) *debug-segment*) (set! (-> obj mood-override?) #f) (set! (-> obj movie?) #f) (set! (-> obj font-scale) 1.0) @@ -422,14 +395,15 @@ (set! (-> obj width) PC_BASE_WIDTH) (set! (-> obj height) PC_BASE_HEIGHT) (set! (-> obj use-vis?) #f) - (set! (-> obj use-original-aspect-ratio?) #f) (set! (-> obj aspect-ratio-auto?) #f) (set! (-> obj vsync?) #t) (set! (-> obj letterbox?) #t) - (set-aspect-ratio-mode! obj 'pc-aspect-4x3) - (set-resolution! obj '640x480) + (set-size! obj 640 480) + (set-aspect! obj 4 3) (set-display-mode! obj 'windowed) + + (set! (-> obj gfx-msaa) 4) ;; 4x msaa (none)) diff --git a/goal_src/pc/pckernel.gc b/goal_src/pc/pckernel.gc index 3708ab193f..3bddc81056 100644 --- a/goal_src/pc/pckernel.gc +++ b/goal_src/pc/pckernel.gc @@ -3,7 +3,7 @@ #| - This file contains code that we need for the PC port of the game specifically. + This file contains new code that we need for the PC port of the game specifically. It should be included as part of the game engine package (engine.cgo). This file contains various types and functions to store PC-specific information @@ -22,7 +22,7 @@ |# - +;; is this necessary? (#when PC_PORT @@ -36,22 +36,17 @@ "sets the game's display mode" ;; changing to same mode, no-op - (if (= (-> obj display-mode) mode) + (if (= (pc-get-fullscreen) mode) (return 0)) ;; else change it and update it (set! (-> obj display-mode) mode) - (cond - ((= mode 'borderless) - (pc-set-fullscreen 2 0)) - ((= mode 'fullscreen) - (pc-set-fullscreen 1 0)) - (else ;; default to windowed - (pc-set-fullscreen 0 0))) - (none)) + (pc-set-fullscreen mode 0) + 0) (defmethod set-size! pc-settings ((obj pc-settings) (width int) (height int)) "sets the size of the display window" + (format #t "Setting size to ~D x ~D~%" width height) (pc-set-window-size width height) (none)) @@ -60,23 +55,13 @@ "set the aspect ratio used for rendering. this forces native widescreen and takes width and height ratios." (let ((aspect (/ (the float aw) (the float ah)))) (set-aspect-ratio! obj aspect) + (set! (-> obj aspect-custom-x) aw) + (set! (-> obj aspect-custom-y) ah) (set! (-> obj aspect-ratio-auto?) #f) (set! (-> obj use-vis?) #f) ) (none)) -(defmethod use-orig-aspect-ratio! pc-settings ((obj pc-settings) (val symbol)) - "whether to use the pc port's aspect ratio, or the original games 4:3/16:9" - (if (= (-> obj use-original-aspect-ratio?) val) - (return 0)) - (set! (-> obj use-original-aspect-ratio?) val) - ;; default to the simplist resolution if we are changing - (if val - (set-aspect-ratio-mode! obj 'orig-aspect-4x3) - (set-aspect-ratio-mode! obj 'pc-aspect-4x3)) - (set! (-> *pc-settings* use-vis?) val) - (none)) - (defmethod set-aspect-ratio! pc-settings ((obj pc-settings) (aspect float)) "set the aspect ratio used for rendering." (set! (-> obj aspect-ratio) aspect) @@ -84,95 +69,13 @@ (set! (-> obj aspect-ratio-reciprocal) (/ ASPECT_4X3 aspect)) (none)) -(defmethod set-aspect-ratio-mode! pc-settings ((obj pc-settings) (mode symbol)) - "sets the game's aspect ratio mode" - - ;; changing to same mode, no-op - (if (= (-> obj aspect-ratio-mode) mode) - (return 0)) - - ;; else change it and update it - (set! (-> obj aspect-ratio-mode) mode) - ;; also default to the lowest resolution option at the same time - (case mode - (('orig-aspect-4x3) - (set-resolution! obj (-> *pc-graphics-4x3-valid-resolutions* 0))) - (('orig-aspect-16x9) - (set-resolution! obj (-> *pc-graphics-16x9-valid-resolutions* 0))) - (('pc-aspect-4x3) - (set-aspect! obj 4 3) - (set-resolution! obj (-> *pc-graphics-4x3-valid-resolutions* 0))) - (('pc-aspect-5x4) - (set-aspect! obj 5 4) - (set-resolution! obj (-> *pc-graphics-5x4-valid-resolutions* 0))) - (('pc-aspect-16x9) - (set-aspect! obj 16 9) - (set-resolution! obj (-> *pc-graphics-16x9-valid-resolutions* 0))) - (('pc-aspect-21x9) - (set-aspect! obj 21 9) - (set-resolution! obj (-> *pc-graphics-21x9-valid-resolutions* 0))) - (('pc-aspect-32x9) - (set-aspect! obj 32 9) - (set-resolution! obj (-> *pc-graphics-32x9-valid-resolutions* 0)))) - - ;; NOTE - i believe this is a temporary workaround to get the hud looking decent on pc aspect ratios - ;; eventually i assume this will only be required for the original ones! - (case mode - (('orig-aspect-4x3 'pc-aspect-4x3) - (set! (-> *setting-control* default aspect-ratio) 'aspect4x3)) - (else - (set! (-> *setting-control* default aspect-ratio) 'aspect16x9))) - - ;; NOTE - it should not be necessarily to call `set-aspect-ratio` as that is - ;; done on a per frame basis as long as it differs from the "current" setting-control value - ;; - ;; However, if I'm wrong, then that needs to be fixed at the build/load level again - ;; as that function is defined in `video` later in the order. - (none)) - -(defmethod set-resolution! pc-settings ((obj pc-settings) (mode symbol)) - "sets the game's resolution" - - ;; TODO - implement a custom resolution mode which will enable resizing and use the values stored - ;; changing to same mode, no-op - (if (= (-> obj resolution) mode) - (none)) - - ;; else change it and update it - (set! (-> obj resolution) mode) - (case mode - (('640x480) (set-size! obj 640 480)) - (('800x600) (set-size! obj 800 600)) - (('1024x768) (set-size! obj 1024 768)) - (('1280x960) (set-size! obj 1280 960)) - (('1600x1200) (set-size! obj 1600 1200)) - (('960x768) (set-size! obj 960 768)) - (('1280x1024) (set-size! obj 1280 1024)) - (('1500x1200) (set-size! obj 1500 1200)) - (('854x480) (set-size! obj 854 480)) - (('1280x720) (set-size! obj 1280 720)) - (('1920x1080) (set-size! obj 1920 1080)) - (('2560x1440) (set-size! obj 2560 1440)) - (('2880x1620) (set-size! obj 2880 1620)) - (('3840x2160) (set-size! obj 3840 2160)) - (('5120x2880) (set-size! obj 5120 2880)) - (('2560x1080) (set-size! obj 2560 1080)) - (('3120x1440) (set-size! obj 3120 1440)) - (('3200x1440) (set-size! obj 3200 1440)) - (('3440x1440) (set-size! obj 3440 1440)) - (('3840x1600) (set-size! obj 3840 1600)) - (('5120x2160) (set-size! obj 5120 2160)) - (('5120x1440) (set-size! obj 5120 1440))) - (none)) - (defmethod commit-to-file pc-settings ((obj pc-settings)) "commits the current settings to the file" ;; auto load settings if available - (clear *pc-temp-string-1*) - (format *pc-temp-string-1* "~S/pc-settings.gc" *pc-settings-folder*) + + (format (clear *pc-temp-string-1*) "~S/pc-settings.gc" *pc-settings-folder*) (pc-mkdir-file-path *pc-temp-string-1*) (write-to-file obj *pc-temp-string-1*) - (clear *pc-temp-string-1*) (none)) (defmethod update-from-os pc-settings ((obj pc-settings)) @@ -181,6 +84,7 @@ (set! (-> obj os) (pc-get-os)) (pc-get-window-size (&-> obj win-width) (&-> obj win-height)) (pc-get-window-scale (&-> obj dpi-x) (&-> obj dpi-y)) + (set! (-> obj display-mode) 'windowed) (when (-> obj use-vis?) (if (= (-> *setting-control* default aspect-ratio) 'aspect4x3) @@ -223,6 +127,7 @@ (cond ((-> obj letterbox?) + ;; AGH bad idea, this is meant for resolution! TODO fix this crap (pc-set-letterbox (-> obj width) (-> obj height)) ) (else @@ -230,14 +135,7 @@ ) ) - (cond - ((-> obj discord-rpc?) - (pc-discord-rpc-set 1) - ) - (else - (pc-discord-rpc-set 0) - ) - ) + (pc-discord-rpc-set (if (-> obj discord-rpc?) 1 0)) (when #t ;; (not (-> obj ps2-lod-dist?)) (pc-renderer-tree-set-lod (pc-renderer-tree-type tfrag3) (-> obj lod-force-tfrag)) @@ -251,7 +149,7 @@ (define *pc-cheat-temp* (the-as (pointer int32) (malloc 'global 24))) (defmacro pc-cheat-toggle-and-tune (obj cheat) `(begin - (cpad-clear-buttons! 0 r1) + (cpad-clear! 0 r1) (logxor! (-> ,obj cheats) (pc-cheats ,cheat)) (cheats-sound-play (logtest? (-> ,obj cheats) (pc-cheats ,cheat))) ) @@ -270,13 +168,9 @@ (set! (-> info fuel) (&-> *game-info* fuel)) (set! (-> info money-total) (&-> *game-info* money-total)) (set! (-> info buzzer-total) (&-> *game-info* buzzer-total)) - (set! (-> info status) "Playing Jak and Daxter: TPL") - (set! (-> info level) (if *target* - (symbol->string (-> *target* current-level name)) ;; use target's level if it exists - (symbol->string (-> (level-get-target-inside *level*) name)) ;; use camera's level otherwise - ) - ) - (set! (-> info cutscene?) (movie?)) + (set! (-> info status) "Playing Jak and Daxter: The Precursor Legacy™") + (set! (-> info level) (symbol->string (-> (level-get-target-inside *level*) name))) ;; grab the name of level we're in + (set! (-> info cutscene?) (-> obj movie?)) (pc-discord-rpc-update info) ) @@ -291,8 +185,9 @@ (when *progress-process* ;; adjust sizes for progress. ;; video.gc sets the sizes in the normal game. + ;; this is a complete hack and i'm losing it (let ((pr (-> *progress-process*)) - (wide-adjust (* 4.0 (- (/ (-> obj aspect-ratio-scale) ASPECT_16X9_SCALE) (1/ ASPECT_16X9_SCALE)))) + ;(wide-adjust (* 4.0 (- (/ (-> obj aspect-ratio-scale) ASPECT_16X9_SCALE) (1/ ASPECT_16X9_SCALE)))) ) (set! (-> pr sides-x-scale) 1.0) (set! (-> pr sides-y-scale) 13.0) @@ -304,11 +199,12 @@ ) (cond ((actor-force-visible? obj) - (set! (-> *ACTOR-bank* birth-dist) (meters 10000)) - (set! (-> *ACTOR-bank* pause-dist) (meters 10000)) - (set! (-> *ACTOR-bank* birth-max) 1000) - ) - ((> (-> *ACTOR-bank* birth-dist) (meters 220)) + ;; kinda overkill. + (set! (-> *ACTOR-bank* birth-dist) (meters 10000)) + (set! (-> *ACTOR-bank* pause-dist) (meters 10000)) + (set! (-> *ACTOR-bank* birth-max) 1000) + ) + ((> (-> *ACTOR-bank* birth-dist) (meters 220)) ;; the original caps at 220m, exceeding that means it was using our hacks (set! (-> *ACTOR-bank* birth-dist) (meters 220)) (set! (-> *ACTOR-bank* pause-dist) (meters 220)) )) @@ -348,6 +244,7 @@ (when *target* + ;; TODO green eco hack here as well (when (and (pc-cheats? obj eco-blue) (or (= (-> *target* fact-info-target eco-type) (pickup-type eco-blue)) (<= (-> *target* fact-info-target eco-level) 0.0))) @@ -562,6 +459,17 @@ (case-str *pc-temp-string* (("settings") (set! version (file-stream-read-int file)) + (cond + ((= (logand version #xffffffff00000000) (logand PC_KERNEL_VERSION #xffffffff00000000)) + ;; minor difference + ) + (else + ;; major difference + (format 0 "PC kernel version mismatch! Got ~D.~D vs ~D.~D~%" PC_KERNEL_VERSION_MAJOR PC_KERNEL_VERSION_MINOR (bit-field int version 32 16) (bit-field int version 48 16)) + (file-stream-close file) + (return #f) + ) + ) (dosettings (file) (case-str *pc-temp-string* (("fps") (set! (-> obj target-fps) (file-stream-read-int file))) @@ -569,18 +477,15 @@ (set! (-> obj width) (file-stream-read-int file)) (set! (-> obj height) (file-stream-read-int file)) (set-size! obj (-> obj width) (-> obj height)) - (set-aspect! obj (-> obj width) (-> obj height)) ) - (("use-original-aspect-ratio?") - (set! (-> obj use-original-aspect-ratio?) (file-stream-read-symbol file))) - (("aspect") + (("aspect") (set-aspect! obj (file-stream-read-int file) (file-stream-read-int file))) + (("aspect-test") (set! (-> obj aspect-custom-x) (file-stream-read-int file)) (set! (-> obj aspect-custom-y) (file-stream-read-int file)) ) (("aspect-auto") (set! (-> obj aspect-ratio-auto?) (file-stream-read-symbol file))) + (("aspect-game") (set! (-> *setting-control* default aspect-ratio) (file-stream-read-symbol file))) (("display-mode") (set-display-mode! obj (file-stream-read-symbol file))) - (("aspect-ratio-mode") (set-aspect-ratio-mode! obj (file-stream-read-symbol file))) - (("resolution") (set-resolution! obj (file-stream-read-symbol file))) (("letterbox") (set! (-> obj letterbox?) (file-stream-read-symbol file))) (("vsync") (set! (-> obj vsync?) (file-stream-read-symbol file))) (("font-scale") (set! (-> obj font-scale) (file-stream-read-float file))) @@ -672,18 +577,6 @@ ) ) - (when (!= PC_KERNEL_VERSION version) - (cond - ((= (logand version #xffffffff00000000) (logand PC_KERNEL_VERSION #xffffffff00000000)) - ;; minor difference - ) - (else - ;; major difference - (format 0 "PC kernel version mismatch! Got ~D.~D vs ~D.~D~%" PC_KERNEL_VERSION_MAJOR PC_KERNEL_VERSION_MINOR (bit-field int version 32 16) (bit-field int version 48 16)) - ) - ) - ) - ) (file-stream-close file) @@ -707,13 +600,12 @@ (format file "(settings #x~X~%" (-> obj version)) (format file " (fps ~D)~%" (-> obj target-fps)) - (format file " (size ~D ~D)~%" (-> obj width) (-> obj height)) - (format file " (use-original-aspect-ratio? ~A)~%" (-> obj use-original-aspect-ratio?)) - (format file " (aspect ~D ~D)~%" (-> obj aspect-custom-x) (-> obj aspect-custom-y)) + (format file " (size ~D ~D)~%" (-> obj win-width) (-> obj win-height)) + (format file " (aspect ~D ~D)~%" (-> obj width) (-> obj height)) + (format file " (aspect-test ~D ~D)~%" (-> obj aspect-custom-x) (-> obj aspect-custom-y)) (format file " (aspect-auto ~A)~%" (-> obj aspect-ratio-auto?)) + (format file " (aspect-game ~A)~%" (-> *setting-control* default aspect-ratio)) (format file " (display-mode ~A)~%" (-> obj display-mode)) - (format file " (aspect-ratio-mode ~A)~%" (-> obj aspect-ratio-mode)) - (format file " (resolution ~A)~%" (-> obj resolution)) (format file " (letterbox ~A)~%" (-> obj letterbox?)) (format file " (vsync ~A)~%" (-> obj vsync?)) (format file " (font-scale ~f)~%" (-> obj font-scale)) @@ -803,6 +695,18 @@ #t ) +(defmethod load-settings pc-settings ((obj pc-settings)) + "load" + + (format (clear *pc-temp-string-1*) "~S/pc-settings.gc" *pc-settings-folder*) + (if (pc-filepath-exists? *pc-temp-string-1*) + (begin + (format 0 "[PC] PC Settings found at '~S'...loading!~%" *pc-temp-string-1*) + (unless (read-from-file obj *pc-temp-string-1*) + (format 0 "[PC] PC Settings found at '~S' but could not be loaded, using defaults!~%" *pc-temp-string-1*) + (reset obj))) + (format 0 "[PC] PC Settings not found at '~S'...initializing with defaults!~%" *pc-temp-string-1*)) + 0) (defmethod new pc-settings ((allocation symbol) (type-to-make type)) "make a new pc-settings" @@ -810,19 +714,9 @@ (reset obj) ;; auto load settings if available ;; if saved settings are corrupted or not found, use defaults - (clear *pc-temp-string-1*) - (format *pc-temp-string-1* "~S/pc-settings.gc" *pc-settings-folder*) - (if (pc-filepath-exists? *pc-temp-string-1*) - (begin - (format 0 "[PC] PC Settings found at '~S'...loading!~%" *pc-temp-string-1*) - (unless (read-from-file obj *pc-temp-string-1*) - (begin - (format 0 "[PC] PC Settings found at '~S' but could not be loaded, using defaults!~%" *pc-temp-string-1*) - (reset obj)))) - (format 0 "[PC] PC Settings not found at '~S'...initializing with defaults!~%" *pc-temp-string-1*)) + (load-settings obj) - (clear *pc-temp-string-1*) obj)) diff --git a/goal_src/pc/progress-pc.gc b/goal_src/pc/progress-pc.gc new file mode 100644 index 0000000000..0da6d1c88e --- /dev/null +++ b/goal_src/pc/progress-pc.gc @@ -0,0 +1,1549 @@ +;;-*-Lisp-*- +(in-package goal) + +#| + + Code for the progress menu in the PC port. The original code is still loaded, this just has some overriden functions. + + |# + + +(#when PC_PORT + + +;;--------------------------- +;;--------------------------- +;; pc menu extra stuff + +(defconstant PROGRESS_PC_PAGE_HEIGHT 7) +(defconstant PROGRESS_SCROLL_DIR_UP -1) +(defconstant PROGRESS_SCROLL_DIR_DOWN 1) + +(defconstant GAME_MIN_RES_MULT 0.5) + + +(deftype progress-scroll (structure) + ((transition float) + (start-index int16) + (real-index int16) + (direction int8) + (last-screen progress-screen) + ) + ) +(define *progress-scroll* (new 'static 'progress-scroll)) + +(defmacro progress-scrolling? () `(< (-> *progress-scroll* transition) 1.0)) +(defmacro progress-scrolling-up? () `(and (progress-scrolling?) (= (-> *progress-scroll* direction) PROGRESS_SCROLL_DIR_UP))) +(defmacro progress-scrolling-down? () `(and (progress-scrolling?) (= (-> *progress-scroll* direction) PROGRESS_SCROLL_DIR_DOWN))) +(defconstant *progress-scroll-start* (-> *progress-scroll* start-index)) +(defconstant *progress-scroll-end* (+ -1 PROGRESS_PC_PAGE_HEIGHT (-> *progress-scroll* start-index))) +(defmacro progress-scroll-reset () + "resets scroll. nothing will be scrolling, as if it had finished." + `(begin + (set! (-> *progress-scroll* transition) 1.0) + (set! (-> *progress-scroll* direction) 0) + (set! (-> *progress-scroll* start-index) 0))) +(defmacro progress-scroll-up! () + `(begin + (set! (-> *progress-scroll* transition) 0.0) + (set! (-> *progress-scroll* direction) PROGRESS_SCROLL_DIR_UP) + (1-! (-> *progress-scroll* start-index)))) +(defmacro progress-scroll-down! () + `(begin + (set! (-> *progress-scroll* transition) 0.0) + (set! (-> *progress-scroll* direction) PROGRESS_SCROLL_DIR_DOWN) + (1+! (-> *progress-scroll* start-index)))) + + +;; ############################ +;; CAROUSELL STUFF +;; ############################ + +(deftype progress-carousell-state (structure) + ((int-backup int) + (symbol-backup symbol) + (subtitle-backup pc-subtitle-lang) + (aspect-native-choice symbol) + (current-carousell (array game-text-id)) + + (selection int) + (direction symbol) + (transition symbol) + (x-offset int32) + ) + ) +(define *progress-carousell* (new 'static 'progress-carousell-state)) + + +(define *carousell-display-mode* (new 'static 'boxed-array :type game-text-id :length 3 :allocated-length 3 + (game-text-id windowed) + (game-text-id fullscreen) + (game-text-id borderless) + )) + +(define *carousell-msaa* (new 'static 'boxed-array :type game-text-id :length 5 :allocated-length 5 + (game-text-id off) + (game-text-id 2-times) + (game-text-id 4-times) + (game-text-id 8-times) + (game-text-id 16-times) + )) + +(define *carousell-lod-bg* (new 'static 'boxed-array :type game-text-id :length 2 :allocated-length 2 + (game-text-id lod-high) + (game-text-id lod-low) + )) + +(define *carousell-lod-fg* (new 'static 'boxed-array :type game-text-id :length 3 :allocated-length 3 + (game-text-id lod-high) + (game-text-id lod-low) + (game-text-id lod-ps2) + )) + +(define *carousell-subtitle-language* (new 'static 'boxed-array :type game-text-id :length 6 :allocated-length 6 + (game-text-id english) + (game-text-id french) + (game-text-id german) + (game-text-id spanish) + (game-text-id italian) + (game-text-id japanese) + )) + +(define *carousell-speaker* (new 'static 'boxed-array :type game-text-id :length 3 :allocated-length 3 + (game-text-id speaker-always) + (game-text-id speaker-never) + (game-text-id speaker-auto) + )) + + + +;;--------------------------- +;;--------------------------- +;; pc menu defines + + +(define *game-options-pc* + (new 'static 'boxed-array :type game-option :length 6 :allocated-length 6 + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id vibrations) :scale #t) + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id play-hints) :scale #t) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id camera-options) :scale #t :param3 (game-option-menu camera-options)) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id accessibility-options) :scale #t :param3 (game-option-menu accessibility-options)) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id misc-options) :scale #t :param3 (game-option-menu misc-options)) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) + ) + +(define *graphic-options-pc* + (new 'static 'boxed-array :type game-option :length 8 :allocated-length 9 + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id game-resolution) :scale #t :param3 (game-option-menu resolution)) + (new 'static 'game-option :option-type (game-option-type display-mode) :name (game-text-id display-mode) :scale #t) + (new 'static 'game-option :option-type (game-option-type aspect-native) :name (game-text-id ps2-aspect-ratio) :scale #t) + (new 'static 'game-option :option-type (game-option-type aspect-ratio) :name (game-text-id aspect-ratio-ps2) :scale #t) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id aspect-ratio) :scale #t :param3 (game-option-menu aspect-ratio)) + (new 'static 'game-option :option-type (game-option-type msaa) :name (game-text-id msaa) :scale #t) + ;(new 'static 'game-option :option-type (game-option-type frame-rate) :name (game-text-id frame-rate) :scale #t) + (new 'static 'game-option :option-type (game-option-type menu) :name (game-text-id ps2-options) :scale #t :param3 (game-option-menu gfx-ps2-options)) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) + ) + +(define *misc-options* + (new 'static 'boxed-array :type game-option :length 2 :allocated-length 2 + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id discord-rpc) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) + ) + +(define *camera-options* + (new 'static 'boxed-array :type game-option :length 3 :allocated-length 3 + (new 'static 'game-option :option-type (game-option-type normal-inverted) :name (game-text-id camera-controls-horz) :scale #t) + (new 'static 'game-option :option-type (game-option-type normal-inverted) :name (game-text-id camera-controls-vert) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) + ) + +(define *accessibility-options* + (new 'static 'boxed-array :type game-option :length 2 :allocated-length 2 + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id money-starburst) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) + ) + +(define *gfx-ps2-options* + (new 'static 'boxed-array :type game-option :length 4 :allocated-length 4 + (new 'static 'game-option :option-type (game-option-type lod-bg) :name (game-text-id lod-bg) :scale #t) + (new 'static 'game-option :option-type (game-option-type lod-fg) :name (game-text-id lod-fg) :scale #t) + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id ps2-parts) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) + ) + +(define *aspect-ratio-options* + (new 'static 'boxed-array :type game-option :length 6 :allocated-length 6 + (new 'static 'game-option :option-type (game-option-type aspect-new) :name (game-text-id fit-to-screen) :scale #t) + (new 'static 'game-option :option-type (game-option-type aspect-new) :name (game-text-id resolution-fmt) :param1 4.0 :param2 3.0 :scale #t) + (new 'static 'game-option :option-type (game-option-type aspect-new) :name (game-text-id resolution-fmt) :param1 16.0 :param2 9.0 :scale #t) + (new 'static 'game-option :option-type (game-option-type aspect-new) :name (game-text-id resolution-fmt) :param1 21.0 :param2 9.0 :scale #t) + (new 'static 'game-option :option-type (game-option-type aspect-new) :name (game-text-id resolution-fmt) :param1 64.0 :param2 27.0 :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) + ) + +(define *sound-options-pc* + (new 'static 'boxed-array :type game-option :length 9 :allocated-length 9 + (new 'static 'game-option :name (game-text-id sfx-volume) :scale #t :param2 100.0) + (new 'static 'game-option :name (game-text-id music-volume) :scale #t :param2 100.0) + (new 'static 'game-option :name (game-text-id speech-volume) :scale #t :param2 100.0) + (new 'static 'game-option :option-type (game-option-type language) :name (game-text-id language) :scale #t) + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id subtitles) :scale #t) + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id hinttitles) :scale #t) + (new 'static 'game-option :option-type (game-option-type language-subtitles) :name (game-text-id subtitles-language) :scale #t) + (new 'static 'game-option :option-type (game-option-type speaker) :name (game-text-id subtitles-speaker) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) + ) + ) + +(define *back-button* (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t)) +(define-perm *temp-options-alloced* symbol #f) + +(defconstant RESOLUTIONS 6) +(define *resolutions* (new 'static 'array int32 RESOLUTIONS + 640 720 768 800 960 1080)) + +;; this is to avoid changing the value of *temp-options* or reallocating the options when reloading file +(unless *temp-options-alloced* +(define *temp-options* (new 'static 'boxed-array :type game-option :length 200 :allocated-length 200)) +(dotimes (i (-> *temp-options* length)) + (set! (-> *temp-options* i) (new 'global 'game-option))) +(true! *temp-options-alloced*)) + + +(defun find-highest-resolution () + + (let ((sx 0) (sy 0) (found #f) (mult GAME_MIN_RES_MULT) (lastr 0) (hir 0) (lor 0)) + (pc-get-screen-size -1 (the (pointer int32) (& sx)) (the (pointer int32) (& sy)) (the (pointer int32) 0)) + (if (> sy sx) + (set! sy sx)) + + (until found + + (dotimes (i RESOLUTIONS) + (let ((thisr (the int (* mult (the float (-> *resolutions* i)))))) + (cond + ((< sy thisr) + (if (zero? i) + (*! mult 0.5)) + (set! i RESOLUTIONS) + (true! found) + ) + (else + (set! lastr thisr)) + ) + )) + + (if (not found) + (*! mult 2)) + + ) + (set! hir lastr) + mult + ) + + ) + +(defmacro add-resolution-option (x y) + "add a resolution button to *temp-options* with specified size" + `(let ((option (-> *temp-options* (length *temp-options*)))) + (set! (-> option option-type) (game-option-type resolution)) + (set! (-> option name) (game-text-id resolution-fmt)) + (set! (-> option param1) (the float ,x)) + (set! (-> option param2) (the float ,y)) + (set! (-> option scale) #t) + + (1+! (-> *temp-options* length)) + ) + ) + +(defmacro add-back-option () + "add *back-button* to *temp-options*" + `(let ((option (-> *temp-options* (length *temp-options*)))) + (set! (-> option option-type) (game-option-type button)) + (set! (-> option name) (game-text-id back)) + (set! (-> option scale) #t) + + (1+! (-> *temp-options* length)) + ) + ) + +(defun build-resolution-options ((skip int) (amount int)) + + (set! (-> *temp-options* length) 0) + + (let ((done? #f) (mult (find-highest-resolution)) (sx 0) (sy 0) (vmodes 0) (flip? #f) (aspect 0.0) + ;; hack - do not use screen resolution in windowed mode, taskbar etc. messes it up and makes it useless! + (skip? (= 'windowed (pc-get-fullscreen))) + ;; shortcut + (max-options (1- (-> *temp-options* allocated-length)))) + + ;; portrait mode. unused + (set! flip? (> sy sx)) + ;; get screen size (for capping) + (pc-get-screen-size -1 (the (pointer int32) (& sx)) (the (pointer int32) (& sy)) (the (pointer int32) (& vmodes))) + + (case (pc-get-fullscreen) + (('fullscreen) + ;; insert psyched out trollface here + (set! sx 0) + (set! sy 0) + (countdown (i vmodes) + (let ((thisx 0) (thisy 0)) + (pc-get-screen-size i (the (pointer int32) (& thisx)) (the (pointer int32) (& thisy)) (the (pointer int32) 0)) + + (when (not (and (= thisx sx) (= thisy sy))) + (add-resolution-option thisx thisy) + ) + (set! sx thisx) + (set! sy thisy) + ) + ) + ) + + (else + ;; extra button when fullscreen + (when (not skip?) + (add-resolution-option sx sy) + (set! (-> *temp-options* (1- (length *temp-options*)) name) (game-text-id fit-to-screen)) + ) + ;; game aspect ratio + (set! aspect (-> *pc-settings* aspect-ratio)) + + (until (or done? (= (length *temp-options*) max-options)) + (countdown (i RESOLUTIONS) + (let ((thisr (the int (* mult (the float (-> *resolutions* i)))))) + + (when (and (< (length *temp-options*) max-options) (<= thisr sy) (not skip?)) + (add-resolution-option (* aspect (the float thisr)) thisr) + )) + (false! skip?) + ) + + (if (> mult GAME_MIN_RES_MULT) + (*! mult 0.5) + (true! done?)) + ) + ) + ) + (add-back-option) + ) + + + *temp-options* + ) + + +(defun print-string-in-carousell ((arg0 game-text-id) (arg1 font-context) (arg2 int) (arg3 symbol)) + (let ((s5-0 (if arg3 + arg2 + (- arg2) + ) + ) + ) + (+! (-> arg1 origin x) (the float s5-0)) + (let ((f30-0 (- 1.0 (* 0.0033333334 (the float arg2))))) + (print-game-text-scaled (lookup-text! *common-text* arg0 #f) f30-0 arg1 (the int (* 128.0 f30-0))) + ) + (set! (-> arg1 origin x) (- (-> arg1 origin x) (the float s5-0))) + ) + (set! (-> arg1 color) (font-color default)) + arg1 + ) + +(defun progress-draw-carousell-from-string-list ((options (array game-text-id)) (font font-context) (y-off int) (new-val int)) + "yep." + + (let ((old-lang (-> *progress-carousell* selection)) + (new-lang new-val) + (max-lang (length options)) + ) + (if (-> *progress-carousell* transition) + (seekl! (-> *progress-carousell* x-offset) 200 (the int (* 10.0 (-> *display* time-adjust-ratio))))) + (when (>= (-> *progress-carousell* x-offset) 100) + (set! (-> *progress-carousell* selection) new-lang) + (set! old-lang new-lang) + (set! (-> *progress-carousell* transition) #f) + (set! (-> *progress-carousell* x-offset) 0) + ) + (set! (-> font origin y) (the float (+ y-off 3))) + ;(set-color! font (font-color lighter-lighter-blue)) + 0 + (let ((next-lang (mod (+ old-lang 1) max-lang)) + (prev-lang (mod (+ max-lang -1 old-lang) max-lang)) + ;; these are used during the transition since it technically allows you to see 4 langs at once. + (next2-lang (mod (+ old-lang 2) max-lang)) + (prev2-lang (mod (+ max-lang -2 old-lang) max-lang)) + ) + (cond + ((-> *progress-carousell* direction) + (let ((a2-22 (- 200 (+ (-> *progress-carousell* x-offset) 100)))) + (print-string-in-carousell (-> options prev-lang) font a2-22 #f) + ) + (let ((a2-23 (+ (-> *progress-carousell* x-offset) 100))) + (cond + ((< a2-23 150) + (print-string-in-carousell (-> options next-lang) font a2-23 #t) + ) + (else + (let ((a2-24 (- 200 (-> *progress-carousell* x-offset)))) + (print-string-in-carousell (-> options prev2-lang) font a2-24 #f) + ) + ) + ) + ) + ) + (else + (let ((a2-25 (+ (-> *progress-carousell* x-offset) 100))) + (cond + ((< a2-25 150) + (print-string-in-carousell (-> options prev-lang) font a2-25 #f) + ) + (else + (let ((a2-26 (- 200 (-> *progress-carousell* x-offset)))) + (print-string-in-carousell (-> options next2-lang) font a2-26 #t) + ) + ) + ) + ) + (let ((a2-27 (- 200 (+ (-> *progress-carousell* x-offset) 100)))) + (print-string-in-carousell (-> options next-lang) font a2-27 #t) + ) + ) + ) + ) + (if (not (-> *progress-carousell* transition)) + (set-color! font (font-color yellow-green-2))) + (print-string-in-carousell (-> options old-lang) font (-> *progress-carousell* x-offset) (-> *progress-carousell* direction)) + ) + ) + +;;--------------------------- +;;--------------------------- +;; function overrides + +(defun init-game-options ((obj progress)) + "Set the options for all of the menus." + + ;; start off by making them all invalid + (dotimes (i (progress-screen max)) + (set! (-> *options-remap* i) #f) + ) + + ;; set up options for each screen + (set! (-> *options-remap* (progress-screen settings)) *main-options*) + (set! (-> *options-remap* (progress-screen game-settings)) *game-options-pc*) + (set! (-> *options-remap* (progress-screen graphic-settings)) *graphic-options-pc*) + + (set! (-> *options-remap* (progress-screen sound-settings)) *sound-options-pc*) + (set! (-> *options-remap* (progress-screen memcard-no-space)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-not-inserted)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-not-formatted)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-format)) *yes-no-options*) + (set! (-> *options-remap* (progress-screen memcard-data-exists)) *yes-no-options*) + (set! (-> *options-remap* (progress-screen memcard-insert)) *ok-options*) + (set! (-> *options-remap* (progress-screen load-game)) *load-options*) + (set! (-> *options-remap* (progress-screen save-game)) *save-options*) + (set! (-> *options-remap* (progress-screen save-game-title)) *save-options-title*) + (set! (-> *options-remap* (progress-screen memcard-error-loading)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-error-saving)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-error-formatting)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-error-creating)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-auto-save-error)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-removed)) *ok-options*) + (set! (-> *options-remap* (progress-screen memcard-no-data)) *yes-no-options*) + (set! (-> *options-remap* (progress-screen title)) *title*) + (set! (-> *options-remap* (progress-screen settings-title)) *options*) + (set! (-> *options-remap* (progress-screen auto-save)) *ok-options*) + (set! (-> *options-remap* (progress-screen pal-change-to-60hz)) *yes-no-options*) + (set! (-> *options-remap* (progress-screen pal-now-60hz)) *yes-no-options*) + (set! (-> *options-remap* (progress-screen no-disc)) *ok-options*) + (set! (-> *options-remap* (progress-screen bad-disc)) *ok-options*) + (set! (-> *options-remap* (progress-screen quit)) *yes-no-options*) + ;; our screens! + (set! (-> *options-remap* (progress-screen aspect-msg)) *yes-no-options*) + (set! (-> *options-remap* (progress-screen camera-options)) *camera-options*) + (set! (-> *options-remap* (progress-screen misc-options)) *misc-options*) + (set! (-> *options-remap* (progress-screen accessibility-options)) *accessibility-options*) + (set! (-> *options-remap* (progress-screen gfx-ps2-options)) *gfx-ps2-options*) + (set! (-> *options-remap* (progress-screen resolution)) *temp-options*) + (set! (-> *options-remap* (progress-screen aspect-ratio)) *aspect-ratio-options*) + + ;; set default params + (set! (-> *progress-state* aspect-ratio-choice) (get-aspect-ratio)) + (set! (-> *progress-state* video-mode-choice) (get-video-mode)) + (set! (-> *progress-state* yes-no-choice) #f) + + ;; set variable pointers + (set! (-> *game-options* 0 value-to-modify) (&-> *setting-control* default vibration)) + (set! (-> *game-options* 1 value-to-modify) (&-> *setting-control* default play-hints)) + (set! (-> *game-options* 2 value-to-modify) (&-> *setting-control* default language)) + (set! (-> *game-options-japan* 0 value-to-modify) (&-> *setting-control* default vibration)) + (set! (-> *game-options-japan* 1 value-to-modify) (&-> *setting-control* default play-hints)) + (set! (-> *game-options-demo* 0 value-to-modify) (&-> *setting-control* default vibration)) + (set! (-> *game-options-demo* 1 value-to-modify) (&-> *setting-control* default play-hints)) + (set! (-> *graphic-options* 1 value-to-modify) (&-> *progress-state* aspect-ratio-choice)) + (set! (-> *graphic-title-options-pal* 1 value-to-modify) (&-> *progress-state* video-mode-choice)) + (set! (-> *graphic-title-options-pal* 2 value-to-modify) (&-> *progress-state* aspect-ratio-choice)) + (set! (-> *sound-options* 0 value-to-modify) (&-> *setting-control* default sfx-volume)) + (set! (-> *sound-options* 1 value-to-modify) (&-> *setting-control* default music-volume)) + (set! (-> *sound-options* 2 value-to-modify) (&-> *setting-control* default dialog-volume)) + (set! (-> *yes-no-options* 0 value-to-modify) (&-> *progress-state* yes-no-choice)) + ;; our options! + (set! (-> *game-options-pc* 0 value-to-modify) (&-> *setting-control* default vibration)) + (set! (-> *game-options-pc* 1 value-to-modify) (&-> *setting-control* default play-hints)) + (set! (-> *graphic-options-pc* 1 value-to-modify) (&-> *progress-carousell* int-backup)) + (set! (-> *graphic-options-pc* 2 value-to-modify) (&-> *progress-carousell* aspect-native-choice)) + (set! (-> *graphic-options-pc* 3 value-to-modify) (&-> *progress-state* aspect-ratio-choice)) + (set! (-> *graphic-options-pc* 5 value-to-modify) (&-> *progress-carousell* int-backup)) + (set! (-> *misc-options* 0 value-to-modify) (&-> *pc-settings* discord-rpc?)) + (set! (-> *camera-options* 0 value-to-modify) (&-> *pc-settings* camera-hflip?)) + (set! (-> *camera-options* 1 value-to-modify) (&-> *pc-settings* camera-vflip?)) + (set! (-> *accessibility-options* 0 value-to-modify) (&-> *pc-settings* money-starburst?)) + (set! (-> *gfx-ps2-options* 0 value-to-modify) (&-> *progress-carousell* int-backup)) + (set! (-> *gfx-ps2-options* 1 value-to-modify) (&-> *progress-carousell* int-backup)) + (set! (-> *gfx-ps2-options* 2 value-to-modify) (&-> *pc-settings* ps2-parts?)) + (set! (-> *sound-options-pc* 0 value-to-modify) (&-> *setting-control* default sfx-volume)) + (set! (-> *sound-options-pc* 1 value-to-modify) (&-> *setting-control* default music-volume)) + (set! (-> *sound-options-pc* 2 value-to-modify) (&-> *setting-control* default dialog-volume)) + (set! (-> *sound-options-pc* 3 value-to-modify) (&-> *setting-control* default language)) + (set! (-> *sound-options-pc* 4 value-to-modify) (&-> *pc-settings* subtitles?)) + (set! (-> *sound-options-pc* 5 value-to-modify) (&-> *pc-settings* hinttitles?)) + (set! (-> *sound-options-pc* 6 value-to-modify) (&-> *progress-carousell* subtitle-backup)) + (set! (-> *sound-options-pc* 7 value-to-modify) (&-> *progress-carousell* int-backup)) + (set! (-> *progress-carousell* aspect-native-choice) (-> *pc-settings* use-vis?)) + + ;; scroll stuff! + (progress-scroll-reset) + (none) + ) + + + +(defmethod respond-common progress ((obj progress)) + "common logic for navigating the progress menu. + this is the overriden version, purged of no longer necessary code and with additional new code." + + ;; read memcard + (mc-get-slot-info 0 *progress-save-info*) + (set! (-> obj card-info) *progress-save-info*) + ;; build custom dynamic menus + (case (-> obj display-state) + (((progress-screen resolution)) + ;; TODO infinite scrolling + (build-resolution-options 0 0) + ) + ) + ;; run nav code + (let ((options (-> *options-remap* (-> obj display-state)))) + ;; snap scroll if oob + (when (> (length options) PROGRESS_PC_PAGE_HEIGHT) + (set! (-> *progress-scroll* start-index) (max (-> *progress-scroll* start-index) + (- (-> obj option-index) (+ PROGRESS_PC_PAGE_HEIGHT -2)))) + ) + (when (and options (not (or (progress-scrolling?) (-> obj in-transition)))) + ;; only respond to inputs when transition is done (and also there's options at all) + (cond + ((cpad-pressed? 0 up) + ;; pressed up + ;; original code checked hold and then press, because hold can be used during center screen option. which we don't use. + (when (not (-> obj selected-option)) + (if (!= (length options) 1) + (sound-play-by-name (static-sound-name "cursor-up-down") (new-sound-id) 1024 0 0 1 #t) + ) + (set! (-> obj last-option-index-change) (-> *display* real-frame-counter)) + (cond + ((> (-> obj option-index) 0) + (1-! (-> obj option-index)) + (when (and (> (length options) PROGRESS_PC_PAGE_HEIGHT) (< (-> obj option-index) *progress-scroll-start*)) + (progress-scroll-up!) + ) + ) + (else + (set! (-> obj option-index) (1- (length options))) + (set! (-> *progress-scroll* start-index) (max 0 (- (length options) PROGRESS_PC_PAGE_HEIGHT -1))) + ) + ) + ) + ) + ((cpad-pressed? 0 down) + ;; pressed down. + (when (not (-> obj selected-option)) + (if (!= (length options) 1) + (sound-play-by-name (static-sound-name "cursor-up-down") (new-sound-id) 1024 0 0 1 #t) + ) + (set! (-> obj last-option-index-change) (-> *display* real-frame-counter)) + (cond + ((< (-> obj option-index) (1- (length options))) + (1+! (-> obj option-index)) + (when (and (> (length options) PROGRESS_PC_PAGE_HEIGHT) (>= (-> obj option-index) *progress-scroll-end*)) + (progress-scroll-down!) + ) + ) + (else + (set! (-> obj option-index) 0) + (set! (-> *progress-scroll* start-index) 0) + ) + ) + ) + ) + ((cpad-hold? 0 left) + ;; holding left. sliders use hold. + (cond + ((cpad-pressed? 0 left) + ;; navigate left. + (when (or (-> obj selected-option) (= (-> options (-> obj option-index) option-type) (game-option-type yes-no))) + (let ((sound? #f)) + (case (-> options (-> obj option-index) option-type) + (((game-option-type on-off) + (game-option-type yes-no) + (game-option-type normal-inverted) + (game-option-type aspect-native)) + ;; pressed left on an on/off yes/no option + (when (not (-> (the-as (pointer uint32) (-> options (-> obj option-index) value-to-modify)))) + ;; it was on 'off' or 'no' + (set! sound? #t) + ;; vibrate if this toggles vibration. broken in original game. + (if (= (-> options (-> obj option-index) value-to-modify) (&-> *setting-control* default vibration)) + (cpad-set-buzz! (-> *cpad-list* cpads 0) 1 255 (seconds 0.3)) + ) + ) + ;; it's on 'on' or 'yes' now + (set! (-> (the-as (pointer symbol) (-> options (-> obj option-index) value-to-modify))) #t) + ) + (((game-option-type aspect-ratio)) + (set! sound? (= (-> (the-as (pointer symbol) (-> options (-> obj option-index) value-to-modify))) 'aspect16x9)) + (set! (-> (the-as (pointer symbol) (-> options (-> obj option-index) value-to-modify))) 'aspect4x3) + ) + (((game-option-type language)) + ;; language selection. if not on first language, go back. if on first language, go to last. + (if (> (the-as int (-> (the-as (pointer uint64) (-> options (-> obj option-index) value-to-modify)))) 0) + (+! (-> (the-as (pointer uint64) (-> options (-> obj option-index) value-to-modify))) -1) + (set! (-> (the-as (pointer int64) (-> options (-> obj option-index) value-to-modify))) 5) + ) + ;; language was updated. + (set! (-> obj language-transition) #t) + (set! (-> obj language-direction) #t) + (set! sound? #t) + ) + (((game-option-type display-mode) + (game-option-type msaa) + (game-option-type lod-bg) + (game-option-type lod-fg) + (game-option-type speaker) + ) + ;; a carousell like language + (if (> (-> (the-as (pointer int) (-> options (-> obj option-index) value-to-modify))) 0) + (+! (-> (the-as (pointer int) (-> options (-> obj option-index) value-to-modify))) -1) + (set! (-> (the-as (pointer int) (-> options (-> obj option-index) value-to-modify))) (1- (length (-> *progress-carousell* current-carousell)))) + ) + ;; updated. + (set! (-> *progress-carousell* transition) #t) + (set! (-> *progress-carousell* direction) #t) + (set! sound? #t) + ) + (((game-option-type language-subtitles)) + ;; a carousell like language + (if (> (-> (the-as (pointer pc-subtitle-lang) (-> options (-> obj option-index) value-to-modify))) (the-as pc-subtitle-lang 0)) + (+! (-> (the-as (pointer pc-subtitle-lang) (-> options (-> obj option-index) value-to-modify))) (the-as pc-subtitle-lang -1)) + (set! (-> (the-as (pointer pc-subtitle-lang) (-> options (-> obj option-index) value-to-modify))) (the-as pc-subtitle-lang (1- (length (-> *progress-carousell* current-carousell))))) + ) + ;; updated. + (set! (-> *progress-carousell* transition) #t) + (set! (-> *progress-carousell* direction) #t) + (set! sound? #t) + ) + ) + (if sound? + (sound-play-by-name (static-sound-name "cursor-l-r") (new-sound-id) 1024 0 0 1 #t) + ) + ) + ) + ) + (else + ;; holding left + (when (-> obj selected-option) + (let ((sound? #f)) + (case (-> options (-> obj option-index) option-type) + (((game-option-type slider)) + ;; slider is selected + (cond + ((>= (-> (the-as (pointer float) (-> options (-> obj option-index) value-to-modify))) + (+ 1.0 (-> options (-> obj option-index) param1))) + ;; we're 1 above minimum, so reduce by 1 + (set! (-> (the-as (pointer float) (-> options (-> obj option-index) value-to-modify))) + (+ -1.0 (-> (the-as (pointer float) (-> options (-> obj option-index) value-to-modify))))) + (set! sound? #t) + ) + ((< (-> options (-> obj option-index) param1) + ;; not at least 1 above minimum, just set to minimum (why not just use max or something!!) + (-> (the-as (pointer float) (-> options (-> obj option-index) value-to-modify)))) + (set! (-> (the-as (pointer float) (-> options (-> obj option-index) value-to-modify))) + (-> options (-> obj option-index) param1)) + (set! sound? #t) + ) + ) + ) + ) + ;; play sound + (when sound? + (let ((vol 100.0)) + (case (-> options (-> obj option-index) name) + (((game-text-id music-volume) (game-text-id speech-volume)) + (set! vol (-> (the-as (pointer float) (-> options (-> obj option-index) value-to-modify)))) + ) + ) + (when (< (seconds 0.3) (- (-> *display* real-frame-counter) (-> *progress-state* last-slider-sound))) + (set! (-> *progress-state* last-slider-sound) (-> *display* real-frame-counter)) + (sound-play-by-name (static-sound-name "slider2001") (new-sound-id) (the int (* 10.24 vol)) 0 0 1 #t) + ) + ) + ) + ) + ) + ) + ) + ) + ((cpad-hold? 0 right) + ;; holding right + (cond + ((cpad-pressed? 0 right) + ;; pressed right + (when (or (-> obj selected-option) (= (-> options (-> obj option-index) option-type) (game-option-type yes-no))) + (let ((sound? #f)) + (case (-> options (-> obj option-index) option-type) + (((game-option-type on-off) + (game-option-type yes-no) + (game-option-type normal-inverted) + (game-option-type aspect-native) + ) + ;; play sound if it was on 'yes' because we're going to 'no' now + (set! sound? (-> (the-as (pointer symbol) (-> options (-> obj option-index) value-to-modify)))) + ;; set to no + (set! (-> (the-as (pointer symbol) (-> options (-> obj option-index) value-to-modify))) #f) + ) + (((game-option-type aspect-ratio)) + ;; same shit different toilet + (set! sound? (= (-> (the-as (pointer symbol) (-> options (-> obj option-index) value-to-modify))) 'aspect4x3)) + (set! (-> (the-as (pointer symbol) (-> options (-> obj option-index) value-to-modify))) 'aspect16x9) + ) + (((game-option-type language)) + ;; same thing as before. if at last, go to first. otherwise, keep going forward. + (if (< (the-as int (-> (the-as (pointer uint64) (-> options (-> obj option-index) value-to-modify)))) 5) + (1+! (-> (the-as (pointer uint64) (-> options (-> obj option-index) value-to-modify)))) + (set! (-> (the-as (pointer int64) (-> options (-> obj option-index) value-to-modify))) 0) + ) + (set! (-> obj language-transition) #t) + (set! (-> obj language-direction) #f) + (set! sound? #t) + ) + (((game-option-type display-mode) + (game-option-type msaa) + (game-option-type lod-bg) + (game-option-type lod-fg) + (game-option-type speaker) + ) + ;; same thing as before. if at last, go to first. otherwise, keep going forward. + (if (< (-> (the-as (pointer int) (-> options (-> obj option-index) value-to-modify))) (1- (length (-> *progress-carousell* current-carousell)))) + (1+! (-> (the-as (pointer int) (-> options (-> obj option-index) value-to-modify)))) + (set! (-> (the-as (pointer int) (-> options (-> obj option-index) value-to-modify))) 0) + ) + (set! (-> *progress-carousell* transition) #t) + (set! (-> *progress-carousell* direction) #f) + (set! sound? #t) + ) + (((game-option-type language-subtitles)) + ;; same thing as before. if at last, go to first. otherwise, keep going forward. + (if (< (-> (the-as (pointer pc-subtitle-lang) (-> options (-> obj option-index) value-to-modify))) (1- (length (-> *progress-carousell* current-carousell)))) + (+! (-> (the-as (pointer pc-subtitle-lang) (-> options (-> obj option-index) value-to-modify))) (the-as pc-subtitle-lang 1)) + (set! (-> (the-as (pointer pc-subtitle-lang) (-> options (-> obj option-index) value-to-modify))) (the-as pc-subtitle-lang 0)) + ) + (set! (-> *progress-carousell* transition) #t) + (set! (-> *progress-carousell* direction) #f) + (set! sound? #t) + ) + ) + ;; play sound if desired + (if sound? + (sound-play-by-name (static-sound-name "cursor-l-r") (new-sound-id) 1024 0 0 1 #t) + ) + ) + ) + ) + (else + ;; holding right, but didnt just press it. same slider stuff as before + (when (-> obj selected-option) + (let ((sound? #f)) + (case (-> options (-> obj option-index) option-type) + (((game-option-type slider)) + (cond + ((>= (+ -1.0 (-> options (-> obj option-index) param2)) + (-> (the-as (pointer float) (-> options (-> obj option-index) value-to-modify)))) + (set! (-> (the-as (pointer float) (-> options (-> obj option-index) value-to-modify))) + (+ 1.0 (-> (the-as (pointer float) (-> options (-> obj option-index) value-to-modify))))) + (set! sound? #t) + ) + ((< (-> (the-as (pointer float) (-> options (-> obj option-index) value-to-modify))) + (-> options (-> obj option-index) param2)) + (set! (-> (the-as (pointer float) (-> options (-> obj option-index) value-to-modify))) + (-> options (-> obj option-index) param2)) + (set! sound? #t) + ) + ) + ) + ) + (when sound? + (let ((vol 100.0)) + (case (-> options (-> obj option-index) name) + (((game-text-id music-volume) (game-text-id speech-volume)) + (set! vol (-> (the-as (pointer float) (-> options (-> obj option-index) value-to-modify)))) + ) + ) + (when (< (seconds 0.3) (- (-> *display* real-frame-counter) (-> *progress-state* last-slider-sound))) + (set! (-> *progress-state* last-slider-sound) (-> *display* real-frame-counter)) + (sound-play-by-name (static-sound-name "slider2001") (new-sound-id) (the int (* 10.24 vol)) 0 0 1 #t) + ) + ) + ) + ) + ) + ) + ) + ) + ((or (cpad-pressed? 0 square) (cpad-pressed? 0 triangle)) + ;; pressed square or triangle, cancel out! + (cond + ((-> obj selected-option) + ;; an option is selected. AHHH!!! just restore to whatever was on the backup + (case (-> options (-> obj option-index) option-type) + (((game-option-type slider)) + (set! (-> (the-as (pointer float) (-> options (-> obj option-index) value-to-modify))) + (-> *progress-state* slider-backup)) + ) + (((game-option-type language)) + (set! (-> (the-as (pointer language-enum) (-> options (-> obj option-index) value-to-modify))) + (-> *progress-state* language-backup)) + ) + (((game-option-type on-off) (game-option-type normal-inverted)) + (set! (-> (the-as (pointer symbol) (-> options (-> obj option-index) value-to-modify))) + (-> *progress-state* on-off-backup)) + ) + ) + ;; ding + (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) + (set! (-> obj selected-option) #f) + ) + ((or (can-go-back? obj) + (= (-> obj display-state) (progress-screen load-game)) + (= (-> obj display-state) (progress-screen save-game)) + (= (-> obj display-state) (progress-screen save-game-title)) + ) + ;; no option selected, go back + (cpad-clear! 0 square) + (cpad-clear! 0 triangle) + (if (= (-> obj display-state) (progress-screen settings)) + (sound-play-by-name (static-sound-name "menu-stats") (new-sound-id) 1024 0 0 1 #t) + (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) + ) + (load-level-text-files (-> *level-task-data* (-> obj display-level-index) text-group-index)) + (set! (-> obj next-display-state) (progress-screen invalid)) + ) + ) + ) + ((or (cpad-pressed? 0 x) (cpad-pressed? 0 circle)) + ;; pressed x or circle. advance! + (cond + ((not (-> obj selected-option)) + ;; no option already selected. + (cond + ((= (-> options (-> obj option-index) option-type) (game-option-type menu)) + ;; go to a menu + (cpad-clear! 0 x) + (cpad-clear! 0 circle) + (push! obj) + (sound-play-by-name (static-sound-name "select-option") (new-sound-id) 1024 0 0 1 #t) + (set! (-> obj next-display-state) (the-as progress-screen (-> options (-> obj option-index) param3))) + (case (-> obj next-display-state) + (((progress-screen load-game) (progress-screen save-game) (progress-screen save-game-title)) + (set! (-> obj next-display-state) (set-memcard-screen obj (-> obj next-display-state))) + ) + ) + ) + ((= (-> options (-> obj option-index) option-type) (game-option-type button)) + ;; a button. what? + (case (-> options (-> obj option-index) name) + (((game-text-id exit-demo)) + ;; exit demo! + (set! *master-exit* 'force) + (set-master-mode 'game) + ) + (((game-text-id back)) + ;; go back! + (if (= (-> obj display-state) (progress-screen settings)) + (sound-play-by-name (static-sound-name "menu-stats") (new-sound-id) 1024 0 0 1 #t) + (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) + ) + (load-level-text-files (-> *level-task-data* (-> obj display-level-index) text-group-index)) + (set! (-> obj next-display-state) (progress-screen invalid)) + ) + ) + ;; other behaviors are hardcoded elsewhere because screw you. + ) + ((= (-> options (-> obj option-index) option-type) (game-option-type resolution)) + ;; resolution button. change resolution! + (let ((newx (the int (-> options (-> obj option-index) param1))) + (newy (the int (-> options (-> obj option-index) param2)))) + (set-size! *pc-settings* newx newy)) + (cpad-clear! 0 x) + (cpad-clear! 0 circle) + (cpad-clear! 0 square) + (cpad-clear! 0 triangle) + (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) + (set! (-> obj next-display-state) (progress-screen invalid)) + ) + ((= (-> options (-> obj option-index) option-type) (game-option-type aspect-new)) + ;; resolution button. change resolution! + (let ((newx (the int (-> options (-> obj option-index) param1))) + (newy (the int (-> options (-> obj option-index) param2)))) + (if (= (-> options (-> obj option-index) name) (game-text-id fit-to-screen)) + (true! (-> *pc-settings* aspect-ratio-auto?)) + (set-aspect! *pc-settings* newx newy))) + (cpad-clear! 0 x) + (cpad-clear! 0 circle) + (cpad-clear! 0 square) + (cpad-clear! 0 triangle) + (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) + (set! (-> obj next-display-state) (progress-screen invalid)) + ) + ((!= (-> options (-> obj option-index) option-type) (game-option-type yes-no)) + ;; not yes-no + ;; set backups! we're entering some toggle or whatever + (case (-> options (-> obj option-index) option-type) + (((game-option-type slider)) + (set! (-> *progress-state* slider-backup) + (-> (the-as (pointer float) (-> options (-> obj option-index) value-to-modify)))) + ) + (((game-option-type language)) + (set! (-> *progress-state* language-backup) + (-> (the-as (pointer language-enum) (-> options (-> obj option-index) value-to-modify)))) + ) + (((game-option-type language-subtitles)) + (set! (-> (the-as (pointer pc-subtitle-lang) (-> options (-> obj option-index) value-to-modify))) (-> *pc-settings* subtitle-language)) + ) + (((game-option-type on-off) (game-option-type normal-inverted)) + (set! (-> *progress-state* on-off-backup) + (-> (the-as (pointer symbol) (-> options (-> obj option-index) value-to-modify)))) + ) + (((game-option-type display-mode)) + ;; display-mode just reuses language stuff + (case (pc-get-fullscreen) + (('windowed #f) (set! (-> *progress-carousell* int-backup) 0)) + (('fullscreen #t) (set! (-> *progress-carousell* int-backup) 1)) + (('borderless) (set! (-> *progress-carousell* int-backup) 2)) + ) + ) + (((game-option-type msaa)) + (case (-> *pc-settings* gfx-msaa) + ((2) (set! (-> *progress-carousell* int-backup) 1)) + ((4) (set! (-> *progress-carousell* int-backup) 2)) + ((8) (set! (-> *progress-carousell* int-backup) 3)) + ((16) (set! (-> *progress-carousell* int-backup) 4)) + (else (set! (-> *progress-carousell* int-backup) 0)) + ) + ) + (((game-option-type lod-bg)) + (case (-> *pc-settings* lod-force-tfrag) + ((0) (set! (-> *progress-carousell* int-backup) 0)) + ((1 2) (set! (-> *progress-carousell* int-backup) 1)) + (else (set! (-> *progress-carousell* int-backup) 2)) + ) + ) + (((game-option-type lod-fg)) + (cond + ((-> *pc-settings* ps2-lod-dist?) (set! (-> *progress-carousell* int-backup) 1)) + (else (set! (-> *progress-carousell* int-backup) 0)) + ) + ) + (((game-option-type speaker)) + (case (-> *pc-settings* subtitle-speaker?) + ((#t) (set! (-> *progress-carousell* int-backup) 0)) + ((#f) (set! (-> *progress-carousell* int-backup) 1)) + (('auto) (set! (-> *progress-carousell* int-backup) 2)) + ) + ) + ) + (sound-play-by-name (static-sound-name "select-option") (new-sound-id) 1024 0 0 1 #t) + (cpad-clear! 0 x) + (cpad-clear! 0 circle) + (set! (-> obj selected-option) #t) + (case (-> options (-> obj option-index) option-type) + (((game-option-type language)) + (set! (-> obj language-selection) (-> *setting-control* current language)) + (set! (-> obj language-direction) #t) + (set! (-> obj language-transition) #f) + (set! (-> obj language-x-offset) 0) + ) + (else + (set! (-> *progress-carousell* selection) (-> *progress-carousell* int-backup)) + (set! (-> *progress-carousell* direction) #t) + (set! (-> *progress-carousell* transition) #f) + (set! (-> *progress-carousell* x-offset) 0) + (case (-> options (-> obj option-index) option-type) + (((game-option-type display-mode)) (set! (-> *progress-carousell* current-carousell) *carousell-display-mode*)) + (((game-option-type msaa)) (set! (-> *progress-carousell* current-carousell) *carousell-msaa*)) + (((game-option-type lod-bg)) (set! (-> *progress-carousell* current-carousell) *carousell-lod-bg*)) + (((game-option-type lod-fg)) (set! (-> *progress-carousell* current-carousell) *carousell-lod-bg*)) + (((game-option-type speaker)) (set! (-> *progress-carousell* current-carousell) *carousell-speaker*)) + (((game-option-type language-subtitles)) + (set! (-> *progress-carousell* current-carousell) *carousell-subtitle-language*) + (set! (-> *progress-carousell* selection) (the int (-> (the-as (pointer pc-subtitle-lang) (-> options (-> obj option-index) value-to-modify))))) + ) + ) + ) + ) + ) + ) + ) + (else + ;; an option was selected. write stuff! + (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) + (set! (-> obj selected-option) #f) + (case (-> options (-> obj option-index) option-type) + (((game-option-type aspect-ratio)) + ;; aspect ratio is first written to the backup. so this is for applying the change if we went through with it. + (set! (-> *setting-control* default aspect-ratio) (-> (the-as (pointer symbol) (-> options (-> obj option-index) value-to-modify)))) + ) + (((game-option-type aspect-native)) + (set! (-> *pc-settings* use-vis?) (-> (the-as (pointer symbol) (-> options (-> obj option-index) value-to-modify)))) + (if (-> *pc-settings* use-vis?) + (set! (-> *setting-control* current aspect-ratio) #f) + (set-aspect! *pc-settings* (-> *pc-settings* aspect-custom-x) (-> *pc-settings* aspect-custom-y))) + ) + (((game-option-type display-mode)) + ;; same thing. + (case (-> *progress-carousell* int-backup) + ((0) (set-display-mode! *pc-settings* 'windowed)) + ((1) (set-display-mode! *pc-settings* 'fullscreen)) + ((2) (set-display-mode! *pc-settings* 'borderless)) + ) + ) + (((game-option-type msaa)) + (case (-> *progress-carousell* int-backup) + ((0) (set! (-> *pc-settings* gfx-msaa) 1)) + ((1) (set! (-> *pc-settings* gfx-msaa) 2)) + ((2) (set! (-> *pc-settings* gfx-msaa) 4)) + ((3) (set! (-> *pc-settings* gfx-msaa) 8)) + ((4) (set! (-> *pc-settings* gfx-msaa) 16)) + ) + ) + (((game-option-type lod-bg)) + (case (-> *progress-carousell* int-backup) + ((0) (set! (-> *pc-settings* lod-force-tfrag) 0) (set! (-> *pc-settings* lod-force-tie) 0)) + ((1) (set! (-> *pc-settings* lod-force-tfrag) 2) (set! (-> *pc-settings* lod-force-tie) 2)) + ((2) (set! (-> *pc-settings* lod-force-tfrag) 2) (set! (-> *pc-settings* lod-force-tie) 3)) + ) + ) + (((game-option-type lod-fg)) + (case (-> *progress-carousell* int-backup) + ((0) (set! (-> *pc-settings* lod-force-actor) 0) (set! (-> *pc-settings* ps2-lod-dist?) #f)) + ((1) (set! (-> *pc-settings* lod-force-actor) 0) (set! (-> *pc-settings* ps2-lod-dist?) #t)) + ) + ) + (((game-option-type language)) + (if (not (-> obj language-transition)) + (load-level-text-files (-> obj display-level-index))) + ) + (((game-option-type language-subtitles)) + (set! (-> *pc-settings* subtitle-language) (-> (the-as (pointer pc-subtitle-lang) (-> options (-> obj option-index) value-to-modify)))) + ) + (((game-option-type speaker)) + ;; same thing. + (case (-> *progress-carousell* int-backup) + ((0) (set! (-> *pc-settings* subtitle-speaker?) #t)) + ((1) (set! (-> *pc-settings* subtitle-speaker?) #f)) + ((2) (set! (-> *pc-settings* subtitle-speaker?) 'auto)) + ) + ) + ) + ) + ) + ) + ) + ) + ) + (none) + ) + + +(defmethod draw-options progress ((obj progress) (arg0 int) (arg1 int) (arg2 float)) + "common logic for drawing options menus." + + (let ((options (-> *options-remap* (-> obj display-state)))) + (when options + ;; this menu has options to draw omg + (let* ((line-amt (if (> (length options) PROGRESS_PC_PAGE_HEIGHT) (1- PROGRESS_PC_PAGE_HEIGHT) (length options))) + (y-off (- arg0 (/ (* arg1 line-amt) 2))) + (option-count 0) + (unkx 27) + (unk2 0) + (font (new 'stack 'font-context *font-default-matrix* 0 0 0.0 (font-color default) (font-flags shadow kerning))) + ) + ;; set the common params for the text drawing + (set-width! font 370) + (set-height! font 25) + (set! (-> font flags) (font-flags shadow kerning middle left large)) + ;; when scrolling we draw an extra line + (cond + ((progress-scrolling-down?) (set! y-off (+ (- y-off arg1) (* (the float arg1) (- 1.0 (-> *progress-scroll* transition)))))) + ((progress-scrolling-up?) (set! y-off (+ (- y-off arg1) (* (the float arg1) (-> *progress-scroll* transition))))) + ) + (let ((draw-arrows (and (not (-> obj in-transition)) + (= (-> obj next-state name) 'progress-normal) + (> (length options) PROGRESS_PC_PAGE_HEIGHT) + (< (mod (-> *display* real-frame-counter) (seconds 0.2)) (seconds 0.1)))) + (draw-prev (< 0 *progress-scroll-start*)) + (draw-next (> (length options) *progress-scroll-end*))) + (set! (-> obj particles 32 init-pos x) (the float (if (and draw-arrows draw-prev) + (- 195 (-> *progress-process* 0 left-x-offset)) + -320 + ))) + (set! (-> obj particles 33 init-pos x) (the float (if (and draw-arrows draw-next) + (- 195 (-> *progress-process* 0 left-x-offset)) + -320 + ))) + ) + (dotimes (index (length options)) + (let ((option-str (the string #f)) ;; the option text + (option-x 17) + (option-y y-off) + ) + (case (-> options index option-type) + (((game-option-type yes-no)) + ;; yes-no option. text is either '->YES<- NO' or 'YES ->NO<-', not the most robust but this option is a strange hack anyway. + (if (-> (the-as (pointer uint32) (-> options index value-to-modify))) + (set! option-str (string-format "~30L~S~0L ~S" (lookup-text! *common-text* (game-text-id yes) #f) (lookup-text! *common-text* (game-text-id no) #f))) + (set! option-str (string-format "~0L~S ~30L~S" (lookup-text! *common-text* (game-text-id yes) #f) (lookup-text! *common-text* (game-text-id no) #f))) + ) + ) + (((game-option-type menu) (game-option-type button)) + ;; menu option or simple button. just draw its text! + (if (nonzero? (-> options index name)) + (set! option-str (lookup-text! *common-text* (-> options index name) #f)) + (set! option-str (the-as string #f)) + ) + ) + (((game-option-type resolution) (game-option-type aspect-new)) + ;; resolution settings + (set! option-str (string-format (lookup-text! *common-text* (-> options index name) #f) + (the int (-> options index param1)) (the int (-> options index param2)))) + ) + (else + (cond + ((and (-> obj selected-option) (= (-> obj option-index) index)) + ;; this option is SELECTED! + (set-color! font (font-color default)) + (set! (-> font origin x) (the float (- option-x (-> obj left-x-offset)))) + (set! (-> font origin y) (the float (+ y-off -8))) + (set-scale! font 0.6) + (print-game-text (lookup-text! *common-text* (-> options index name) #f) font #f 128 22) + (set! option-y (+ y-off 7)) + (case (-> options index option-type) + (((game-option-type slider)) + ;; draw a slider and its text. + ;; this ugliness is just decompiler stuff. all it does is fade the alpha according to value. + (let* ((v1-82 (the-as uint #x8000ffff)) + (f0-12 (* 0.01 (-> (the-as (pointer float) (-> options index value-to-modify))))) + (a0-34 (logior (logand v1-82 -256) (shr (shl (the int (+ 64.0 (* 191.0 f0-12))) 56) 56))) + (a3-5 (logior (logand a0-34 -65281) (shr (shl (shr (shl a0-34 56) 56) 56) 48))) + ) + (draw-percent-bar (- 75 (-> obj left-x-offset)) (+ y-off 8) f0-12 (the-as int a3-5)) + ) + (set! option-str (string-format "~D" (the int (-> (the-as (pointer float) (-> options index value-to-modify)))))) + (set! option-x (+ (the int (* 2.5 (-> (the-as (pointer float) (-> options index value-to-modify))))) -100)) + ) + (((game-option-type on-off) (game-option-type normal-inverted) (game-option-type aspect-native)) + ;; on-off option or some other toggle. same logic as yes-no. changed to cut down code duping. + (let ( + (on-str (case (-> options index option-type) + (((game-option-type on-off) (game-option-type aspect-native)) + (lookup-text! *common-text* (game-text-id on) #f)) + (((game-option-type normal-inverted)) + (lookup-text! *common-text* (game-text-id normal) #f)) + )) + (off-str (case (-> options index option-type) + (((game-option-type on-off) (game-option-type aspect-native)) + (lookup-text! *common-text* (game-text-id off) #f)) + (((game-option-type normal-inverted)) + (lookup-text! *common-text* (game-text-id inverted) #f)) + )) + ) + (if (-> (the-as (pointer symbol) (-> options index value-to-modify))) + (set! option-str (string-format "~30L~S~0L ~S" on-str off-str)) + (set! option-str (string-format "~0L~S ~30L~S" on-str off-str)) + ) + ) + ) + (((game-option-type display-mode) + (game-option-type msaa) + (game-option-type lod-bg) + (game-option-type lod-fg) + (game-option-type speaker) + ) + ;; crunched down to one generic function. + (progress-draw-carousell-from-string-list (-> *progress-carousell* current-carousell) font y-off (-> (the-as (pointer int) (-> options index value-to-modify)))) + ) + (((game-option-type language-subtitles)) + ;; crunched down to one generic function. + (progress-draw-carousell-from-string-list (-> *progress-carousell* current-carousell) font y-off (the int (-> (the-as (pointer pc-subtitle-lang) (-> options index value-to-modify))))) + ) + (((game-option-type language)) + ;; language carousell. who knew this could be so complicated. + (let ((old-lang (-> obj language-selection)) + (new-lang (-> (the-as (pointer language-enum) (-> options index value-to-modify)))) + (max-lang 6) + ) + (if (-> obj language-transition) + (seekl! (-> obj language-x-offset) 200 (the int (* 10.0 (-> *display* time-adjust-ratio))))) + (when (>= (-> obj language-x-offset) 100) + (set! (-> obj language-selection) new-lang) + (set! old-lang new-lang) + (set! (-> obj language-transition) #f) + (set! (-> obj language-x-offset) 0) + ) + (set! (-> font origin y) (the float (+ y-off 3))) + ;(set-color! font (font-color lighter-lighter-blue)) + 0 + (let ((next-lang (mod (+ old-lang 1) max-lang)) + (prev-lang (mod (+ max-lang -1 old-lang) max-lang)) + ;; these are used during the transition since it technically allows you to see 4 langs at once. + (next2-lang (mod (+ old-lang 2) max-lang)) + (prev2-lang (mod (+ max-lang -2 old-lang) max-lang)) + ) + (cond + ((-> obj language-direction) + (let ((a2-22 (- 200 (+ (-> obj language-x-offset) 100)))) + (print-language-name prev-lang font a2-22 #f) + ) + (let ((a2-23 (+ (-> obj language-x-offset) 100))) + (cond + ((< a2-23 150) + (print-language-name (the int next-lang) font a2-23 #t) + ) + (else + (let ((a2-24 (- 200 (-> obj language-x-offset)))) + (print-language-name prev2-lang font a2-24 #f) + ) + ) + ) + ) + ) + (else + (let ((a2-25 (+ (-> obj language-x-offset) 100))) + (cond + ((< a2-25 150) + (print-language-name prev-lang font a2-25 #f) + ) + (else + (let ((a2-26 (- 200 (-> obj language-x-offset)))) + (print-language-name (the int next2-lang) font a2-26 #t) + ) + ) + ) + ) + (let ((a2-27 (- 200 (+ (-> obj language-x-offset) 100)))) + (print-language-name (the int next-lang) font a2-27 #t) + ) + ) + ) + ) + (if (not (-> obj language-transition)) + (set-color! font (font-color yellow-green-2))) + (print-language-name (the-as int old-lang) font (-> obj language-x-offset) (-> obj language-direction)) + )) + (((game-option-type aspect-ratio)) + ;; same as on-off but checks a different symbol + (if (= (-> (the-as (pointer symbol) (-> options index value-to-modify))) 'aspect4x3) + (set! option-str (string-format "~30L~S~0L ~S" (lookup-text! *common-text* (game-text-id 4x3) #f) (lookup-text! *common-text* (game-text-id 16x9) #f))) + (set! option-str (string-format "~0L~S ~30L~S" (lookup-text! *common-text* (game-text-id 4x3) #f) (lookup-text! *common-text* (game-text-id 16x9) #f))) + ) + ) + ) + ) + (else + ;; this option is not selected :-( + (case (-> options index option-type) + (((game-option-type slider) + (game-option-type aspect-ratio) + (game-option-type display-mode) + (game-option-type msaa) + (game-option-type lod-bg) + (game-option-type lod-fg) + (game-option-type speaker) + ) + ;; slider and aspect ratio options just show their text + (set! option-str (lookup-text! *common-text* (-> options index name) #f)) + ) + (((game-option-type on-off) (game-option-type aspect-native)) + ;; on-off options show their text + on or off + (set! option-str (string-format "~S: ~S" (lookup-text! *common-text* (-> options index name) #f) + (if (-> (the-as (pointer uint32) (-> options index value-to-modify))) + (lookup-text! *common-text* (game-text-id on) #f) + (lookup-text! *common-text* (game-text-id off) #f) + ))) + ) + (((game-option-type normal-inverted)) + ;; etc + (set! option-str (string-format "~S: ~S" (lookup-text! *common-text* (-> options index name) #f) + (if (-> (the-as (pointer uint32) (-> options index value-to-modify))) + (lookup-text! *common-text* (game-text-id normal) #f) + (lookup-text! *common-text* (game-text-id inverted) #f) + ))) + ) + (((game-option-type language)) + ;; language options show their text + language name + (set! option-str (string-format "~S: ~S" (lookup-text! *common-text* (-> options index name) #f) + (lookup-text! *common-text* (-> *language-name-remap* (-> (the-as (pointer uint64) (-> options index value-to-modify)))) #f))) + ) + (((game-option-type language-subtitles)) + (let ((stupidity (the int (-> (the-as (pointer pc-subtitle-lang) (-> options index value-to-modify)))))) + (set! option-str (string-format "~S: ~S" (lookup-text! *common-text* (-> options index name) #f) + (lookup-text! *common-text* (-> *carousell-subtitle-language* stupidity) #f))) + ) + ) + ) + ) + )) + ) + (when (or (<= (length options) PROGRESS_PC_PAGE_HEIGHT) + (and (not (progress-scrolling?)) + (>= index *progress-scroll-start*) + (< index *progress-scroll-end*)) + (and (progress-scrolling-down?) + (>= index (1- *progress-scroll-start*)) + (< index *progress-scroll-end*)) + (and (progress-scrolling-up?) + (>= index *progress-scroll-start*) + (< index (1+ *progress-scroll-end*))) + ) + (when option-str + ;; draw the actual text! + (let ((f0-23 (-> obj transition-percentage-invert)) + (scroll-amt (-> *progress-scroll* transition))) + (cond + ((or (and (progress-scrolling-up?) (= index *progress-scroll-start*)) + (and (progress-scrolling-down?) (= index (1- *progress-scroll-end*)))) + ) + ((or (and (progress-scrolling-down?) (= index (1- *progress-scroll-start*))) + (and (progress-scrolling-up?) (= index *progress-scroll-end*))) + (set! scroll-amt (- 1.0 scroll-amt)) + ) + (else + (set! scroll-amt 1.0) + ) + ) + (set-color! font (if (and (= index (-> obj option-index)) (not (or (progress-scrolling?) (-> obj in-transition)))) + (font-color yellow-green-2) + (font-color default) + )) + (set! (-> font origin x) (the float (- option-x (-> obj left-x-offset)))) + (set! (-> font origin y) (the float (the int (* (the float option-y) (if (-> options index scale) + f0-23 + 1.0 + ))))) + (set-scale! font (* arg2 f0-23 scroll-amt)) + (print-game-text option-str font #f (the int (* 128.0 f0-23 scroll-amt)) 22) + ) + ) + (+! y-off arg1) + (+! option-count 1) + ) + )) + ) + ) + ) + 0 + (none) + ) + + +;; override the post handler for progress-normal +(set! (-> progress-normal post) + (lambda :behavior progress () + ;; scroll stuff TODO time ratio + (when (progress-scrolling?) + (seek! (-> *progress-scroll* transition) 1.0 (* 1.75 (1/ 512) (-> self transition-speed) (-> *display* time-adjust-ratio))) + ) + (when (!= (-> self display-state) (-> *progress-scroll* last-screen)) + (progress-scroll-reset) + (set! (-> *progress-scroll* last-screen) (-> self display-state)) + ) + ;; draw the menus!! + (let* ((a1-0 (-> self display-level-index)) + (gp-0 (-> *level-task-data* a1-0)) + (unk #t) + (stats? #f) + ) + (case (-> self display-state) + (((progress-screen fuel-cell)) + (set! stats? #t) + (draw-fuel-cell-screen self a1-0) + ) + (((progress-screen money)) + (set! stats? #t) + (draw-money-screen self a1-0) + ) + (((progress-screen buzzer)) + (set! stats? #t) + (draw-buzzer-screen self a1-0) + ) + (((progress-screen graphic-settings) + (progress-screen settings-title) + (progress-screen title) + (progress-screen game-settings) + (progress-screen settings) + (progress-screen misc-options) + (progress-screen accessibility-options) + (progress-screen game-ps2-options) + (progress-screen resolution) + (progress-screen aspect-ratio) + ) + (hide-progress-icons) + (draw-options self 115 25 0.82) + ) + (((progress-screen camera-options)) + ;; camera options lines are a bit too big + (hide-progress-icons) + (draw-options self 115 36 0.77) + ) + (((progress-screen gfx-ps2-options)) + (hide-progress-icons) + (draw-options self 115 25 0.72) + ) + (((progress-screen sound-settings)) + (hide-progress-icons) + (draw-options self 115 25 0.76) + ) + (((progress-screen memcard-removed) (progress-screen memcard-auto-save-error)) + (draw-notice-screen self) + (draw-options self 192 0 0.82) + ) + (((progress-screen memcard-no-data)) + (draw-notice-screen self) + (draw-options self 165 0 0.82) + ) + (((progress-screen memcard-format)) + (draw-notice-screen self) + (draw-options self 172 0 0.82) + ) + (((progress-screen memcard-no-space) + (progress-screen memcard-not-inserted) + (progress-screen memcard-not-formatted) + ) + (draw-notice-screen self) + (draw-options self 195 0 0.82) + ) + (((progress-screen memcard-error-loading) + (progress-screen memcard-error-saving) + (progress-screen memcard-error-formatting) + (progress-screen memcard-error-creating) + (progress-screen memcard-auto-save-error) + (progress-screen auto-save) (progress-screen load-game) (progress-screen save-game) + ) + (draw-notice-screen self) + (draw-options self 190 0 0.82) + ) + (((progress-screen no-disc) (progress-screen bad-disc)) + (draw-notice-screen self) + (if (is-cd-in?) + (draw-options self 170 0 0.82) + ) + ) + (((progress-screen quit)) + (draw-notice-screen self) + (draw-options self 110 0 0.82) + ) + (((progress-screen memcard-insert)) + (draw-notice-screen self) + (draw-options self 165 0 0.82) + ) + (((progress-screen memcard-data-exists)) + (draw-notice-screen self) + (draw-options self 168 0 0.82) + ) + (((progress-screen memcard-loading) + (progress-screen memcard-saving) + (progress-screen memcard-formatting) + (progress-screen memcard-creating) + ) + (draw-notice-screen self) + ) + (((progress-screen save-game-title)) + (draw-notice-screen self) + (draw-options self 169 15 0.6) + ) + ) + (when stats? + (let* ((v1-98 (cond ((-> self stat-transition) 0) + ((= (-> self level-transition) 1) (- (-> self transition-offset))) + (else (-> self transition-offset)) + )) + (f30-0 (the-as float (if (-> self stat-transition) + 1.0 + (-> self transition-percentage-invert) + ))) + (s5-1 (new 'stack 'font-context *font-default-matrix* + (- 32 (-> self left-x-offset)) + (the int (* (+ 42.0 (the float (/ v1-98 2))) f30-0)) + 8325000.0 + (font-color lighter-lighter-blue) + (font-flags shadow kerning) + )) + ) + (set-width! s5-1 328) + (set-height! s5-1 45) + (set! (-> s5-1 flags) (font-flags shadow kerning middle left large)) + (print-game-text-scaled (lookup-text! *common-text* (-> gp-0 level-name-id) #f) f30-0 s5-1 (the int (* 128.0 f30-0))) + ) + ) + ) + (case (-> self display-state) + (((progress-screen fuel-cell) (progress-screen money) (progress-screen buzzer)) + (draw-progress self) + ) + ) + (adjust-sprites self) + (adjust-icons self) + (none) + )) + +;; override the enter handler for progress-going-out +(set! (-> progress-going-out enter) + (lambda :behavior progress () + (sound-play-by-name (static-sound-name "menu-close") (new-sound-id) 1024 0 0 1 #t) + (hide-progress-icons) + (commit-to-file *pc-settings*) + (set! (-> self particles 3 init-pos x) -320.0) + (set! (-> self particles 4 init-pos x) -320.0) + (set! (-> self particles 32 init-pos x) -320.0) + (set! (-> self particles 33 init-pos x) -320.0) + (case (-> self display-state) + (((progress-screen load-game) (progress-screen save-game) (progress-screen save-game-title)) + (set! (-> self transition-speed) 30.0) + ) + ) + (none) + )) + + + +) + + + diff --git a/goal_src/pc/subtitle.gc b/goal_src/pc/subtitle.gc index 3c7c5eb595..9c8f94c0bc 100644 --- a/goal_src/pc/subtitle.gc +++ b/goal_src/pc/subtitle.gc @@ -199,6 +199,16 @@ ) 0) +(defun load-level-subtitle-files ((idx int)) + "If needed, load subtitles" + + ;; just load common. These flags are not yet understood. + (if (or *level-text-file-load-flag* (>= idx 0)) + (load-subtitle-text-info PC_SUBTITLE_FILE_NAME '*subtitle-text* *subtitle-text-heap*) + ) + (none) + ) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -246,7 +256,7 @@ (suspend)) ) :trans (behavior () - (load-subtitle-text-info PC_SUBTITLE_FILE_NAME '*subtitle-text* *subtitle-text-heap*) + (load-level-subtitle-files 0) ;; reset params (set! (-> self spool-name) #f) (set! (-> self cur-channel) (pc-subtitle-channel invalid)) diff --git a/goalc/compiler/Compiler.cpp b/goalc/compiler/Compiler.cpp index 6766d3db70..374155ce80 100644 --- a/goalc/compiler/Compiler.cpp +++ b/goalc/compiler/Compiler.cpp @@ -21,7 +21,6 @@ Compiler::Compiler(const std::string& user_profile, std::unique_ptr // let the build system run us m_make.add_tool(std::make_shared(this)); - m_make.add_tool(std::make_shared(this)); // load GOAL library Object library_code = m_goos.reader.read_from_file({"goal_src", "goal-lib.gc"}); diff --git a/goalc/compiler/Compiler.h b/goalc/compiler/Compiler.h index 7bd3d4abfe..081ab1d585 100644 --- a/goalc/compiler/Compiler.h +++ b/goalc/compiler/Compiler.h @@ -18,6 +18,7 @@ #include "goalc/emitter/Register.h" #include "goalc/listener/Listener.h" #include "goalc/make/MakeSystem.h" +#include "goalc/data_compiler/game_text.h" #include "goalc/data_compiler/game_subtitle.h" enum MathMode { MATH_INT, MATH_BINT, MATH_FLOAT, MATH_INVALID }; @@ -56,7 +57,6 @@ class Compiler { listener::Listener& listener() { return m_listener; } void poke_target() { m_listener.send_poke(); } bool connect_to_target(); - GameSubtitleDB& subtitle_db() { return m_subtitle_db; } Replxx::completions_t find_symbols_by_prefix(std::string const& context, int& contextLen, std::vector const& user_data); @@ -88,7 +88,6 @@ class Compiler { SymbolInfoMap m_symbol_info; std::unique_ptr m_repl; MakeSystem m_make; - GameSubtitleDB m_subtitle_db; struct DebugStats { int num_spills = 0; diff --git a/goalc/compiler/compilation/CompilerControl.cpp b/goalc/compiler/compilation/CompilerControl.cpp index ab975f8006..600bcbbf36 100644 --- a/goalc/compiler/compilation/CompilerControl.cpp +++ b/goalc/compiler/compilation/CompilerControl.cpp @@ -66,10 +66,7 @@ Val* Compiler::compile_asm_data_file(const goos::Object& form, const goos::Objec auto args = get_va(form, rest); va_check(form, args, {goos::ObjectType::SYMBOL, goos::ObjectType::STRING}, {}); auto kind = symbol_string(args.unnamed.at(0)); - if (kind == "game-text") { - // TODO version - compile_game_text(as_string(args.unnamed.at(1))); - } else if (kind == "game-count") { + if (kind == "game-count") { compile_game_count(as_string(args.unnamed.at(1))); } else if (kind == "dir-tpages") { compile_dir_tpages(as_string(args.unnamed.at(1))); @@ -97,7 +94,17 @@ Val* Compiler::compile_asm_text_file(const goos::Object& form, const goos::Objec throw_compiler_error(form, "Invalid object {} in asm-text-file files list.", o.print()); } }); - compile_game_subtitle(files, (GameTextVersion)args.unnamed.at(1).as_int(), m_subtitle_db); + compile_game_subtitle(files, (GameTextVersion)args.unnamed.at(1).as_int()); + } else if (kind == "text") { + std::vector files; + for_each_in_list(args.named.at("files"), [this, &files, &form](const goos::Object& o) { + if (o.is_string()) { + files.push_back(o.as_string()->data); + } else { + throw_compiler_error(form, "Invalid object {} in asm-text-file files list.", o.print()); + } + }); + compile_game_text(files, (GameTextVersion)args.unnamed.at(1).as_int()); } else { throw_compiler_error(form, "The option {} was not recognized for asm-text-file.", kind); } diff --git a/goalc/data_compiler/game_subtitle.cpp b/goalc/data_compiler/game_subtitle.cpp index d87058b2cb..7e319fd260 100644 --- a/goalc/data_compiler/game_subtitle.cpp +++ b/goalc/data_compiler/game_subtitle.cpp @@ -62,14 +62,13 @@ std::string uppercase(const std::string& in) { */ void parse(const goos::Object& data, GameTextVersion text_ver, GameSubtitleDB& db) { auto font = get_font_bank(text_ver); - std::map banks; - bool languages_set = false; + std::map> banks; for_each_in_list(data.as_pair()->cdr, [&](const goos::Object& obj) { if (obj.is_pair()) { auto& head = car(obj); if (head.is_symbol() && head.as_symbol()->name == "language-id") { - if (languages_set) { + if (banks.size() != 0) { throw std::runtime_error("Languages have been set multiple times."); } @@ -81,17 +80,15 @@ void parse(const goos::Object& data, GameTextVersion text_ver, GameSubtitleDB& d auto lang = get_int(obj); if (!db.bank_exists(lang)) { // database has no lang yet - banks[lang] = db.new_bank(lang); + banks[lang] = db.add_bank(std::make_shared(lang)); } else { banks[lang] = db.bank_by_id(lang); } }); - - languages_set = true; } else if (head.is_string()) { - if (!languages_set) { + if (banks.size() == 0) { throw std::runtime_error("At least one language must be set before defining entries."); } GameSubtitleSceneInfo scene(head.as_string()->data); @@ -127,7 +124,7 @@ void parse(const goos::Object& data, GameTextVersion text_ver, GameSubtitleDB& d throw std::runtime_error("Invalid game subtitles file"); } }); - if (!languages_set) { + if (banks.size() == 0) { throw std::runtime_error("At least one language must be set."); } } @@ -183,9 +180,8 @@ void compile(GameSubtitleDB& db) { } } // namespace -void compile_game_subtitle(const std::vector& filenames, - GameTextVersion text_ver, - GameSubtitleDB& db) { +void compile_game_subtitle(const std::vector& filenames, GameTextVersion text_ver) { + GameSubtitleDB db; goos::Reader reader; for (auto& filename : filenames) { fmt::print("[Build Game Subtitle] {}\n", filename.c_str()); diff --git a/goalc/data_compiler/game_subtitle.h b/goalc/data_compiler/game_subtitle.h index 59488fda45..7f4e590745 100644 --- a/goalc/data_compiler/game_subtitle.h +++ b/goalc/data_compiler/game_subtitle.h @@ -4,6 +4,7 @@ #include #include #include +#include class GameSubtitleSceneInfo { public: @@ -58,25 +59,21 @@ class GameSubtitleBank { }; /*! - * The subtitles database contains a subtitbles bank for each language. + * The subtitles database contains a subtitles bank for each language. * Each subtitles bank contains a series of subtitle scene infos. */ class GameSubtitleDB { public: - const std::map& banks() const { return m_banks; } + const std::map>& banks() const { return m_banks; } bool bank_exists(int id) const { return m_banks.find(id) != m_banks.end(); } - GameSubtitleBank* new_bank(int id) { - ASSERT(!bank_exists(id)); - m_banks[id] = new GameSubtitleBank(id); - return m_banks.at(id); - } - void add_bank(GameSubtitleBank* bank) { + std::shared_ptr add_bank(std::shared_ptr bank) { ASSERT(!bank_exists(bank->lang())); m_banks[bank->lang()] = bank; + return bank; } - GameSubtitleBank* bank_by_id(int id) { + std::shared_ptr bank_by_id(int id) { if (!bank_exists(id)) { return nullptr; } @@ -84,9 +81,7 @@ class GameSubtitleDB { } private: - std::map m_banks; + std::map> m_banks; }; -void compile_game_subtitle(const std::vector& filenames, - GameTextVersion text_ver, - GameSubtitleDB& db); +void compile_game_subtitle(const std::vector& filenames, GameTextVersion text_ver); diff --git a/goalc/data_compiler/game_text.cpp b/goalc/data_compiler/game_text.cpp index 175916ecf6..2cdb3d1dd0 100644 --- a/goalc/data_compiler/game_text.cpp +++ b/goalc/data_compiler/game_text.cpp @@ -60,34 +60,44 @@ std::string uppercase(const std::string& in) { } /*! - * Parse a game text file for all languages. - * The result is a vector> - * so result[lang_id][text_id] gets you the text in the given language. + * Parse a game text file. + * Information is added to the game text database. * - * The file should begin with (language-count x) with the given number of languages. - * Each entry should be (text-id "text-in-lang-0" "text-in-lang-1" ... ) - * The text id's can be out of order or missing entries. + * The file should begin with (language-id x y z...) with the given language IDs. + * Each entry should be (id "line for 1st language" "line for 2nd language" ...) + * This adds the text line to each of the specified languages. */ -std::vector> parse(const goos::Object& data, - std::string* group_name) { - std::vector> text; - bool languages_set = false; +void parse(const goos::Object& data, GameTextVersion text_ver, GameTextDB& db) { + auto font = get_font_bank(text_ver); + std::vector> banks; bool group_name_set = false; std::string possible_group_name; for_each_in_list(data.as_pair()->cdr, [&](const goos::Object& obj) { if (obj.is_pair()) { - auto& head = obj.as_pair()->car; - if (head.is_symbol() && head.as_symbol()->name == "language-count") { - if (languages_set) { - throw std::runtime_error("Languages has been set multiple times."); + auto& head = car(obj); + if (head.is_symbol() && head.as_symbol()->name == "language-id") { + if (banks.size() != 0) { + throw std::runtime_error("Languages have been set multiple times."); } - languages_set = true; - text.resize(get_int(car(cdr(obj)))); - if (!cdr(cdr(obj)).is_empty_list()) { - throw std::runtime_error("language-count has too many arguments"); + if (cdr(obj).is_empty_list()) { + throw std::runtime_error("At least one language must be set."); } + + if (!group_name_set) { + throw std::runtime_error("Text group must be set before languages."); + } + + for_each_in_list(cdr(obj), [&](const goos::Object& obj) { + auto lang = get_int(obj); + if (!db.bank_exists(possible_group_name, lang)) { + // database has no lang in this group yet + banks.push_back(db.add_bank(possible_group_name, std::make_shared(lang))); + } else { + banks.push_back(db.bank_by_id(possible_group_name, lang)); + } + }); } else if (head.is_symbol() && head.as_symbol()->name == "group-name") { if (group_name_set) { throw std::runtime_error("group-name has been set multiple times."); @@ -101,31 +111,26 @@ std::vector> parse(const goos::Object& data } else if (head.is_int()) { + if (banks.size() == 0) { + throw std::runtime_error("At least one language must be set before defining entries."); + } int i = 0; int id = head.as_int(); for_each_in_list(cdr(obj), [&](const goos::Object& entry) { - if (i >= int(text.size())) { - throw std::runtime_error( - "String has too many entries. There should be one per language"); - } - if (entry.is_string()) { - auto& map = text.at(i); - if (map.find(id) != map.end()) { - throw std::runtime_error("Entry appears more than once"); + if (i >= int(banks.size())) { + throw std::runtime_error(fmt::format("Too many strings in text id #x{:x}", id)); } - // TODO - auto font = get_font_bank(GameTextVersion::JAK1_V1); - map[id] = font->convert_utf8_to_game(entry.as_string()->data); + auto line = font->convert_utf8_to_game(entry.as_string()->data); + banks[i++]->set_line(id, line); } else { - throw std::runtime_error("Each entry must be a string"); + throw std::runtime_error(fmt::format("Non-string value in text id #x{:x}", id)); } - - i++; }); - if (i != int(text.size())) { - throw std::runtime_error("String did not have an entry for each language"); + if (i != int(banks.size())) { + throw std::runtime_error( + fmt::format("Not enough strings specified in text id #x{:x}", id)); } } else { throw std::runtime_error("Invalid game text file entry: " + head.print()); @@ -134,12 +139,9 @@ std::vector> parse(const goos::Object& data throw std::runtime_error("Invalid game text file"); } }); - - if (!group_name_set) { - throw std::runtime_error("group-name not set."); + if (banks.size() == 0) { + throw std::runtime_error("At least one language must be set."); } - *group_name = possible_group_name; - return text; } /* @@ -162,43 +164,33 @@ std::vector> parse(const goos::Object& data * Write game text data to a file. Uses the V2 object format which is identical between GOAL and * OpenGOAL, so this should produce exactly identical files to what is found in the game. */ -void compile(const std::vector>& text, - const std::string& group_name) { - if (text.empty()) { - return; - } - // get all text ID's we know - std::vector add_order; - add_order.reserve(text.front().size()); - for (auto& x : text.front()) { - add_order.push_back(x.first); - } - // and sort them to be added in order. This matches the game. - std::sort(add_order.begin(), add_order.end()); +void compile(GameTextDB& db) { + for (const auto& [group_name, banks] : db.groups()) { + for (const auto& [lang, bank] : banks) { + DataObjectGenerator gen; + gen.add_type_tag("game-text-info"); // type + gen.add_word(bank->lines().size()); // length + gen.add_word(lang); // language-id + // this string is found in the string pool. + gen.add_ref_to_string_in_pool(group_name); // group-name - for (int lang = 0; lang < int(text.size()); lang++) { - DataObjectGenerator gen; - gen.add_type_tag("game-text-info"); // type - gen.add_word(text.front().size()); // length - gen.add_word(lang); // language-id - // this string is found in the string pool. - gen.add_ref_to_string_in_pool(group_name); // group-name + // now add all the datas: (the lines are already sorted by id) + for (auto& [id, line] : bank->lines()) { + gen.add_word(id); // id + // these strings must be in the string pool, as sometimes there are duplicate + // strings in a single language, and these strings should be stored once and have multiple + // references to them. + gen.add_ref_to_string_in_pool(line); // text + } - // now add all the datas: - for (auto id : add_order) { - gen.add_word(id); // id - // these strings must be in the string pool, as sometimes there are duplicate - // strings in a single language, and these strings should be stored once and have multiple - // references to them. - gen.add_ref_to_string_in_pool(text.at(lang).at(id)); // text + auto data = gen.generate_v2(); + + file_util::create_dir_if_needed(file_util::get_file_path({"out", "iso"})); + file_util::write_binary_file( + file_util::get_file_path( + {"out", "iso", fmt::format("{}{}.TXT", lang, uppercase(group_name))}), + data.data(), data.size()); } - auto data = gen.generate_v2(); - - file_util::create_dir_if_needed(file_util::get_file_path({"out", "iso"})); - file_util::write_binary_file( - file_util::get_file_path( - {"out", "iso", fmt::format("{}{}.TXT", lang, uppercase(group_name))}), - data.data(), data.size()); } } } // namespace @@ -206,11 +198,13 @@ void compile(const std::vector>& text, /*! * Read a game text description file and generate GOAL objects. */ -void compile_game_text(const std::string& filename) { +void compile_game_text(const std::vector& filenames, GameTextVersion text_ver) { + GameTextDB db; goos::Reader reader; - auto code = reader.read_from_file({filename}); - printf("[Build Game Text] %s\n", filename.c_str()); - std::string group_name; - auto text_map = parse(code, &group_name); - compile(text_map, group_name); + for (auto& filename : filenames) { + fmt::print("[Build Game Text] {}\n", filename.c_str()); + auto code = reader.read_from_file({filename}); + parse(code, text_ver, db); + } + compile(db); } diff --git a/goalc/data_compiler/game_text.h b/goalc/data_compiler/game_text.h index d2aa968f64..4c419cbe3a 100644 --- a/goalc/data_compiler/game_text.h +++ b/goalc/data_compiler/game_text.h @@ -1,4 +1,62 @@ #pragma once +#include "common/util/FontUtils.h" +#include "common/util/Assert.h" #include +#include +#include +#include +#include -void compile_game_text(const std::string& filename); \ No newline at end of file +class GameTextBank { + public: + GameTextBank(int lang_id) : m_lang_id(lang_id) {} + + int lang() const { return m_lang_id; } + const std::map& lines() const { return m_lines; } + + bool line_exists(int id) const { return m_lines.find(id) != m_lines.end(); } + std::string line(int id) { return m_lines.at(id); } + void set_line(int id, std::string line) { m_lines[id] = line; } + + private: + int m_lang_id; + std::map m_lines; +}; + +/*! + * The text database contains a text bank for each language for each text group. + * Each text bank contains a list of text lines. Very simple. + */ +class GameTextDB { + public: + const std::unordered_map>>& groups() + const { + return m_banks; + } + const std::map>& banks(std::string group) const { + return m_banks.at(group); + } + + bool bank_exists(std::string group, int id) const { + if (m_banks.find(group) == m_banks.end()) + return false; + return m_banks.at(group).find(id) != m_banks.at(group).end(); + } + + std::shared_ptr add_bank(std::string group, std::shared_ptr bank) { + ASSERT(!bank_exists(group, bank->lang())); + m_banks[group][bank->lang()] = bank; + return bank; + } + std::shared_ptr bank_by_id(std::string group, int id) { + if (!bank_exists(group, id)) { + return nullptr; + } + return m_banks.at(group).at(id); + } + + private: + std::unordered_map>> m_banks; +}; + +void compile_game_text(const std::vector& filenames, GameTextVersion text_ver); diff --git a/goalc/make/MakeSystem.cpp b/goalc/make/MakeSystem.cpp index 75d282d41d..939400298c 100644 --- a/goalc/make/MakeSystem.cpp +++ b/goalc/make/MakeSystem.cpp @@ -63,8 +63,9 @@ MakeSystem::MakeSystem() { add_tool(); add_tool(); add_tool(); - add_tool(); add_tool(); + add_tool(); + add_tool(); } /*! @@ -376,4 +377,4 @@ void MakeSystem::set_constant(const std::string& name, const std::string& value) void MakeSystem::set_constant(const std::string& name, bool value) { m_goos.set_global_variable_to_symbol(name, value ? "#t" : "#f"); -} \ No newline at end of file +} diff --git a/goalc/make/Tools.cpp b/goalc/make/Tools.cpp index 2f90e549a4..e07dcd5b51 100644 --- a/goalc/make/Tools.cpp +++ b/goalc/make/Tools.cpp @@ -71,19 +71,20 @@ DgoDescription parse_desc_file(const std::string& filename, goos::Reader& reader static const std::unordered_map s_text_ver_enum_map = { {"jak1-v1", GameTextVersion::JAK1_V1}}; -std::unordered_map> open_subtitle_project( +std::unordered_map> open_text_project( + const std::string& kind, const std::string& filename) { goos::Reader reader; auto& proj = reader.read_from_file({filename}).as_pair()->cdr.as_pair()->car; if (!proj.is_pair() || !proj.as_pair()->car.is_symbol() || - proj.as_pair()->car.as_symbol()->name != "subtitle") { - throw std::runtime_error("invalid subtitle project"); + proj.as_pair()->car.as_symbol()->name != kind) { + throw std::runtime_error(fmt::format("invalid {} project", kind)); } std::unordered_map> inputs; goos::for_each_in_list(proj.as_pair()->cdr, [&](const goos::Object& o) { if (!o.is_pair()) { - throw std::runtime_error("invalid entry in subtitle project"); + throw std::runtime_error(fmt::format("invalid entry in {} project", kind)); } auto& ver = o.as_pair()->car.as_symbol()->name; @@ -152,11 +153,24 @@ bool GameCntTool::run(const ToolInput& task) { TextTool::TextTool() : Tool("text") {} -bool TextTool::run(const ToolInput& task) { +bool TextTool::needs_run(const ToolInput& task) { if (task.input.size() != 1) { throw std::runtime_error(fmt::format("Invalid amount of inputs to {} tool", name())); } - compile_game_text(task.input.at(0)); + + std::vector deps; + for (auto& [ver, inputs] : open_text_project("text", task.input.at(0))) { + for (auto& in : inputs) { + deps.push_back(in); + } + } + return Tool::needs_run({task.input, deps, task.output, task.arg}); +} + +bool TextTool::run(const ToolInput& task) { + for (auto& [ver, in] : open_text_project("text", task.input.at(0))) { + compile_game_text(in, ver); + } return true; } @@ -166,7 +180,7 @@ bool GroupTool::run(const ToolInput&) { return true; } -SubtitleTool::SubtitleTool(Compiler* compiler) : Tool("subtitle"), m_compiler(compiler) {} +SubtitleTool::SubtitleTool() : Tool("subtitle") {} bool SubtitleTool::needs_run(const ToolInput& task) { if (task.input.size() != 1) { @@ -174,7 +188,7 @@ bool SubtitleTool::needs_run(const ToolInput& task) { } std::vector deps; - for (auto& [ver, inputs] : open_subtitle_project(task.input.at(0))) { + for (auto& [ver, inputs] : open_text_project("subtitle", task.input.at(0))) { for (auto& in : inputs) { deps.push_back(in); } @@ -183,8 +197,8 @@ bool SubtitleTool::needs_run(const ToolInput& task) { } bool SubtitleTool::run(const ToolInput& task) { - for (auto& [ver, in] : open_subtitle_project(task.input.at(0))) { - compile_game_subtitle(in, ver, m_compiler->subtitle_db()); + for (auto& [ver, in] : open_text_project("subtitle", task.input.at(0))) { + compile_game_subtitle(in, ver); } return true; } diff --git a/goalc/make/Tools.h b/goalc/make/Tools.h index 49622d1320..f36df144f9 100644 --- a/goalc/make/Tools.h +++ b/goalc/make/Tools.h @@ -48,6 +48,7 @@ class TextTool : public Tool { public: TextTool(); bool run(const ToolInput& task) override; + bool needs_run(const ToolInput& task) override; }; class GroupTool : public Tool { @@ -58,10 +59,7 @@ class GroupTool : public Tool { class SubtitleTool : public Tool { public: - SubtitleTool(Compiler* compiler); + SubtitleTool(); bool run(const ToolInput& task) override; bool needs_run(const ToolInput& task) override; - - private: - Compiler* m_compiler; }; diff --git a/test/decompiler/reference/engine/collide/collide-cache-h_REF.gc b/test/decompiler/reference/engine/collide/collide-cache-h_REF.gc index fb6f9858c7..1829745414 100644 --- a/test/decompiler/reference/engine/collide/collide-cache-h_REF.gc +++ b/test/decompiler/reference/engine/collide/collide-cache-h_REF.gc @@ -185,15 +185,15 @@ (debug-draw (_type_) none 9) (fill-and-probe-using-line-sphere (_type_ vector vector float collide-kind process collide-tri-result int) float 10) (fill-and-probe-using-spheres (_type_ collide-using-spheres-params) symbol 11) - (fill-and-probe-using-y-probe (_type_ vector float collide-kind process collide-tri-result uint) float 12) + (fill-and-probe-using-y-probe (_type_ vector float collide-kind process-drawable collide-tri-result pat-surface) float 12) (fill-using-bounding-box (_type_ bounding-box collide-kind process-drawable pat-surface) none 13) (fill-using-line-sphere (_type_ vector vector float collide-kind process-drawable int) none 14) (fill-using-spheres (_type_ collide-using-spheres-params) none 15) - (fill-using-y-probe (_type_ vector float collide-kind process-drawable uint) none 16) + (fill-using-y-probe (_type_ vector float collide-kind process-drawable pat-surface) none 16) (initialize (_type_) none 17) (probe-using-line-sphere (_type_ vector vector float collide-kind collide-tri-result int) float 18) (probe-using-spheres (_type_ collide-using-spheres-params) symbol 19) - (probe-using-y-probe (_type_ vector float collide-kind collide-tri-result uint) float 20) + (probe-using-y-probe (_type_ vector float collide-kind collide-tri-result pat-surface) float 20) (fill-from-background (_type_ (function bsp-header int collide-list none) (function collide-cache object none)) none 21) (fill-from-foreground-using-box (_type_) none 22) (fill-from-foreground-using-line-sphere (_type_) none 23) diff --git a/test/decompiler/reference/engine/collide/collide-shape-h_REF.gc b/test/decompiler/reference/engine/collide/collide-shape-h_REF.gc index 23fe0d66a0..424b12a51d 100644 --- a/test/decompiler/reference/engine/collide/collide-shape-h_REF.gc +++ b/test/decompiler/reference/engine/collide/collide-shape-h_REF.gc @@ -377,7 +377,7 @@ (deftype collide-shape (trsqv) ((process process-drawable :offset-assert 140) (max-iteration-count uint8 :offset-assert 144) - (nav-flags uint8 :offset-assert 145) + (nav-flags nav-flags :offset-assert 145) (pad-byte uint8 2 :offset-assert 146) (pat-ignore-mask pat-surface :offset-assert 148) (event-self basic :offset-assert 152) @@ -638,17 +638,17 @@ (let ((obj (object-new allocation type-to-make (the-as int (-> type-to-make size))))) (set! (-> obj process) proc) (set! (-> obj max-iteration-count) (the-as uint 1)) - (set! (-> obj nav-flags) (the-as uint 1)) + (set! (-> obj nav-flags) (nav-flags navf0)) (set! (-> obj event-self) #f) (set! (-> obj event-other) #f) (set! (-> obj riders) #f) (set! (-> obj root-prim) #f) (case (-> proc type symbol) (('camera) - (set! (-> obj pat-ignore-mask) (new 'static 'pat-surface :skip #x2 :nocamera #x1)) + (set! (-> obj pat-ignore-mask) (new 'static 'pat-surface :nocamera #x1)) ) (else - (set! (-> obj pat-ignore-mask) (new 'static 'pat-surface :skip #x1 :noentity #x1)) + (set! (-> obj pat-ignore-mask) (new 'static 'pat-surface :noentity #x1)) ) ) (set! (-> obj trans w) 1.0) diff --git a/test/decompiler/reference/engine/draw/drawable_REF.gc b/test/decompiler/reference/engine/draw/drawable_REF.gc index 92c502e3d0..330beb78f1 100644 --- a/test/decompiler/reference/engine/draw/drawable_REF.gc +++ b/test/decompiler/reference/engine/draw/drawable_REF.gc @@ -1629,7 +1629,7 @@ ) (toggle-pause) ) - (when (or (not *progress-process*) (dummy-32 (-> *progress-process* 0))) + (when (or (not *progress-process*) (can-go-back? (-> *progress-process* 0))) (if (or (cpad-pressed? 0 select r3 start) (and (logtest? (-> *cpad-list* cpads 0 valid) 128) (= *master-mode* 'game) diff --git a/test/decompiler/reference/engine/game/collectables_REF.gc b/test/decompiler/reference/engine/game/collectables_REF.gc index 7b4bb8c7d6..a857724e62 100644 --- a/test/decompiler/reference/engine/game/collectables_REF.gc +++ b/test/decompiler/reference/engine/game/collectables_REF.gc @@ -3003,9 +3003,9 @@ s2-1 (the-as float 81920.0) (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) s1-1 - (the-as uint 1) + (new 'static 'pat-surface :noentity #x1) ) 0.0 ) diff --git a/test/decompiler/reference/engine/game/game-save_REF.gc b/test/decompiler/reference/engine/game/game-save_REF.gc index b46f74a558..63d6df7621 100644 --- a/test/decompiler/reference/engine/game/game-save_REF.gc +++ b/test/decompiler/reference/engine/game/game-save_REF.gc @@ -219,7 +219,7 @@ (((game-save-elt buzzer-total)) "buzzer-total" ) - (((game-save-elt moeny-per-level)) + (((game-save-elt money-per-level)) "money-per-level" ) (((game-save-elt money-total)) @@ -312,7 +312,7 @@ ) (when detail (case (-> tag elt-type) - (((game-save-elt moeny-per-level) (game-save-elt deaths-per-level)) + (((game-save-elt money-per-level) (game-save-elt deaths-per-level)) (dotimes (prog-lev-idx (-> tag elt-count)) (let ((lev-name (progress-level-index->string prog-lev-idx))) (if lev-name @@ -510,7 +510,7 @@ ) (let ((v1-56 (&+ v1-55 16))) (let ((a0-30 (the-as game-save-tag (&+ v1-56 0)))) - (set! (-> a0-30 elt-type) (game-save-elt moeny-per-level)) + (set! (-> a0-30 elt-type) (game-save-elt money-per-level)) (set! (-> a0-30 elt-count) 32) (set! (-> a0-30 elt-size) (the-as uint 1)) ) @@ -944,7 +944,7 @@ (((game-save-elt money-total)) (set! (-> obj money-total) (-> data user-float0)) ) - (((game-save-elt moeny-per-level)) + (((game-save-elt money-per-level)) (let ((v1-34 (min 32 (-> data elt-count)))) (dotimes (a0-76 v1-34) (set! (-> obj money-per-level a0-76) (-> (the-as (pointer uint8) (&+ (the-as pointer data) 16)) a0-76)) diff --git a/test/decompiler/reference/engine/game/projectiles_REF.gc b/test/decompiler/reference/engine/game/projectiles_REF.gc index d89f1b2f25..b2696513c4 100644 --- a/test/decompiler/reference/engine/game/projectiles_REF.gc +++ b/test/decompiler/reference/engine/game/projectiles_REF.gc @@ -1099,7 +1099,7 @@ (-> obj root-override shadow-pos) 8192.0 (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) 12288.0 81920.0 ) diff --git a/test/decompiler/reference/engine/gfx/shadow/shadow_REF.gc b/test/decompiler/reference/engine/gfx/shadow/shadow_REF.gc index 51c49fd558..234508baaf 100644 --- a/test/decompiler/reference/engine/gfx/shadow/shadow_REF.gc +++ b/test/decompiler/reference/engine/gfx/shadow/shadow_REF.gc @@ -115,14 +115,31 @@ ;; definition for function find-ground-and-draw-shadow ;; INFO: Return type mismatch int vs none. ;; Used lq/sq -(defun find-ground-and-draw-shadow ((arg0 vector) (arg1 vector) (arg2 float) (arg3 collide-kind) (arg4 process) (arg5 float) (arg6 float)) +(defun find-ground-and-draw-shadow ((arg0 vector) + (arg1 vector) + (arg2 float) + (arg3 collide-kind) + (arg4 process-drawable) + (arg5 float) + (arg6 float) + ) (let ((s2-0 (new 'stack-no-clear 'vector))) (set! (-> s2-0 quad) (-> arg0 quad)) (new 'stack-no-clear 'vector) (+! (-> s2-0 y) arg5) (let ((s4-0 (new 'stack-no-clear 'collide-tri-result))) (cond - ((>= (fill-and-probe-using-y-probe *collide-cache* s2-0 arg6 arg3 arg4 s4-0 (the-as uint 1)) 0.0) + ((>= (fill-and-probe-using-y-probe + *collide-cache* + s2-0 + arg6 + arg3 + arg4 + s4-0 + (new 'static 'pat-surface :noentity #x1) + ) + 0.0 + ) (if (!= arg2 0.0) (compute-and-draw-shadow s2-0 (-> s4-0 intersect) (-> s4-0 normal) (the-as vector arg2) arg6 (the-as float 0)) ) diff --git a/test/decompiler/reference/engine/nav/navigate-h_REF.gc b/test/decompiler/reference/engine/nav/navigate-h_REF.gc index 8c8eb2be1a..1038161a94 100644 --- a/test/decompiler/reference/engine/nav/navigate-h_REF.gc +++ b/test/decompiler/reference/engine/nav/navigate-h_REF.gc @@ -499,7 +499,7 @@ (goto cfg-4) ) (set! (-> obj max-spheres) sphere-count) - (set! (-> obj flags) (nav-control-flags bit8 bit13)) + (set! (-> obj flags) (nav-control-flags navcf8 navcf13)) (set! (-> obj mesh) (nav-mesh-connect (-> shape process) shape obj)) (let ((ent (-> shape process entity))) (set! (-> obj nearest-y-threshold) diff --git a/test/decompiler/reference/engine/nav/navigate_REF.gc b/test/decompiler/reference/engine/nav/navigate_REF.gc index 89fa53b84c..851df7c3ad 100644 --- a/test/decompiler/reference/engine/nav/navigate_REF.gc +++ b/test/decompiler/reference/engine/nav/navigate_REF.gc @@ -1271,14 +1271,14 @@ (let ((v1-1 (find-poly-fast obj arg0 arg1))) (when v1-1 (if arg2 - (set! (-> arg2 0) (logior (nav-control-flags bit20) (-> arg2 0))) + (set! (-> arg2 0) (logior (nav-control-flags navcf20) (-> arg2 0))) ) (set! s3-1 v1-1) (goto cfg-14) ) ) (if arg2 - (logclear! (-> arg2 0) (nav-control-flags bit20)) + (logclear! (-> arg2 0) (nav-control-flags navcf20)) ) (let ((s2-0 (new 'stack-no-clear 'inline-array 'nav-vertex 3))) (set! s3-1 (the-as nav-poly #f)) @@ -1750,7 +1750,7 @@ (when #t (set! (-> s5-0 debug-time) (the-as uint (-> *display* actual-frame-counter))) (add-debug-sphere - (logtest? (-> obj flags) (nav-control-flags bit1)) + (logtest? (-> obj flags) (nav-control-flags navcf1)) (bucket-id debug-draw0) (-> s5-0 bounds) (-> s5-0 bounds w) @@ -1758,7 +1758,7 @@ ) (add-debug-vector #t (bucket-id debug-draw1) (-> s5-0 origin) *x-vector* (meters 1.0) *color-red*) (add-debug-vector #t (bucket-id debug-draw1) (-> s5-0 origin) *z-vector* (meters 1.0) *color-blue*) - (when (logtest? (-> obj flags) (nav-control-flags bit2)) + (when (logtest? (-> obj flags) (nav-control-flags navcf2)) (dotimes (s3-0 (-> s5-0 vertex-count)) (add-debug-x #t @@ -1813,7 +1813,7 @@ ) ) ) - (when (logtest? (-> obj flags) (nav-control-flags bit3)) + (when (logtest? (-> obj flags) (nav-control-flags navcf3)) (dotimes (s3-2 (-> s5-0 poly-count)) (let ((s2-1 (-> s5-0 poly s3-2))) (debug-draw-poly s5-0 s2-1 (the-as rgba (cond @@ -1838,7 +1838,7 @@ ) ) ) - (when (logtest? (-> obj flags) (nav-control-flags bit4)) + (when (logtest? (-> obj flags) (nav-control-flags navcf4)) (let ((s1-1 add-debug-text-3d) (s0-1 #t) ) @@ -1862,7 +1862,7 @@ ) ) ) - (when (logtest? (-> obj flags) (nav-control-flags bit5)) + (when (logtest? (-> obj flags) (nav-control-flags navcf5)) (if (-> obj next-poly) (debug-draw-poly s5-0 (-> obj next-poly) *color-cyan*) ) @@ -1873,7 +1873,7 @@ (debug-draw-poly s5-0 (-> obj current-poly) *color-red*) ) ) - (when (logtest? (-> obj flags) (nav-control-flags bit7)) + (when (logtest? (-> obj flags) (nav-control-flags navcf7)) (dotimes (s3-3 (the-as int (-> s5-0 static-sphere-count))) (let ((s2-2 (-> s5-0 static-sphere s3-3))) (add-debug-sphere #t (bucket-id debug-draw0) (the-as vector s2-2) (-> s2-2 trans w) *color-blue*) @@ -1906,7 +1906,7 @@ ) ) ) - (when (logtest? (-> obj flags) (nav-control-flags bit6)) + (when (logtest? (-> obj flags) (nav-control-flags navcf6)) (when (and (-> obj portal 0) (-> obj portal 1)) (let ((v1-80 (-> s5-0 origin)) (a2-22 (new 'stack-no-clear 'vector)) @@ -1946,7 +1946,7 @@ (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) ) ) - (when (logtest? (-> obj flags) (nav-control-flags bit7)) + (when (logtest? (-> obj flags) (nav-control-flags navcf7)) (add-debug-sphere #t (bucket-id debug-draw1) @@ -2012,7 +2012,7 @@ ;; INFO: Return type mismatch int vs none. (defmethod set-current-poly! nav-control ((obj nav-control) (arg0 nav-poly)) (set! (-> obj current-poly) arg0) - (logior! (-> obj flags) (nav-control-flags bit9)) + (logior! (-> obj flags) (nav-control-flags navcf9)) 0 (none) ) @@ -2066,7 +2066,7 @@ ;; INFO: Return type mismatch int vs none. ;; Used lq/sq (defun add-collide-shape-spheres ((arg0 nav-control) (arg1 collide-shape) (arg2 vector)) - (when (logtest? (-> arg1 nav-flags) 1) + (when (logtest? (-> arg1 nav-flags) (nav-flags navf0)) (set! (-> arg2 quad) (-> arg1 root-prim prim-core world-sphere quad)) (set! (-> arg2 w) (-> arg1 nav-radius)) (let ((s4-0 arg0) @@ -2088,7 +2088,7 @@ ) 0 ) - (when (logtest? (-> arg1 nav-flags) 2) + (when (logtest? (-> arg1 nav-flags) (nav-flags navf1)) (let ((s5-1 (-> arg1 process nav extra-nav-sphere))) (when (< (-> arg0 num-spheres) (-> arg0 max-spheres)) (let* ((s4-1 (-> arg0 sphere (-> arg0 num-spheres))) @@ -2127,13 +2127,13 @@ (s3-0 (new 'stack-no-clear 'vector)) ) (when (and *target* - (or (logtest? (-> obj flags) (nav-control-flags bit11)) (logtest? (-> *target* state-flags) #x80f8)) + (or (logtest? (-> obj flags) (nav-control-flags navcf11)) (logtest? (-> *target* state-flags) #x80f8)) ) (let ((s2-0 obj) (s1-0 (-> *target* control)) ) (let ((s0-0 s3-0)) - (when (logtest? (-> s1-0 nav-flags) 1) + (when (logtest? (-> s1-0 nav-flags) (nav-flags navf0)) (set! (-> s0-0 quad) (-> s1-0 root-prim prim-core world-sphere quad)) (set! (-> s0-0 w) (-> s1-0 nav-radius)) (set! sv-32 s2-0) @@ -2153,7 +2153,7 @@ 0 ) ) - (when (logtest? (-> s1-0 nav-flags) 2) + (when (logtest? (-> s1-0 nav-flags) (nav-flags navf1)) (let ((s1-1 (-> s1-0 process nav extra-nav-sphere))) (when (< (-> s2-0 num-spheres) (-> s2-0 max-spheres)) (let* ((s0-1 (-> s2-0 sphere (-> s2-0 num-spheres))) @@ -2173,7 +2173,7 @@ ) ) ) - (when (logtest? (-> obj flags) (nav-control-flags bit13)) + (when (logtest? (-> obj flags) (nav-control-flags navcf13)) (countdown (s2-1 (-> obj mesh static-sphere-count)) (let ((s1-2 obj) (s0-2 (-> obj mesh static-sphere s2-1)) @@ -2203,7 +2203,7 @@ (when (not (or (= s0-3 (-> obj shape)) (zero? (logand arg0 (-> s0-3 root-prim prim-core collide-as))))) (let ((s1-3 obj)) (set! sv-112 s3-0) - (when (logtest? (-> s0-3 nav-flags) 1) + (when (logtest? (-> s0-3 nav-flags) (nav-flags navf0)) (set! (-> sv-112 quad) (-> s0-3 root-prim prim-core world-sphere quad)) (set! (-> sv-112 w) (-> s0-3 nav-radius)) (set! sv-80 s1-3) @@ -2226,7 +2226,7 @@ ) 0 ) - (when (logtest? (-> s0-3 nav-flags) 2) + (when (logtest? (-> s0-3 nav-flags) (nav-flags navf1)) (let ((s0-4 (-> s0-3 process nav extra-nav-sphere))) (when (< (-> s1-3 num-spheres) (-> s1-3 max-spheres)) (set! sv-128 (-> s1-3 sphere (-> s1-3 num-spheres))) @@ -2662,7 +2662,7 @@ (set! (-> obj blocked-travel quad) (-> obj travel quad)) (let ((f0-0 (vector-xz-length (-> obj travel)))) (when (and (>= f30-0 f0-0) (< f0-0 204.8)) - (set! (-> obj flags) (logior (nav-control-flags bit17) (-> obj flags))) + (set! (-> obj flags) (logior (nav-control-flags navcf17) (-> obj flags))) (set! (-> obj block-time) (-> *display* base-frame-counter)) (set! (-> obj block-count) (+ 1.0 (-> obj block-count))) (if (-> obj block-event) @@ -2709,21 +2709,21 @@ ) (cond ((or (vector= arg2 (-> obj target-pos)) (< (fabs f28-0) 364.0889)) - (set! (-> obj flags) (logior (nav-control-flags bit21) (-> obj flags))) + (set! (-> obj flags) (logior (nav-control-flags navcf21) (-> obj flags))) (set! (-> arg0 quad) (-> arg2 quad)) ) (else (let ((s2-1 (vector-z-quaternion! (new 'stack-no-clear 'vector) (-> arg1 quat)))) (vector-rotate-y! s2-1 s2-1 (fmax (fmin f28-0 f30-0) (- f30-0))) (vector-normalize! s2-1 819.2) - (logclear! (-> obj flags) (nav-control-flags bit21)) + (logclear! (-> obj flags) (nav-control-flags navcf21)) (vector+! arg0 (-> arg1 trans) s2-1) ) (when (or (not (dummy-16 obj arg0)) - (logtest? (nav-control-flags bit17) (-> obj flags)) - (zero? (logand (-> obj flags) (nav-control-flags bit10))) + (logtest? (nav-control-flags navcf17) (-> obj flags)) + (zero? (logand (-> obj flags) (nav-control-flags navcf10))) ) - (set! (-> obj flags) (logior (nav-control-flags bit21) (-> obj flags))) + (set! (-> obj flags) (logior (nav-control-flags navcf21) (-> obj flags))) (vector-! (-> obj travel) arg2 (-> arg1 trans)) (set! (-> arg0 quad) (-> arg2 quad)) ) @@ -2938,7 +2938,7 @@ v1-0 (-> obj current-poly) (-> obj travel) - (zero? (logand (-> obj flags) (nav-control-flags bit12))) + (zero? (logand (-> obj flags) (nav-control-flags navcf12))) arg0 arg1 ) @@ -3149,7 +3149,7 @@ sv-84 sv-88 (-> obj travel) - (zero? (logand (-> obj flags) (nav-control-flags bit12))) + (zero? (logand (-> obj flags) (nav-control-flags navcf12))) 204.8 s5-1 ) @@ -3254,9 +3254,9 @@ (set! (-> obj old-travel quad) (-> obj travel quad)) (-> obj block-count) (set! (-> obj block-count) (seek (-> obj block-count) 0.0 0.016666668)) - (logclear! (-> obj flags) (nav-control-flags bit9 bit17 bit18 bit19)) + (logclear! (-> obj flags) (nav-control-flags navcf9 navcf17 navcf18 navcf19)) (TODO-RENAME-27 obj) - (if (logtest? (-> obj flags) (nav-control-flags bit8)) + (if (logtest? (-> obj flags) (nav-control-flags navcf8)) (TODO-RENAME-28 obj (collide-kind background cak-1 @@ -3331,7 +3331,7 @@ (let ((s5-1 (new 'stack-no-clear 'nav-gap-info))) (when (< (vector-xz-length (-> obj travel)) 204.8) (cond - ((logtest? (nav-control-flags bit17) (-> obj flags)) + ((logtest? (nav-control-flags navcf17) (-> obj flags)) ) ((-> obj next-poly) (cond @@ -3349,7 +3349,7 @@ ) ) (else - (set! (-> obj flags) (logior (nav-control-flags bit19) (-> obj flags))) + (set! (-> obj flags) (logior (nav-control-flags navcf19) (-> obj flags))) ) ) ) diff --git a/test/decompiler/reference/engine/target/target-death_REF.gc b/test/decompiler/reference/engine/target/target-death_REF.gc index b68f9ffe3a..585356e4c0 100644 --- a/test/decompiler/reference/engine/target/target-death_REF.gc +++ b/test/decompiler/reference/engine/target/target-death_REF.gc @@ -1185,7 +1185,7 @@ (clear-pending-settings-from-process *setting-control* self 'process-mask) (clear-pending-settings-from-process *setting-control* self 'allow-progress) (restore-collide-with-as (-> self control)) - (set! (-> self control pat-ignore-mask) (new 'static 'pat-surface :skip #x1 :noentity #x1)) + (set! (-> self control pat-ignore-mask) (new 'static 'pat-surface :noentity #x1)) (set! (-> self control dynam gravity-max) (-> self control unknown-dynamics00 gravity-max)) (set! (-> self control dynam gravity-length) (-> self control unknown-dynamics00 gravity-length)) (none) diff --git a/test/decompiler/reference/engine/target/target-part_REF.gc b/test/decompiler/reference/engine/target/target-part_REF.gc index 676edd1a22..802ab89d84 100644 --- a/test/decompiler/reference/engine/target/target-part_REF.gc +++ b/test/decompiler/reference/engine/target/target-part_REF.gc @@ -43,7 +43,7 @@ (collide-kind background cak-1 cak-2 cak-3 water powerup crate enemy wall-object ground-object mother-spider) s5-0 s3-0 - (the-as uint 1) + (new 'static 'pat-surface :noentity #x1) ) 0.0 ) diff --git a/test/decompiler/reference/engine/ui/progress-h_REF.gc b/test/decompiler/reference/engine/ui/progress-h_REF.gc index 0360733354..f9350cb6d5 100644 --- a/test/decompiler/reference/engine/ui/progress-h_REF.gc +++ b/test/decompiler/reference/engine/ui/progress-h_REF.gc @@ -84,13 +84,13 @@ ;; definition of type game-option (deftype game-option (basic) - ((option-type uint64 :offset-assert 8) - (name game-text-id :offset-assert 16) - (scale basic :offset-assert 20) - (param1 float :offset-assert 24) - (param2 float :offset-assert 28) - (param3 int32 :offset-assert 32) - (value-to-modify pointer :offset-assert 36) + ((option-type game-option-type :offset-assert 8) + (name game-text-id :offset-assert 16) + (scale symbol :offset-assert 20) + (param1 float :offset-assert 24) + (param2 float :offset-assert 28) + (param3 game-option-menu :offset-assert 32) + (value-to-modify pointer :offset-assert 36) ) :method-count-assert 9 :size-assert #x28 @@ -130,8 +130,8 @@ (force-transition basic :offset-assert 180) (stat-transition basic :offset-assert 184) (level-transition int32 :offset-assert 188) - (language-selection uint64 :offset-assert 192) - (language-direction basic :offset-assert 200) + (language-selection language-enum :offset-assert 192) + (language-direction symbol :offset-assert 200) (language-transition basic :offset-assert 204) (language-x-offset int32 :offset-assert 208) (sides-x-scale float :offset-assert 212) @@ -172,12 +172,12 @@ :size-assert #x2dc :flag-assert #x3b027002dc (:methods - (dummy-14 (_type_) none 14) - (dummy-15 (_type_) none 15) - (dummy-16 (_type_) none 16) + (progress-dummy-14 (_type_) none 14) + (progress-dummy-15 (_type_) none 15) + (progress-dummy-16 (_type_) none 16) (draw-progress (_type_) none 17) - (dummy-18 () none 18) - (dummy-19 (_type_) symbol 19) + (progress-dummy-18 () none 18) + (visible? (_type_) symbol 19) (hidden? (_type_) symbol 20) (adjust-sprites (_type_) none 21) (adjust-icons (_type_) none 22) @@ -187,10 +187,10 @@ (draw-buzzer-screen (_type_ int) none 26) (draw-notice-screen (_type_) none 27) (draw-options (_type_ int int float) none 28) - (dummy-29 (_type_) none 29) + (respond-common (_type_) none 29) (respond-progress (_type_) none 30) - (dummy-31 (_type_) none 31) - (dummy-32 (_type_) symbol 32) + (respond-memcard (_type_) none 31) + (can-go-back? (_type_) symbol 32) (initialize-icons (_type_) none 33) (initialize-particles (_type_) none 34) (draw-memcard-storage-error (_type_ font-context) none 35) @@ -202,16 +202,16 @@ (draw-memcard-auto-save-error (_type_ font-context) none 41) (draw-memcard-removed (_type_ font-context) none 42) (draw-memcard-error (_type_ font-context) none 43) - (dummy-44 (_type_) none 44) + (progress-dummy-44 (_type_) none 44) (push! (_type_) none 45) (pop! (_type_) none 46) - (dummy-47 (_type_) none 47) + (progress-dummy-47 (_type_) none 47) (enter! (_type_ progress-screen int) none 48) (draw-memcard-format (_type_ font-context) none 49) (draw-auto-save (_type_ font-context) none 50) (set-transition-progress! (_type_ int) none 51) (set-transition-speed! (_type_) none 52) - (dummy-53 (_type_ progress-screen) progress-screen 53) + (set-memcard-screen (_type_ progress-screen) progress-screen 53) (draw-pal-change-to-60hz (_type_ font-context) none 54) (draw-pal-now-60hz (_type_ font-context) none 55) (draw-no-disc (_type_ font-context) none 56) diff --git a/test/decompiler/reference/engine/ui/progress/progress-draw_REF.gc b/test/decompiler/reference/engine/ui/progress/progress-draw_REF.gc index 081bd9e4dd..96b069d6ea 100644 --- a/test/decompiler/reference/engine/ui/progress/progress-draw_REF.gc +++ b/test/decompiler/reference/engine/ui/progress/progress-draw_REF.gc @@ -1579,7 +1579,7 @@ (sv-464 int) (sv-480 int) (sv-496 int) - (sv-512 uint) + (sv-512 int) (sv-528 (function _varargs_ object)) (sv-544 string) (sv-560 string) @@ -1629,7 +1629,7 @@ (set! sv-144 s2-1) (let ((v1-18 (-> s3-0 s0-0 option-type))) (cond - ((= v1-18 7) + ((= v1-18 (game-option-type yes-no)) (cond ((-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) (set! sv-160 format) @@ -1655,7 +1655,7 @@ ) ) ) - ((or (= v1-18 6) (= v1-18 8)) + ((or (= v1-18 (game-option-type menu)) (= v1-18 (game-option-type button))) (cond ((nonzero? (-> s3-0 s0-0 name)) (set! sv-912 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) @@ -1673,7 +1673,7 @@ ) (set! (-> sv-112 origin x) (the float (- sv-128 (-> obj left-x-offset)))) (case (-> s3-0 s0-0 option-type) - ((3) + (((game-option-type center-screen)) (set! (-> sv-112 origin y) (the float (+ s2-1 -20))) ) (else @@ -1693,7 +1693,7 @@ (sv-288 a0-23 a1-11 a2-10 a3-4 t0-1) ) (case (-> s3-0 s0-0 option-type) - ((3) + (((game-option-type center-screen)) (set! sv-144 (+ s2-1 3)) sv-144 ) @@ -1702,243 +1702,243 @@ sv-144 ) ) - (let ((v1-81 (-> s3-0 s0-0 option-type))) - (cond - ((zero? v1-81) - (let* ((v1-82 (the-as uint #x8000ffff)) - (f0-12 (* 0.01 (-> (the-as (pointer float) (-> s3-0 s0-0 value-to-modify))))) - (a0-34 (logior (logand v1-82 -256) (shr (shl (the int (+ 64.0 (* 191.0 f0-12))) 56) 56))) - (a3-5 (logior (logand a0-34 -65281) (shr (shl (shr (shl a0-34 56) 56) 56) 48))) - ) - (draw-percent-bar (- 75 (-> obj left-x-offset)) (+ s2-1 8) f0-12 (the-as int a3-5)) - ) - (set! sv-304 format) - (let ((a0-42 (clear *temp-string*)) - (a1-13 "~D") - (a2-12 (the int (-> (the-as (pointer float) (-> s3-0 s0-0 value-to-modify))))) - ) - (sv-304 a0-42 a1-13 a2-12) - ) - (set! sv-912 *temp-string*) - (set! sv-128 (+ (the int (* 2.5 (-> (the-as (pointer float) (-> s3-0 s0-0 value-to-modify))))) -100)) - sv-128 - ) - ((= v1-81 2) - (cond - ((-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) - (set! sv-320 format) - (set! sv-336 (clear *temp-string*)) - (set! sv-352 "~30L~S~0L ~S") - (set! sv-368 (lookup-text! *common-text* (game-text-id on) #f)) - (let ((a3-6 (lookup-text! *common-text* (game-text-id off) #f))) - (sv-320 sv-336 sv-352 sv-368 a3-6) + (case (-> s3-0 s0-0 option-type) + (((game-option-type slider)) + (let* ((v1-82 (the-as uint #x8000ffff)) + (f0-12 (* 0.01 (-> (the-as (pointer float) (-> s3-0 s0-0 value-to-modify))))) + (a0-34 (logior (logand v1-82 -256) (shr (shl (the int (+ 64.0 (* 191.0 f0-12))) 56) 56))) + (a3-5 (logior (logand a0-34 -65281) (shr (shl (shr (shl a0-34 56) 56) 56) 48))) ) - (set! sv-912 *temp-string*) - sv-912 - ) - (else - (set! sv-384 format) - (set! sv-400 (clear *temp-string*)) - (set! sv-416 "~0L~S ~30L~S~1L") - (set! sv-432 (lookup-text! *common-text* (game-text-id on) #f)) - (let ((a3-7 (lookup-text! *common-text* (game-text-id off) #f))) - (sv-384 sv-400 sv-416 sv-432 a3-7) - ) - (set! sv-912 *temp-string*) - sv-912 + (draw-percent-bar (- 75 (-> obj left-x-offset)) (+ s2-1 8) f0-12 (the-as int a3-5)) + ) + (set! sv-304 format) + (let ((a0-42 (clear *temp-string*)) + (a1-13 "~D") + (a2-12 (the int (-> (the-as (pointer float) (-> s3-0 s0-0 value-to-modify))))) ) + (sv-304 a0-42 a1-13 a2-12) + ) + (set! sv-912 *temp-string*) + (set! sv-128 (+ (the int (* 2.5 (-> (the-as (pointer float) (-> s3-0 s0-0 value-to-modify))))) -100)) + sv-128 + ) + (((game-option-type on-off)) + (cond + ((-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) + (set! sv-320 format) + (set! sv-336 (clear *temp-string*)) + (set! sv-352 "~30L~S~0L ~S") + (set! sv-368 (lookup-text! *common-text* (game-text-id on) #f)) + (let ((a3-6 (lookup-text! *common-text* (game-text-id off) #f))) + (sv-320 sv-336 sv-352 sv-368 a3-6) + ) + (set! sv-912 *temp-string*) + sv-912 + ) + (else + (set! sv-384 format) + (set! sv-400 (clear *temp-string*)) + (set! sv-416 "~0L~S ~30L~S~1L") + (set! sv-432 (lookup-text! *common-text* (game-text-id on) #f)) + (let ((a3-7 (lookup-text! *common-text* (game-text-id off) #f))) + (sv-384 sv-400 sv-416 sv-432 a3-7) + ) + (set! sv-912 *temp-string*) + sv-912 ) ) - ((= v1-81 1) - (set! sv-512 (-> obj language-selection)) - (set! sv-448 (-> (the-as (pointer uint64) (-> s3-0 s0-0 value-to-modify)))) - (if (and (zero? (scf-get-territory)) - (not (and (= *progress-cheat* 'language) (cpad-hold? 0 l2) (cpad-hold? 0 r2))) - ) - (set! sv-464 5) - (set! sv-464 6) - ) - (if (-> obj language-transition) - (set! (-> obj language-x-offset) - (seekl (-> obj language-x-offset) 200 (the int (* 10.0 (-> *display* time-adjust-ratio)))) - ) - ) - (when (>= (-> obj language-x-offset) 100) - (set! (-> obj language-selection) sv-448) - (set! sv-512 sv-448) - (set! (-> obj language-transition) #f) - (set! (-> obj language-x-offset) 0) - 0 + ) + (((game-option-type language)) + (set! sv-512 (the-as int (-> obj language-selection))) + (set! sv-448 (-> (the-as (pointer uint64) (-> s3-0 s0-0 value-to-modify)))) + (if (and (zero? (scf-get-territory)) + (not (and (= *progress-cheat* 'language) (cpad-hold? 0 l2) (cpad-hold? 0 r2))) + ) + (set! sv-464 5) + (set! sv-464 6) ) - (set! (-> sv-112 origin y) (the float (+ s2-1 3))) - (let ((a0-62 sv-112)) - (set! (-> a0-62 color) (font-color lighter-lighter-blue)) + (if (-> obj language-transition) + (set! (-> obj language-x-offset) + (seekl (-> obj language-x-offset) 200 (the int (* 10.0 (-> *display* time-adjust-ratio)))) + ) ) + (when (>= (-> obj language-x-offset) 100) + (set! (-> obj language-selection) (the-as language-enum sv-448)) + (set! sv-512 (the-as int sv-448)) + (set! (-> obj language-transition) #f) + (set! (-> obj language-x-offset) 0) 0 - (set! sv-480 (mod (the-as int (+ sv-512 1)) sv-464)) - (let ((a0-66 (mod (+ sv-464 -1 sv-512) sv-464)) - (v1-153 (mod (the-as int (+ sv-512 2)) sv-464)) - ) - (set! sv-496 (mod (+ sv-464 -2 sv-512) sv-464)) - (cond - ((-> obj language-direction) - (let ((a2-22 (- 200 (+ (-> obj language-x-offset) 100)))) - (print-language-name a0-66 sv-112 a2-22 #f) - ) - (let ((a2-23 (+ (-> obj language-x-offset) 100))) - (cond - ((< a2-23 150) - (let ((t9-27 print-language-name) - (a1-30 sv-112) - (a3-9 #t) - ) - (t9-27 sv-480 a1-30 a2-23 a3-9) - ) + ) + (set! (-> sv-112 origin y) (the float (+ s2-1 3))) + (let ((a0-62 sv-112)) + (set! (-> a0-62 color) (font-color lighter-lighter-blue)) + ) + 0 + (set! sv-480 (mod (+ sv-512 1) sv-464)) + (let ((a0-66 (mod (+ sv-464 -1 sv-512) sv-464)) + (v1-153 (mod (+ sv-512 2) sv-464)) + ) + (set! sv-496 (mod (+ sv-464 -2 sv-512) sv-464)) + (cond + ((-> obj language-direction) + (let ((a2-22 (- 200 (+ (-> obj language-x-offset) 100)))) + (print-language-name a0-66 sv-112 a2-22 #f) + ) + (let ((a2-23 (+ (-> obj language-x-offset) 100))) + (cond + ((< a2-23 150) + (let ((t9-27 print-language-name) + (a1-30 sv-112) + (a3-9 #t) + ) + (t9-27 sv-480 a1-30 a2-23 a3-9) ) - (else - (let ((a2-24 (- 200 (-> obj language-x-offset))) - (t9-28 print-language-name) - (a1-31 sv-112) - (a3-10 #f) - ) - (t9-28 sv-496 a1-31 a2-24 a3-10) - ) + ) + (else + (let ((a2-24 (- 200 (-> obj language-x-offset))) + (t9-28 print-language-name) + (a1-31 sv-112) + (a3-10 #f) + ) + (t9-28 sv-496 a1-31 a2-24 a3-10) ) ) ) ) - (else - (let ((a2-25 (+ (-> obj language-x-offset) 100))) - (cond - ((< a2-25 150) - (print-language-name a0-66 sv-112 a2-25 #f) - ) - (else - (let ((a2-26 (- 200 (-> obj language-x-offset)))) - (print-language-name v1-153 sv-112 a2-26 #t) - ) + ) + (else + (let ((a2-25 (+ (-> obj language-x-offset) 100))) + (cond + ((< a2-25 150) + (print-language-name a0-66 sv-112 a2-25 #f) + ) + (else + (let ((a2-26 (- 200 (-> obj language-x-offset)))) + (print-language-name v1-153 sv-112 a2-26 #t) ) ) ) - (let ((a2-27 (- 200 (+ (-> obj language-x-offset) 100)))) - (print-language-name sv-480 sv-112 a2-27 #t) - ) + ) + (let ((a2-27 (- 200 (+ (-> obj language-x-offset) 100)))) + (print-language-name sv-480 sv-112 a2-27 #t) ) ) ) - (when (not (-> obj language-transition)) - (let ((a0-75 sv-112)) - (set! (-> a0-75 color) (font-color yellow-green-2)) + ) + (when (not (-> obj language-transition)) + (let ((a0-75 sv-112)) + (set! (-> a0-75 color) (font-color yellow-green-2)) + ) + ) + (let ((t9-32 print-language-name) + (a1-37 sv-112) + (a2-28 (-> obj language-x-offset)) + (a3-14 (-> obj language-direction)) ) - ) - (let ((t9-32 print-language-name) - (a1-37 sv-112) - (a2-28 (-> obj language-x-offset)) - (a3-14 (-> obj language-direction)) - ) - (t9-32 (the-as int sv-512) a1-37 a2-28 (the-as symbol a3-14)) - ) + (t9-32 sv-512 a1-37 a2-28 a3-14) ) - ((= v1-81 3) - (set! sv-912 (lookup-text! *common-text* (game-text-id move-dpad) #f)) - sv-912 - ) - ((= v1-81 4) - (cond - ((= (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) 'aspect4x3) - (set! sv-528 format) - (set! sv-544 (clear *temp-string*)) - (set! sv-560 "~30L~S~0L ~S") - (set! sv-576 (lookup-text! *common-text* (game-text-id 4x3) #f)) - (let ((a3-15 (lookup-text! *common-text* (game-text-id 16x9) #f))) - (sv-528 sv-544 sv-560 sv-576 a3-15) - ) - (set! sv-912 *temp-string*) - sv-912 + ) + (((game-option-type center-screen)) + (set! sv-912 (lookup-text! *common-text* (game-text-id move-dpad) #f)) + sv-912 + ) + (((game-option-type aspect-ratio)) + (cond + ((= (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) 'aspect4x3) + (set! sv-528 format) + (set! sv-544 (clear *temp-string*)) + (set! sv-560 "~30L~S~0L ~S") + (set! sv-576 (lookup-text! *common-text* (game-text-id 4x3) #f)) + (let ((a3-15 (lookup-text! *common-text* (game-text-id 16x9) #f))) + (sv-528 sv-544 sv-560 sv-576 a3-15) ) - (else - (set! sv-592 format) - (set! sv-608 (clear *temp-string*)) - (set! sv-624 "~0L~S ~30L~S~1L") - (set! sv-640 (lookup-text! *common-text* (game-text-id 4x3) #f)) - (let ((a3-16 (lookup-text! *common-text* (game-text-id 16x9) #f))) - (sv-592 sv-608 sv-624 sv-640 a3-16) - ) - (set! sv-912 *temp-string*) - sv-912 + (set! sv-912 *temp-string*) + sv-912 + ) + (else + (set! sv-592 format) + (set! sv-608 (clear *temp-string*)) + (set! sv-624 "~0L~S ~30L~S~1L") + (set! sv-640 (lookup-text! *common-text* (game-text-id 4x3) #f)) + (let ((a3-16 (lookup-text! *common-text* (game-text-id 16x9) #f))) + (sv-592 sv-608 sv-624 sv-640 a3-16) ) + (set! sv-912 *temp-string*) + sv-912 ) ) - ((= v1-81 5) - (cond - ((= (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) 'ntsc) - (set! sv-656 format) - (set! sv-672 (clear *temp-string*)) - (set! sv-688 "~0L~S ~30L~S~1L") - (set! sv-704 (lookup-text! *common-text* (game-text-id 50hz) #f)) - (let ((a3-17 (lookup-text! *common-text* (game-text-id 60hz) #f))) - (sv-656 sv-672 sv-688 sv-704 a3-17) - ) - (set! sv-912 *temp-string*) - sv-912 + ) + (((game-option-type video-mode)) + (cond + ((= (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) 'ntsc) + (set! sv-656 format) + (set! sv-672 (clear *temp-string*)) + (set! sv-688 "~0L~S ~30L~S~1L") + (set! sv-704 (lookup-text! *common-text* (game-text-id 50hz) #f)) + (let ((a3-17 (lookup-text! *common-text* (game-text-id 60hz) #f))) + (sv-656 sv-672 sv-688 sv-704 a3-17) ) - (else - (set! sv-720 format) - (set! sv-736 (clear *temp-string*)) - (set! sv-752 "~30L~S~0L ~S") - (set! sv-768 (lookup-text! *common-text* (game-text-id 50hz) #f)) - (let ((a3-18 (lookup-text! *common-text* (game-text-id 60hz) #f))) - (sv-720 sv-736 sv-752 sv-768 a3-18) - ) - (set! sv-912 *temp-string*) - sv-912 + (set! sv-912 *temp-string*) + sv-912 + ) + (else + (set! sv-720 format) + (set! sv-736 (clear *temp-string*)) + (set! sv-752 "~30L~S~0L ~S") + (set! sv-768 (lookup-text! *common-text* (game-text-id 50hz) #f)) + (let ((a3-18 (lookup-text! *common-text* (game-text-id 60hz) #f))) + (sv-720 sv-736 sv-752 sv-768 a3-18) ) + (set! sv-912 *temp-string*) + sv-912 ) ) - ) + ) ) ) (else - (let ((v1-195 (-> s3-0 s0-0 option-type))) - (cond - ((or (zero? v1-195) (= v1-195 3) (= v1-195 4) (= v1-195 5)) - (set! sv-912 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) - sv-912 - ) - ((= v1-195 2) - (set! sv-784 format) - (set! sv-800 (clear *temp-string*)) - (set! sv-816 "~S: ~S") - (set! sv-832 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) - (let ((a3-19 (if (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) - (lookup-text! *common-text* (game-text-id on) #f) - (lookup-text! *common-text* (game-text-id off) #f) - ) - ) - ) - (sv-784 sv-800 sv-816 sv-832 a3-19) - ) - (set! sv-912 *temp-string*) - sv-912 - ) - ((= v1-195 1) - (set! sv-848 format) - (set! sv-864 (clear *temp-string*)) - (set! sv-880 "~S: ~S") - (set! sv-896 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) - (let ((a3-20 (lookup-text! - *common-text* - (-> *language-name-remap* (-> (the-as (pointer uint64) (-> s3-0 s0-0 value-to-modify)))) - #f - ) - ) - ) - (sv-848 sv-864 sv-880 sv-896 a3-20) - ) - (set! sv-912 *temp-string*) - sv-912 - ) + (case (-> s3-0 s0-0 option-type) + (((game-option-type slider) + (game-option-type center-screen) + (game-option-type aspect-ratio) + (game-option-type video-mode) ) + (set! sv-912 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) + sv-912 + ) + (((game-option-type on-off)) + (set! sv-784 format) + (set! sv-800 (clear *temp-string*)) + (set! sv-816 "~S: ~S") + (set! sv-832 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) + (let ((a3-19 (if (-> (the-as (pointer uint32) (-> s3-0 s0-0 value-to-modify))) + (lookup-text! *common-text* (game-text-id on) #f) + (lookup-text! *common-text* (game-text-id off) #f) + ) + ) + ) + (sv-784 sv-800 sv-816 sv-832 a3-19) + ) + (set! sv-912 *temp-string*) + sv-912 + ) + (((game-option-type language)) + (set! sv-848 format) + (set! sv-864 (clear *temp-string*)) + (set! sv-880 "~S: ~S") + (set! sv-896 (lookup-text! *common-text* (-> s3-0 s0-0 name) #f)) + (let ((a3-20 (lookup-text! + *common-text* + (-> *language-name-remap* (-> (the-as (pointer uint64) (-> s3-0 s0-0 value-to-modify)))) + #f + ) + ) + ) + (sv-848 sv-864 sv-880 sv-896 a3-20) + ) + (set! sv-912 *temp-string*) + sv-912 + ) ) ) ) diff --git a/test/decompiler/reference/engine/ui/progress/progress-static_REF.gc b/test/decompiler/reference/engine/ui/progress/progress-static_REF.gc index 056b2d9ff9..c023341824 100644 --- a/test/decompiler/reference/engine/ui/progress/progress-static_REF.gc +++ b/test/decompiler/reference/engine/ui/progress/progress-static_REF.gc @@ -4,288 +4,370 @@ ;; definition for symbol *main-options*, type (array game-option) (define *main-options* - (the-as (array game-option) - (new - 'static - 'boxed-array - :type game-option :length 7 :allocated-length 7 - (new 'static 'game-option :option-type #x6 :name (game-text-id game-options) :scale #t :param3 4) - (new 'static 'game-option :option-type #x6 :name (game-text-id graphic-options) :scale #t :param3 5) - (new 'static 'game-option :option-type #x6 :name (game-text-id sound-options) :scale #t :param3 6) - (new 'static 'game-option :option-type #x6 :name (game-text-id load-game) :scale #t :param3 16) - (new 'static 'game-option :option-type #x6 :name (game-text-id save-game) :scale #t :param3 17) - (new 'static 'game-option :option-type #x6 :name (game-text-id quit-game) :scale #t :param3 34) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) + (new + 'static + 'boxed-array + :type game-option :length 7 :allocated-length 7 + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id game-options) + :scale #t + :param3 (game-option-menu game-settings) ) + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id graphic-options) + :scale #t + :param3 (game-option-menu graphic-settings) + ) + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id sound-options) + :scale #t + :param3 (game-option-menu sound-settings) + ) + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id load-game) + :scale #t + :param3 (game-option-menu load-game) + ) + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id save-game) + :scale #t + :param3 (game-option-menu save-game) + ) + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id quit-game) + :scale #t + :param3 (game-option-menu quit) + ) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) ) ) ;; definition for symbol *title*, type (array game-option) (define *title* - (the-as (array game-option) - (new - 'static - 'boxed-array - :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :option-type #x6 :name (game-text-id new-game) :scale #t :param3 18) - (new 'static 'game-option :option-type #x6 :name (game-text-id load-game) :scale #t :param3 16) - (new 'static 'game-option :option-type #x6 :name (game-text-id options) :scale #t :param3 28) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) + (new + 'static + 'boxed-array + :type game-option :length 4 :allocated-length 4 + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id new-game) + :scale #t + :param3 (game-option-menu save-game-title) ) + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id load-game) + :scale #t + :param3 (game-option-menu load-game) + ) + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id options) + :scale #t + :param3 (game-option-menu settings-title) + ) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) ) ) ;; definition for symbol *options*, type (array game-option) (define *options* - (the-as (array game-option) - (new - 'static - 'boxed-array - :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :option-type #x6 :name (game-text-id game-options) :scale #t :param3 4) - (new 'static 'game-option :option-type #x6 :name (game-text-id graphic-options) :scale #t :param3 5) - (new 'static 'game-option :option-type #x6 :name (game-text-id sound-options) :scale #t :param3 6) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) + (new + 'static + 'boxed-array + :type game-option :length 4 :allocated-length 4 + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id game-options) + :scale #t + :param3 (game-option-menu game-settings) ) + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id graphic-options) + :scale #t + :param3 (game-option-menu graphic-settings) + ) + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id sound-options) + :scale #t + :param3 (game-option-menu sound-settings) + ) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) ) ) ;; definition for symbol *main-options-demo*, type (array game-option) (define *main-options-demo* - (the-as (array game-option) - (new - 'static - 'boxed-array - :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :option-type #x6 :name (game-text-id game-options) :scale #t :param3 4) - (new 'static 'game-option :option-type #x6 :name (game-text-id graphic-options) :scale #t :param3 5) - (new 'static 'game-option :option-type #x6 :name (game-text-id sound-options) :scale #t :param3 6) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) + (new + 'static + 'boxed-array + :type game-option :length 4 :allocated-length 4 + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id game-options) + :scale #t + :param3 (game-option-menu game-settings) ) + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id graphic-options) + :scale #t + :param3 (game-option-menu graphic-settings) + ) + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id sound-options) + :scale #t + :param3 (game-option-menu sound-settings) + ) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) ) ) ;; definition for symbol *main-options-demo-shared*, type (array game-option) (define *main-options-demo-shared* - (the-as (array game-option) - (new - 'static - 'boxed-array - :type game-option :length 5 :allocated-length 5 - (new 'static 'game-option :option-type #x6 :name (game-text-id game-options) :scale #t :param3 4) - (new 'static 'game-option :option-type #x6 :name (game-text-id graphic-options) :scale #t :param3 5) - (new 'static 'game-option :option-type #x6 :name (game-text-id sound-options) :scale #t :param3 6) - (new 'static 'game-option :option-type #x8 :name (game-text-id exit-demo) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) + (new + 'static + 'boxed-array + :type game-option :length 5 :allocated-length 5 + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id game-options) + :scale #t + :param3 (game-option-menu game-settings) ) + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id graphic-options) + :scale #t + :param3 (game-option-menu graphic-settings) + ) + (new 'static 'game-option + :option-type (game-option-type menu) + :name (game-text-id sound-options) + :scale #t + :param3 (game-option-menu sound-settings) + ) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id exit-demo) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) ) ) ;; definition for symbol *game-options*, type (array game-option) (define *game-options* - (the-as (array game-option) - (new - 'static - 'boxed-array - :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :option-type #x2 :name (game-text-id vibrations) :scale #t) - (new 'static 'game-option :option-type #x2 :name (game-text-id play-hints) :scale #t) - (new 'static 'game-option :option-type #x1 :name (game-text-id language) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) + (new + 'static + 'boxed-array + :type game-option :length 4 :allocated-length 4 + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id vibrations) :scale #t) + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id play-hints) :scale #t) + (new 'static 'game-option :option-type (game-option-type language) :name (game-text-id language) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) ) ) ;; definition for symbol *game-options-japan*, type (array game-option) (define *game-options-japan* - (the-as (array game-option) - (new - 'static - 'boxed-array - :type game-option :length 3 :allocated-length 3 - (new 'static 'game-option :option-type #x2 :name (game-text-id vibrations) :scale #t) - (new 'static 'game-option :option-type #x2 :name (game-text-id play-hints) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) + (new + 'static + 'boxed-array + :type game-option :length 3 :allocated-length 3 + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id vibrations) :scale #t) + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id play-hints) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) ) ) ;; definition for symbol *game-options-demo*, type (array game-option) (define *game-options-demo* - (the-as (array game-option) - (new - 'static - 'boxed-array - :type game-option :length 3 :allocated-length 3 - (new 'static 'game-option :option-type #x2 :name (game-text-id vibrations) :scale #t) - (new 'static 'game-option :option-type #x2 :name (game-text-id play-hints) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) + (new + 'static + 'boxed-array + :type game-option :length 3 :allocated-length 3 + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id vibrations) :scale #t) + (new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id play-hints) :scale #t) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) ) ) ;; definition for symbol *graphic-options*, type (array game-option) (define *graphic-options* - (the-as (array game-option) - (new - 'static - 'boxed-array - :type game-option :length 3 :allocated-length 3 - (new 'static 'game-option :option-type #x3 :name (game-text-id center-screen) :scale #t) - (new 'static 'game-option :option-type #x4 :name (game-text-id aspect-ratio) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) + (new + 'static + 'boxed-array + :type game-option :length 3 :allocated-length 3 + (new 'static 'game-option + :option-type (game-option-type center-screen) + :name (game-text-id center-screen) + :scale #t ) + (new 'static 'game-option + :option-type (game-option-type aspect-ratio) + :name (game-text-id aspect-ratio) + :scale #t + ) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) ) ) ;; definition for symbol *graphic-title-options-pal*, type (array game-option) (define *graphic-title-options-pal* - (the-as (array game-option) - (new - 'static - 'boxed-array - :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :option-type #x3 :name (game-text-id center-screen) :scale #t) - (new 'static 'game-option :option-type #x5 :name (game-text-id video-mode) :scale #t) - (new 'static 'game-option :option-type #x4 :name (game-text-id aspect-ratio) :scale #t) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) + (new + 'static + 'boxed-array + :type game-option :length 4 :allocated-length 4 + (new 'static 'game-option + :option-type (game-option-type center-screen) + :name (game-text-id center-screen) + :scale #t ) + (new 'static 'game-option + :option-type (game-option-type video-mode) + :name (game-text-id video-mode) + :scale #t + ) + (new 'static 'game-option + :option-type (game-option-type aspect-ratio) + :name (game-text-id aspect-ratio) + :scale #t + ) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) ) ) ;; definition for symbol *sound-options*, type (array game-option) (define *sound-options* - (the-as (array game-option) - (new - 'static - 'boxed-array - :type game-option :length 4 :allocated-length 4 - (new 'static 'game-option :name (game-text-id sfx-volume) :scale #t :param2 100.0) - (new 'static 'game-option :name (game-text-id music-volume) :scale #t :param2 100.0) - (new 'static 'game-option :name (game-text-id speech-volume) :scale #t :param2 100.0) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #t) - ) + (new + 'static + 'boxed-array + :type game-option :length 4 :allocated-length 4 + (new 'static 'game-option :name (game-text-id sfx-volume) :scale #t :param2 100.0) + (new 'static 'game-option :name (game-text-id music-volume) :scale #t :param2 100.0) + (new 'static 'game-option :name (game-text-id speech-volume) :scale #t :param2 100.0) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t) ) ) ;; definition for symbol *yes-no-options*, type (array game-option) -(define *yes-no-options* (the-as (array game-option) (new - 'static - 'boxed-array - :type game-option :length 1 :allocated-length 1 - (new 'static 'game-option :option-type #x7 :scale #f) - ) - ) +(define *yes-no-options* (new + 'static + 'boxed-array + :type game-option :length 1 :allocated-length 1 + (new 'static 'game-option :option-type (game-option-type yes-no) :scale #f) + ) ) ;; definition for symbol *ok-options*, type (array game-option) (define *ok-options* - (the-as (array game-option) (new - 'static - 'boxed-array - :type game-option :length 1 :allocated-length 1 - (new 'static 'game-option :option-type #x8 :name (game-text-id ok) :scale #f) - ) - ) + (new + 'static + 'boxed-array + :type game-option :length 1 :allocated-length 1 + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id ok) :scale #f) + ) ) ;; definition for symbol *load-options*, type (array game-option) (define *load-options* - (the-as (array game-option) (new - 'static - 'boxed-array - :type game-option :length 5 :allocated-length 5 - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #f) - ) - ) + (new + 'static + 'boxed-array + :type game-option :length 5 :allocated-length 5 + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #f) + ) ) ;; definition for symbol *save-options*, type (array game-option) (define *save-options* - (the-as (array game-option) (new - 'static - 'boxed-array - :type game-option :length 5 :allocated-length 5 - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #f) - ) - ) + (new + 'static + 'boxed-array + :type game-option :length 5 :allocated-length 5 + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #f) + ) ) ;; definition for symbol *save-options-title*, type (array game-option) (define *save-options-title* - (the-as (array game-option) - (new - 'static - 'boxed-array - :type game-option :length 6 :allocated-length 6 - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :scale #f) - (new 'static 'game-option :option-type #x8 :name (game-text-id continue-without-saving) :scale #f) - (new 'static 'game-option :option-type #x8 :name (game-text-id back) :scale #f) + (new + 'static + 'boxed-array + :type game-option :length 6 :allocated-length 6 + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option :option-type (game-option-type button) :scale #f) + (new 'static 'game-option + :option-type (game-option-type button) + :name (game-text-id continue-without-saving) + :scale #f ) + (new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #f) ) ) ;; definition for symbol *options-remap*, type (array (array game-option)) -(define - *options-remap* - (the-as (array (array game-option)) (new 'static 'boxed-array :type array :length 0 :allocated-length 35)) - ) +(define *options-remap* (new 'static 'boxed-array :type (array game-option) :length 0 :allocated-length 35)) ;; definition for symbol *level-task-data-remap*, type (array int32) -(define *level-task-data-remap* (the-as (array int32) (new - 'static - 'boxed-array - :type int32 :length 23 :allocated-length 23 - 0 - 1 - 2 - 3 - 3 - 4 - 5 - 6 - 7 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 13 - 13 - 14 - 15 - 15 - 4 - 4 - ) - ) +(define *level-task-data-remap* (new + 'static + 'boxed-array + :type int32 :length 23 :allocated-length 23 + 0 + 1 + 2 + 3 + 3 + 4 + 5 + 6 + 7 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 13 + 13 + 14 + 15 + 15 + 4 + 4 + ) ) ;; definition for symbol *language-name-remap*, type (array game-text-id) @@ -303,1178 +385,1173 @@ ) ;; definition for symbol *level-task-data*, type (array level-tasks-info) -(define - *level-task-data* - (the-as (array level-tasks-info) (new - 'static - 'boxed-array - :type level-tasks-info :length 16 :allocated-length 16 - (new 'static 'level-tasks-info - :level-name-id (game-text-id training-level-name) - :text-group-index 1 - :nb-of-tasks 4 - :buzzer-task-index 3 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task training-gimmie) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id training-gimmie-task-name) - (game-text-id training-gimmie-task-name) - (game-text-id training-gimmie-task-name) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task training-door) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id training-door-task-name) - (game-text-id training-door-task-name) - (game-text-id training-door-task-name) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task training-climb) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id training-climb-task-name) - (game-text-id training-climb-task-name) - (game-text-id training-climb-task-name) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task training-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id training-buzzer-task-name) - (game-text-id training-buzzer-task-name) - (game-text-id training-buzzer-task-name) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id village1-level-name) - :text-group-index 1 - :nb-of-tasks 6 - :buzzer-task-index 5 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task village1-mayor-money) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village1-mayor-money) - (game-text-id village1-mayor-money) - (game-text-id village1-mayor-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village1-uncle-money) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id vollage1-uncle-money) - (game-text-id vollage1-uncle-money) - (game-text-id vollage1-uncle-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village1-yakow) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village1-yakow-herd) - (game-text-id village1-yakow-herd) - (game-text-id village1-yakow-return) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village1-oracle-money1) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village1-oracle) - (game-text-id village1-oracle) - (game-text-id village1-oracle) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village1-oracle-money2) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village1-oracle) - (game-text-id village1-oracle) - (game-text-id village1-oracle) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village1-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id beach-level-name) - :text-group-index 1 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task beach-ecorocks) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-ecorocks) - (game-text-id beach-ecorocks) - (game-text-id beach-ecorocks) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task beach-flutflut) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-flutflut-push) - (game-text-id beach-flutflut-push) - (game-text-id beach-flutflut-meet) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task beach-pelican) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-pelican) - (game-text-id beach-pelican) - (game-text-id beach-pelican) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task beach-seagull) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-seagull) - (game-text-id beach-seagull) - (game-text-id beach-seagull-get) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task beach-cannon) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-cannon) - (game-text-id beach-cannon) - (game-text-id beach-cannon) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task beach-gimmie) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-gimmie) - (game-text-id beach-gimmie) - (game-text-id beach-gimmie) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task beach-sentinel) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-sentinel) - (game-text-id beach-sentinel) - (game-text-id beach-sentinel) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task beach-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id jungle-level-name) - :text-group-index 1 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task jungle-lurkerm) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id jungle-lurkerm-unblock) - (game-text-id jungle-lurkerm-connect) - (game-text-id jungle-lurkerm-return) - (game-text-id zero) - ) - :text-index-when-resolved 1 - ) - (new 'static 'task-info-data - :task-id (game-task jungle-tower) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id jungle-tower) - (game-text-id jungle-tower) - (game-text-id jungle-tower) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task jungle-eggtop) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id jungle-eggtop) - (game-text-id jungle-eggtop) - (game-text-id jungle-eggtop) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task jungle-plant) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id jungle-plant) - (game-text-id jungle-plant) - (game-text-id jungle-plant) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task jungle-fishgame) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id jungle-fishgame) - (game-text-id jungle-fishgame) - (game-text-id jungle-fishgame) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task jungle-canyon-end) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id jungle-canyon-end) - (game-text-id jungle-canyon-end) - (game-text-id jungle-canyon-end) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task jungle-temple-door) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id jungle-temple-door) - (game-text-id jungle-temple-door) - (game-text-id jungle-temple-door) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task jungle-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id misty-level-name) - :text-group-index 1 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task misty-muse) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id misty-muse-catch) - (game-text-id misty-muse-catch) - (game-text-id misty-muse-return) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task misty-boat) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id misty-boat) - (game-text-id misty-boat) - (game-text-id misty-boat) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task misty-cannon) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id misty-cannon) - (game-text-id misty-cannon) - (game-text-id misty-cannon) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task misty-warehouse) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id misty-return-to-pool) - (game-text-id misty-return-to-pool) - (game-text-id misty-return-to-pool) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task misty-bike) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id misty-find-transpad) - (game-text-id misty-balloon-lurkers) - (game-text-id misty-find-transpad) - (game-text-id zero) - ) - :text-index-when-resolved 1 - ) - (new 'static 'task-info-data - :task-id (game-task misty-bike-jump) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id misty-bike-jump) - (game-text-id misty-bike-jump) - (game-text-id misty-bike-jump) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task misty-eco-challenge) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id misty-eco-challenge) - (game-text-id misty-eco-challenge) - (game-text-id misty-eco-challenge) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task misty-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id beach-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id fire-canyon-level-name) - :text-group-index 5 - :nb-of-tasks 2 - :buzzer-task-index 1 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task firecanyon-end) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id fire-canyon-end) - (game-text-id fire-canyon-end) - (game-text-id fire-canyon-end) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task firecanyon-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id fire-canyon-buzzer) - (game-text-id fire-canyon-buzzer) - (game-text-id fire-canyon-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id village2-level-name) - :text-group-index 2 - :nb-of-tasks 6 - :buzzer-task-index 5 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task village2-gambler-money) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village2-gambler-money) - (game-text-id village2-gambler-money) - (game-text-id village2-gambler-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village2-geologist-money) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village2-geologist-money) - (game-text-id village2-geologist-money) - (game-text-id village2-geologist-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village2-warrior-money) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village2-warrior-money) - (game-text-id village2-warrior-money) - (game-text-id village2-warrior-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village2-oracle-money1) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village2-oracle-money) - (game-text-id village2-oracle-money) - (game-text-id village2-oracle-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village2-oracle-money2) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village2-oracle-money) - (game-text-id village2-oracle-money) - (game-text-id village2-oracle-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village2-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id sunken-level-name) - :text-group-index 2 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task sunken-room) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id sunken-elevator-raise) - (game-text-id sunken-elevator-raise) - (game-text-id sunken-elevator-get-to-roof) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task sunken-pipe) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id sunken-pipe) - (game-text-id sunken-pipe) - (game-text-id sunken-pipe) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task sunken-slide) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id sunken-bottom) - (game-text-id sunken-bottom) - (game-text-id sunken-bottom) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task sunken-sharks) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id sunken-pool) - (game-text-id sunken-pool) - (game-text-id sunken-pool) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task sunken-platforms) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id sunken-platforms) - (game-text-id sunken-platforms) - (game-text-id sunken-platforms) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task sunken-top-of-helix) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id sunken-climb-tube) - (game-text-id sunken-climb-tube) - (game-text-id sunken-climb-tube) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task sunken-spinning-room) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id reach-center) - (game-text-id reach-center) - (game-text-id reach-center) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task sunken-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id swamp-level-name) - :text-group-index 2 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task swamp-flutflut) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id swamp-flutflut) - (game-text-id swamp-flutflut) - (game-text-id swamp-flutflut) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task swamp-billy) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id swamp-billy) - (game-text-id swamp-billy) - (game-text-id swamp-billy) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task swamp-battle) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id swamp-battle) - (game-text-id swamp-battle) - (game-text-id swamp-battle) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task swamp-tether-4) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task swamp-tether-1) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task swamp-tether-2) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task swamp-tether-3) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id swamp-tether) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task swamp-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id rolling-level-name) - :text-group-index 2 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task rolling-moles) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id rolling-moles) - (game-text-id rolling-moles) - (game-text-id rolling-moles-return) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task rolling-robbers) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id rolling-robbers) - (game-text-id rolling-robbers) - (game-text-id rolling-robbers) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task rolling-race) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id rolling-race) - (game-text-id rolling-race) - (game-text-id rolling-race-return) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task rolling-lake) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id rolling-lake) - (game-text-id rolling-lake) - (game-text-id rolling-lake) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task rolling-plants) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id rolling-plants) - (game-text-id rolling-plants) - (game-text-id rolling-plants) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task rolling-ring-chase-1) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id rolling-ring-chase-1) - (game-text-id rolling-ring-chase-1) - (game-text-id rolling-ring-chase-1) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task rolling-ring-chase-2) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id rolling-ring-chase-2) - (game-text-id rolling-ring-chase-2) - (game-text-id rolling-ring-chase-2) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task rolling-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id unknown-buzzers) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id ogre-level-name) - :text-group-index 6 - :nb-of-tasks 4 - :buzzer-task-index 3 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task ogre-boss) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id ogre-boss) - (game-text-id ogre-boss) - (game-text-id ogre-boss) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task ogre-end) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id ogre-end) - (game-text-id ogre-end) - (game-text-id ogre-end) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task ogre-secret) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id hidden-power-cell) - (game-text-id hidden-power-cell) - (game-text-id hidden-power-cell) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task ogre-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id ogre-buzzer) - (game-text-id ogre-buzzer) - (game-text-id ogre-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id village3-level-name) - :text-group-index 3 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task village3-miner-money1) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village3-miner-money2) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village3-miner-money3) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village3-miner-money4) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id village3-miner-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village3-oracle-money1) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-oracle-money) - (game-text-id village3-oracle-money) - (game-text-id village3-oracle-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village3-oracle-money2) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-oracle-money) - (game-text-id village3-oracle-money) - (game-text-id village3-oracle-money) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village3-extra1) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id hidden-power-cell) - (game-text-id hidden-power-cell) - (game-text-id hidden-power-cell) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task village3-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-buzzer) - (game-text-id village3-buzzer) - (game-text-id village3-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id snowy-level-name) - :text-group-index 3 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task snow-eggtop) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id snow-eggtop) - (game-text-id snow-eggtop) - (game-text-id snow-eggtop) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task snow-ram) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id snow-ram-3-left) - (game-text-id snow-ram-2-left) - (game-text-id snow-ram-1-left) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task snow-bumpers) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id snow-bumpers) - (game-text-id snow-bumpers) - (game-text-id snow-bumpers) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task snow-cage) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id snow-frozen-crate) - (game-text-id snow-frozen-crate) - (game-text-id snow-frozen-crate) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task snow-fort) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id snow-fort) - (game-text-id snow-fort) - (game-text-id snow-fort) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task snow-ball) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id snow-open-door) - (game-text-id snow-open-door) - (game-text-id snow-open-door) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task snow-bunnies) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id snow-bunnies) - (game-text-id snow-bunnies) - (game-text-id snow-bunnies) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task snow-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-buzzer) - (game-text-id village3-buzzer) - (game-text-id village3-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id cave-level-name) - :text-group-index 3 - :nb-of-tasks 8 - :buzzer-task-index 7 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task cave-gnawers) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id cave-gnawers) - (game-text-id cave-gnawers) - (game-text-id cave-gnawers) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task cave-dark-crystals) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id cave-dark-crystals) - (game-text-id cave-dark-crystals) - (game-text-id cave-dark-crystals) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task cave-dark-climb) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id cave-dark-climb) - (game-text-id cave-dark-climb) - (game-text-id cave-dark-climb) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task cave-robot-climb) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id cave-robot-climb) - (game-text-id cave-robot-climb) - (game-text-id cave-robot-climb) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task cave-swing-poles) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id cave-swing-poles) - (game-text-id cave-swing-poles) - (game-text-id cave-swing-poles) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task cave-spider-tunnel) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id cave-spider-tunnel) - (game-text-id cave-spider-tunnel) - (game-text-id cave-spider-tunnel) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task cave-platforms) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id cave-platforms) - (game-text-id cave-platforms) - (game-text-id cave-platforms) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task cave-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id village3-buzzer) - (game-text-id village3-buzzer) - (game-text-id village3-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id lavatube-level-name) - :text-group-index 3 - :nb-of-tasks 2 - :buzzer-task-index 1 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task lavatube-end) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id lavatube-end) - (game-text-id lavatube-end) - (game-text-id lavatube-end) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task lavatube-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id lavatube-buzzer) - (game-text-id lavatube-buzzer) - (game-text-id lavatube-buzzer) - (game-text-id zero) - ) - ) - ) - ) - (new 'static 'level-tasks-info - :level-name-id (game-text-id citadel-level-name) - :text-group-index 4 - :nb-of-tasks 5 - :buzzer-task-index 4 - :task-info - (new 'static 'array task-info-data 8 - (new 'static 'task-info-data - :task-id (game-task citadel-sage-blue) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id citadel-sage-blue) - (game-text-id citadel-sage-blue) - (game-text-id citadel-sage-blue) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task citadel-sage-red) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id citadel-sage-red) - (game-text-id citadel-sage-red) - (game-text-id citadel-sage-red) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task citadel-sage-yellow) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id citadel-sage-yellow) - (game-text-id citadel-sage-yellow) - (game-text-id citadel-sage-yellow) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task citadel-sage-green) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id citadel-sage-green) - (game-text-id citadel-sage-green) - (game-text-id citadel-sage-green) - (game-text-id zero) - ) - ) - (new 'static 'task-info-data - :task-id (game-task citadel-buzzer) - :task-name - (new 'static 'array game-text-id 4 - (game-text-id citadel-buzzer) - (game-text-id citadel-buzzer) - (game-text-id citadel-buzzer) - (game-text-id zero) - ) - ) - ) - ) - ) - ) - ) +(define *level-task-data* (new + 'static + 'boxed-array + :type level-tasks-info :length 16 :allocated-length 16 + (new 'static 'level-tasks-info + :level-name-id (game-text-id training-level-name) + :text-group-index 1 + :nb-of-tasks 4 + :buzzer-task-index 3 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task training-gimmie) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id training-gimmie-task-name) + (game-text-id training-gimmie-task-name) + (game-text-id training-gimmie-task-name) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task training-door) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id training-door-task-name) + (game-text-id training-door-task-name) + (game-text-id training-door-task-name) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task training-climb) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id training-climb-task-name) + (game-text-id training-climb-task-name) + (game-text-id training-climb-task-name) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task training-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id training-buzzer-task-name) + (game-text-id training-buzzer-task-name) + (game-text-id training-buzzer-task-name) + (game-text-id zero) + ) + ) + ) + ) + (new 'static 'level-tasks-info + :level-name-id (game-text-id village1-level-name) + :text-group-index 1 + :nb-of-tasks 6 + :buzzer-task-index 5 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task village1-mayor-money) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village1-mayor-money) + (game-text-id village1-mayor-money) + (game-text-id village1-mayor-money) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village1-uncle-money) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id vollage1-uncle-money) + (game-text-id vollage1-uncle-money) + (game-text-id vollage1-uncle-money) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village1-yakow) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village1-yakow-herd) + (game-text-id village1-yakow-herd) + (game-text-id village1-yakow-return) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village1-oracle-money1) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village1-oracle) + (game-text-id village1-oracle) + (game-text-id village1-oracle) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village1-oracle-money2) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village1-oracle) + (game-text-id village1-oracle) + (game-text-id village1-oracle) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village1-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id beach-buzzer) + (game-text-id beach-buzzer) + (game-text-id beach-buzzer) + (game-text-id zero) + ) + ) + ) + ) + (new 'static 'level-tasks-info + :level-name-id (game-text-id beach-level-name) + :text-group-index 1 + :nb-of-tasks 8 + :buzzer-task-index 7 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task beach-ecorocks) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id beach-ecorocks) + (game-text-id beach-ecorocks) + (game-text-id beach-ecorocks) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task beach-flutflut) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id beach-flutflut-push) + (game-text-id beach-flutflut-push) + (game-text-id beach-flutflut-meet) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task beach-pelican) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id beach-pelican) + (game-text-id beach-pelican) + (game-text-id beach-pelican) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task beach-seagull) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id beach-seagull) + (game-text-id beach-seagull) + (game-text-id beach-seagull-get) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task beach-cannon) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id beach-cannon) + (game-text-id beach-cannon) + (game-text-id beach-cannon) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task beach-gimmie) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id beach-gimmie) + (game-text-id beach-gimmie) + (game-text-id beach-gimmie) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task beach-sentinel) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id beach-sentinel) + (game-text-id beach-sentinel) + (game-text-id beach-sentinel) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task beach-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id beach-buzzer) + (game-text-id beach-buzzer) + (game-text-id beach-buzzer) + (game-text-id zero) + ) + ) + ) + ) + (new 'static 'level-tasks-info + :level-name-id (game-text-id jungle-level-name) + :text-group-index 1 + :nb-of-tasks 8 + :buzzer-task-index 7 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task jungle-lurkerm) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id jungle-lurkerm-unblock) + (game-text-id jungle-lurkerm-connect) + (game-text-id jungle-lurkerm-return) + (game-text-id zero) + ) + :text-index-when-resolved 1 + ) + (new 'static 'task-info-data + :task-id (game-task jungle-tower) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id jungle-tower) + (game-text-id jungle-tower) + (game-text-id jungle-tower) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task jungle-eggtop) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id jungle-eggtop) + (game-text-id jungle-eggtop) + (game-text-id jungle-eggtop) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task jungle-plant) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id jungle-plant) + (game-text-id jungle-plant) + (game-text-id jungle-plant) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task jungle-fishgame) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id jungle-fishgame) + (game-text-id jungle-fishgame) + (game-text-id jungle-fishgame) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task jungle-canyon-end) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id jungle-canyon-end) + (game-text-id jungle-canyon-end) + (game-text-id jungle-canyon-end) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task jungle-temple-door) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id jungle-temple-door) + (game-text-id jungle-temple-door) + (game-text-id jungle-temple-door) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task jungle-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id beach-buzzer) + (game-text-id beach-buzzer) + (game-text-id beach-buzzer) + (game-text-id zero) + ) + ) + ) + ) + (new 'static 'level-tasks-info + :level-name-id (game-text-id misty-level-name) + :text-group-index 1 + :nb-of-tasks 8 + :buzzer-task-index 7 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task misty-muse) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id misty-muse-catch) + (game-text-id misty-muse-catch) + (game-text-id misty-muse-return) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task misty-boat) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id misty-boat) + (game-text-id misty-boat) + (game-text-id misty-boat) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task misty-cannon) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id misty-cannon) + (game-text-id misty-cannon) + (game-text-id misty-cannon) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task misty-warehouse) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id misty-return-to-pool) + (game-text-id misty-return-to-pool) + (game-text-id misty-return-to-pool) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task misty-bike) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id misty-find-transpad) + (game-text-id misty-balloon-lurkers) + (game-text-id misty-find-transpad) + (game-text-id zero) + ) + :text-index-when-resolved 1 + ) + (new 'static 'task-info-data + :task-id (game-task misty-bike-jump) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id misty-bike-jump) + (game-text-id misty-bike-jump) + (game-text-id misty-bike-jump) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task misty-eco-challenge) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id misty-eco-challenge) + (game-text-id misty-eco-challenge) + (game-text-id misty-eco-challenge) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task misty-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id beach-buzzer) + (game-text-id beach-buzzer) + (game-text-id beach-buzzer) + (game-text-id zero) + ) + ) + ) + ) + (new 'static 'level-tasks-info + :level-name-id (game-text-id fire-canyon-level-name) + :text-group-index 5 + :nb-of-tasks 2 + :buzzer-task-index 1 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task firecanyon-end) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id fire-canyon-end) + (game-text-id fire-canyon-end) + (game-text-id fire-canyon-end) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task firecanyon-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id fire-canyon-buzzer) + (game-text-id fire-canyon-buzzer) + (game-text-id fire-canyon-buzzer) + (game-text-id zero) + ) + ) + ) + ) + (new 'static 'level-tasks-info + :level-name-id (game-text-id village2-level-name) + :text-group-index 2 + :nb-of-tasks 6 + :buzzer-task-index 5 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task village2-gambler-money) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village2-gambler-money) + (game-text-id village2-gambler-money) + (game-text-id village2-gambler-money) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village2-geologist-money) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village2-geologist-money) + (game-text-id village2-geologist-money) + (game-text-id village2-geologist-money) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village2-warrior-money) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village2-warrior-money) + (game-text-id village2-warrior-money) + (game-text-id village2-warrior-money) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village2-oracle-money1) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village2-oracle-money) + (game-text-id village2-oracle-money) + (game-text-id village2-oracle-money) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village2-oracle-money2) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village2-oracle-money) + (game-text-id village2-oracle-money) + (game-text-id village2-oracle-money) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village2-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id unknown-buzzers) + (game-text-id unknown-buzzers) + (game-text-id unknown-buzzers) + (game-text-id zero) + ) + ) + ) + ) + (new 'static 'level-tasks-info + :level-name-id (game-text-id sunken-level-name) + :text-group-index 2 + :nb-of-tasks 8 + :buzzer-task-index 7 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task sunken-room) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id sunken-elevator-raise) + (game-text-id sunken-elevator-raise) + (game-text-id sunken-elevator-get-to-roof) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task sunken-pipe) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id sunken-pipe) + (game-text-id sunken-pipe) + (game-text-id sunken-pipe) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task sunken-slide) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id sunken-bottom) + (game-text-id sunken-bottom) + (game-text-id sunken-bottom) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task sunken-sharks) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id sunken-pool) + (game-text-id sunken-pool) + (game-text-id sunken-pool) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task sunken-platforms) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id sunken-platforms) + (game-text-id sunken-platforms) + (game-text-id sunken-platforms) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task sunken-top-of-helix) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id sunken-climb-tube) + (game-text-id sunken-climb-tube) + (game-text-id sunken-climb-tube) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task sunken-spinning-room) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id reach-center) + (game-text-id reach-center) + (game-text-id reach-center) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task sunken-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id unknown-buzzers) + (game-text-id unknown-buzzers) + (game-text-id unknown-buzzers) + (game-text-id zero) + ) + ) + ) + ) + (new 'static 'level-tasks-info + :level-name-id (game-text-id swamp-level-name) + :text-group-index 2 + :nb-of-tasks 8 + :buzzer-task-index 7 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task swamp-flutflut) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id swamp-flutflut) + (game-text-id swamp-flutflut) + (game-text-id swamp-flutflut) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task swamp-billy) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id swamp-billy) + (game-text-id swamp-billy) + (game-text-id swamp-billy) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task swamp-battle) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id swamp-battle) + (game-text-id swamp-battle) + (game-text-id swamp-battle) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task swamp-tether-4) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id swamp-tether) + (game-text-id swamp-tether) + (game-text-id swamp-tether) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task swamp-tether-1) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id swamp-tether) + (game-text-id swamp-tether) + (game-text-id swamp-tether) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task swamp-tether-2) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id swamp-tether) + (game-text-id swamp-tether) + (game-text-id swamp-tether) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task swamp-tether-3) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id swamp-tether) + (game-text-id swamp-tether) + (game-text-id swamp-tether) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task swamp-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id unknown-buzzers) + (game-text-id unknown-buzzers) + (game-text-id unknown-buzzers) + (game-text-id zero) + ) + ) + ) + ) + (new 'static 'level-tasks-info + :level-name-id (game-text-id rolling-level-name) + :text-group-index 2 + :nb-of-tasks 8 + :buzzer-task-index 7 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task rolling-moles) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id rolling-moles) + (game-text-id rolling-moles) + (game-text-id rolling-moles-return) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task rolling-robbers) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id rolling-robbers) + (game-text-id rolling-robbers) + (game-text-id rolling-robbers) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task rolling-race) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id rolling-race) + (game-text-id rolling-race) + (game-text-id rolling-race-return) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task rolling-lake) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id rolling-lake) + (game-text-id rolling-lake) + (game-text-id rolling-lake) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task rolling-plants) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id rolling-plants) + (game-text-id rolling-plants) + (game-text-id rolling-plants) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task rolling-ring-chase-1) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id rolling-ring-chase-1) + (game-text-id rolling-ring-chase-1) + (game-text-id rolling-ring-chase-1) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task rolling-ring-chase-2) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id rolling-ring-chase-2) + (game-text-id rolling-ring-chase-2) + (game-text-id rolling-ring-chase-2) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task rolling-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id unknown-buzzers) + (game-text-id unknown-buzzers) + (game-text-id unknown-buzzers) + (game-text-id zero) + ) + ) + ) + ) + (new 'static 'level-tasks-info + :level-name-id (game-text-id ogre-level-name) + :text-group-index 6 + :nb-of-tasks 4 + :buzzer-task-index 3 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task ogre-boss) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id ogre-boss) + (game-text-id ogre-boss) + (game-text-id ogre-boss) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task ogre-end) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id ogre-end) + (game-text-id ogre-end) + (game-text-id ogre-end) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task ogre-secret) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id hidden-power-cell) + (game-text-id hidden-power-cell) + (game-text-id hidden-power-cell) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task ogre-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id ogre-buzzer) + (game-text-id ogre-buzzer) + (game-text-id ogre-buzzer) + (game-text-id zero) + ) + ) + ) + ) + (new 'static 'level-tasks-info + :level-name-id (game-text-id village3-level-name) + :text-group-index 3 + :nb-of-tasks 8 + :buzzer-task-index 7 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task village3-miner-money1) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village3-miner-money) + (game-text-id village3-miner-money) + (game-text-id village3-miner-money) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village3-miner-money2) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village3-miner-money) + (game-text-id village3-miner-money) + (game-text-id village3-miner-money) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village3-miner-money3) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village3-miner-money) + (game-text-id village3-miner-money) + (game-text-id village3-miner-money) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village3-miner-money4) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village3-miner-money) + (game-text-id village3-miner-money) + (game-text-id village3-miner-money) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village3-oracle-money1) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village3-oracle-money) + (game-text-id village3-oracle-money) + (game-text-id village3-oracle-money) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village3-oracle-money2) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village3-oracle-money) + (game-text-id village3-oracle-money) + (game-text-id village3-oracle-money) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village3-extra1) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id hidden-power-cell) + (game-text-id hidden-power-cell) + (game-text-id hidden-power-cell) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task village3-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village3-buzzer) + (game-text-id village3-buzzer) + (game-text-id village3-buzzer) + (game-text-id zero) + ) + ) + ) + ) + (new 'static 'level-tasks-info + :level-name-id (game-text-id snowy-level-name) + :text-group-index 3 + :nb-of-tasks 8 + :buzzer-task-index 7 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task snow-eggtop) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id snow-eggtop) + (game-text-id snow-eggtop) + (game-text-id snow-eggtop) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task snow-ram) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id snow-ram-3-left) + (game-text-id snow-ram-2-left) + (game-text-id snow-ram-1-left) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task snow-bumpers) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id snow-bumpers) + (game-text-id snow-bumpers) + (game-text-id snow-bumpers) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task snow-cage) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id snow-frozen-crate) + (game-text-id snow-frozen-crate) + (game-text-id snow-frozen-crate) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task snow-fort) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id snow-fort) + (game-text-id snow-fort) + (game-text-id snow-fort) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task snow-ball) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id snow-open-door) + (game-text-id snow-open-door) + (game-text-id snow-open-door) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task snow-bunnies) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id snow-bunnies) + (game-text-id snow-bunnies) + (game-text-id snow-bunnies) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task snow-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village3-buzzer) + (game-text-id village3-buzzer) + (game-text-id village3-buzzer) + (game-text-id zero) + ) + ) + ) + ) + (new 'static 'level-tasks-info + :level-name-id (game-text-id cave-level-name) + :text-group-index 3 + :nb-of-tasks 8 + :buzzer-task-index 7 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task cave-gnawers) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id cave-gnawers) + (game-text-id cave-gnawers) + (game-text-id cave-gnawers) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task cave-dark-crystals) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id cave-dark-crystals) + (game-text-id cave-dark-crystals) + (game-text-id cave-dark-crystals) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task cave-dark-climb) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id cave-dark-climb) + (game-text-id cave-dark-climb) + (game-text-id cave-dark-climb) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task cave-robot-climb) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id cave-robot-climb) + (game-text-id cave-robot-climb) + (game-text-id cave-robot-climb) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task cave-swing-poles) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id cave-swing-poles) + (game-text-id cave-swing-poles) + (game-text-id cave-swing-poles) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task cave-spider-tunnel) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id cave-spider-tunnel) + (game-text-id cave-spider-tunnel) + (game-text-id cave-spider-tunnel) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task cave-platforms) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id cave-platforms) + (game-text-id cave-platforms) + (game-text-id cave-platforms) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task cave-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id village3-buzzer) + (game-text-id village3-buzzer) + (game-text-id village3-buzzer) + (game-text-id zero) + ) + ) + ) + ) + (new 'static 'level-tasks-info + :level-name-id (game-text-id lavatube-level-name) + :text-group-index 3 + :nb-of-tasks 2 + :buzzer-task-index 1 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task lavatube-end) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id lavatube-end) + (game-text-id lavatube-end) + (game-text-id lavatube-end) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task lavatube-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id lavatube-buzzer) + (game-text-id lavatube-buzzer) + (game-text-id lavatube-buzzer) + (game-text-id zero) + ) + ) + ) + ) + (new 'static 'level-tasks-info + :level-name-id (game-text-id citadel-level-name) + :text-group-index 4 + :nb-of-tasks 5 + :buzzer-task-index 4 + :task-info + (new 'static 'array task-info-data 8 + (new 'static 'task-info-data + :task-id (game-task citadel-sage-blue) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id citadel-sage-blue) + (game-text-id citadel-sage-blue) + (game-text-id citadel-sage-blue) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task citadel-sage-red) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id citadel-sage-red) + (game-text-id citadel-sage-red) + (game-text-id citadel-sage-red) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task citadel-sage-yellow) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id citadel-sage-yellow) + (game-text-id citadel-sage-yellow) + (game-text-id citadel-sage-yellow) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task citadel-sage-green) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id citadel-sage-green) + (game-text-id citadel-sage-green) + (game-text-id citadel-sage-green) + (game-text-id zero) + ) + ) + (new 'static 'task-info-data + :task-id (game-task citadel-buzzer) + :task-name + (new 'static 'array game-text-id 4 + (game-text-id citadel-buzzer) + (game-text-id citadel-buzzer) + (game-text-id citadel-buzzer) + (game-text-id zero) + ) + ) + ) + ) + ) + ) ;; definition for symbol *task-egg-starting-x*, type (array int32) (define *task-egg-starting-x* - (the-as (array int32) - (new 'static 'boxed-array :type int32 :length 9 :allocated-length 9 #xda #xc2 #xab #x93 #x7c 100 77 53 30) - ) + (new 'static 'boxed-array :type int32 :length 9 :allocated-length 9 #xda #xc2 #xab #x93 #x7c 100 77 53 30) ) ;; definition for symbol *game-counts*, type game-count-info diff --git a/test/decompiler/reference/engine/ui/progress/progress_REF.gc b/test/decompiler/reference/engine/ui/progress/progress_REF.gc index 8d459e890b..34b54cf694 100644 --- a/test/decompiler/reference/engine/ui/progress/progress_REF.gc +++ b/test/decompiler/reference/engine/ui/progress/progress_REF.gc @@ -10,7 +10,7 @@ (starting-state progress-screen :offset-assert 24) (last-slot-saved int32 :offset-assert 32) (slider-backup float :offset-assert 36) - (language-backup int64 :offset-assert 40) + (language-backup language-enum :offset-assert 40) (on-off-backup symbol :offset-assert 48) (center-x-backup int32 :offset-assert 52) (center-y-backup int32 :offset-assert 56) @@ -1065,7 +1065,7 @@ ) ;; definition for method 32 of type progress -(defmethod dummy-32 progress ((obj progress)) +(defmethod can-go-back? progress ((obj progress)) (let ((v1-2 (-> *progress-process* 0 display-state)) (a1-1 (-> *progress-state* starting-state)) ) @@ -1095,7 +1095,7 @@ ;; definition for method 19 of type progress ;; INFO: Return type mismatch object vs symbol. -(defmethod dummy-19 progress ((obj progress)) +(defmethod visible? progress ((obj progress)) (the-as symbol (and *progress-process* (zero? (-> *progress-process* 0 in-out-position)))) ) @@ -1147,7 +1147,7 @@ ) ;; definition for method 53 of type progress -(defmethod dummy-53 progress ((obj progress) (arg0 progress-screen)) +(defmethod set-memcard-screen progress ((obj progress) (arg0 progress-screen)) (let ((s4-0 (-> obj card-info)) (gp-0 arg0) ) @@ -1250,7 +1250,7 @@ ;; definition for method 31 of type progress ;; INFO: Return type mismatch int vs none. -(defmethod dummy-31 progress ((obj progress)) +(defmethod respond-memcard progress ((obj progress)) (let ((s5-0 (-> obj card-info))) (when (and s5-0 (not (-> obj in-transition))) (when (or (cpad-pressed? 0 x) (cpad-pressed? 0 circle)) @@ -1307,14 +1307,12 @@ (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) (set! (-> obj next-display-state) (progress-screen memcard-saving)) ) - ((begin - (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) - (= (-> obj display-state-stack 0) (progress-screen title)) - ) - (set! (-> obj next-display-state) (progress-screen save-game-title)) - ) (else - (set! (-> obj next-display-state) (progress-screen save-game)) + (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) + (if (= (-> obj display-state-stack 0) (progress-screen title)) + (set! (-> obj next-display-state) (progress-screen save-game-title)) + (set! (-> obj next-display-state) (progress-screen save-game)) + ) ) ) ) @@ -1443,7 +1441,7 @@ ;; definition for method 29 of type progress ;; INFO: Return type mismatch int vs none. -(defmethod dummy-29 progress ((obj progress)) +(defmethod respond-common progress ((obj progress)) (mc-get-slot-info 0 *progress-save-info*) (set! (-> obj card-info) *progress-save-info*) (let ((s5-0 (-> *options-remap* (-> obj display-state)))) @@ -1467,7 +1465,7 @@ (when (-> obj selected-option) (let ((v1-34 #f)) (case (-> s5-0 (-> obj option-index) option-type) - ((3) + (((game-option-type center-screen)) (when (< -48 (-> *setting-control* current screeny)) (set! v1-34 #t) (+! (-> *setting-control* default screeny) -1) @@ -1508,7 +1506,7 @@ (when (-> obj selected-option) (let ((v1-69 #f)) (case (-> s5-0 (-> obj option-index) option-type) - ((3) + (((game-option-type center-screen)) (when (< (-> *setting-control* current screeny) 48) (set! v1-69 #t) (+! (-> *setting-control* default screeny) 1) @@ -1529,10 +1527,10 @@ ((cpad-hold? 0 left) (cond ((cpad-pressed? 0 left) - (when (or (-> obj selected-option) (= (-> s5-0 (-> obj option-index) option-type) 7)) + (when (or (-> obj selected-option) (= (-> s5-0 (-> obj option-index) option-type) (game-option-type yes-no))) (let ((s4-5 #f)) (case (-> s5-0 (-> obj option-index) option-type) - ((2 7) + (((game-option-type on-off) (game-option-type yes-no)) (when (not (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) (set! s4-5 #t) (if (= (-> s5-0 (-> obj option-index) value-to-modify) (&-> *setting-control* current vibration)) @@ -1541,15 +1539,15 @@ ) (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) #t) ) - ((4) + (((game-option-type aspect-ratio)) (set! s4-5 (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'aspect16x9)) (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'aspect4x3) ) - ((5) + (((game-option-type video-mode)) (set! s4-5 (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'ntsc)) (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'pal) ) - ((1) + (((game-option-type language)) (if (> (the-as int (-> (the-as (pointer uint64) (-> s5-0 (-> obj option-index) value-to-modify)))) 0) (+! (-> (the-as (pointer uint64) (-> s5-0 (-> obj option-index) value-to-modify))) -1) (set! (-> (the-as (pointer int64) (-> s5-0 (-> obj option-index) value-to-modify))) @@ -1575,35 +1573,33 @@ (else (when (-> obj selected-option) (let ((v1-157 #f)) - (let ((a0-101 (-> s5-0 (-> obj option-index) option-type))) - (cond - ((zero? a0-101) - (cond - ((>= (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (+ 1.0 (-> s5-0 (-> obj option-index) param1)) + (case (-> s5-0 (-> obj option-index) option-type) + (((game-option-type slider)) + (cond + ((>= (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (+ 1.0 (-> s5-0 (-> obj option-index) param1)) + ) + (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (+ -1.0 (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify)))) ) - (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (+ -1.0 (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - (set! v1-157 #t) - ) - ((< (-> s5-0 (-> obj option-index) param1) - (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - ) - (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> s5-0 (-> obj option-index) param1) - ) - (set! v1-157 #t) - ) - ) + (set! v1-157 #t) + ) + ((< (-> s5-0 (-> obj option-index) param1) + (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + ) + (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (-> s5-0 (-> obj option-index) param1) + ) + (set! v1-157 #t) + ) ) - ((= a0-101 3) - (when (< -96 (-> *setting-control* default screenx)) - (set! v1-157 #t) - (+! (-> *setting-control* default screenx) -1) - ) + ) + (((game-option-type center-screen)) + (when (< -96 (-> *setting-control* default screenx)) + (set! v1-157 #t) + (+! (-> *setting-control* default screenx) -1) ) - ) + ) ) (when v1-157 (let ((f30-0 100.0)) @@ -1626,22 +1622,22 @@ ((cpad-hold? 0 right) (cond ((cpad-pressed? 0 right) - (when (or (-> obj selected-option) (= (-> s5-0 (-> obj option-index) option-type) 7)) + (when (or (-> obj selected-option) (= (-> s5-0 (-> obj option-index) option-type) (game-option-type yes-no))) (let ((v1-217 (the-as object #f))) (case (-> s5-0 (-> obj option-index) option-type) - ((2 7) + (((game-option-type on-off) (game-option-type yes-no)) (set! v1-217 (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) #f) ) - ((4) + (((game-option-type aspect-ratio)) (set! v1-217 (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'aspect4x3)) (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'aspect16x9) ) - ((5) + (((game-option-type video-mode)) (set! v1-217 (= (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'pal)) (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) 'ntsc) ) - ((1) + (((game-option-type language)) (let ((v1-243 (if (and (zero? (scf-get-territory)) (not (and (= *progress-cheat* 'language) (cpad-hold? 0 l2) (cpad-hold? 0 r2))) ) @@ -1674,35 +1670,33 @@ (else (when (-> obj selected-option) (let ((v1-263 #f)) - (let ((a0-177 (-> s5-0 (-> obj option-index) option-type))) - (cond - ((zero? a0-177) - (cond - ((>= (+ -1.0 (-> s5-0 (-> obj option-index) param2)) - (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (case (-> s5-0 (-> obj option-index) option-type) + (((game-option-type slider)) + (cond + ((>= (+ -1.0 (-> s5-0 (-> obj option-index) param2)) + (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + ) + (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (+ 1.0 (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify)))) ) - (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (+ 1.0 (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - (set! v1-263 #t) - ) - ((< (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> s5-0 (-> obj option-index) param2) - ) - (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> s5-0 (-> obj option-index) param2) - ) - (set! v1-263 #t) - ) - ) + (set! v1-263 #t) + ) + ((< (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (-> s5-0 (-> obj option-index) param2) + ) + (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (-> s5-0 (-> obj option-index) param2) + ) + (set! v1-263 #t) + ) ) - ((= a0-177 3) - (when (< (-> *setting-control* default screenx) 96) - (set! v1-263 #t) - (+! (-> *setting-control* default screenx) 1) - ) + ) + (((game-option-type center-screen)) + (when (< (-> *setting-control* default screenx) 96) + (set! v1-263 #t) + (+! (-> *setting-control* default screenx) 1) ) - ) + ) ) (when v1-263 (let ((f30-1 100.0)) @@ -1725,38 +1719,36 @@ ((or (cpad-pressed? 0 square) (cpad-pressed? 0 triangle)) (cond ((-> obj selected-option) - (let ((v1-319 (-> s5-0 (-> obj option-index) option-type))) - (cond - ((zero? v1-319) - (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> *progress-state* slider-backup) - ) - ) - ((= v1-319 1) - (set! (-> (the-as (pointer int64) (-> s5-0 (-> obj option-index) value-to-modify))) - (-> *progress-state* language-backup) - ) - ) - ((= v1-319 2) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) - (-> *progress-state* on-off-backup) - ) - ) - ((= v1-319 3) - (set! (-> *setting-control* default screenx) (-> *progress-state* center-x-backup)) - (set! (-> *setting-control* default screeny) (-> *progress-state* center-y-backup)) - ) - ((or (= v1-319 4) (= v1-319 5)) - (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) - (-> *progress-state* aspect-ratio-backup) - ) - ) - ) + (case (-> s5-0 (-> obj option-index) option-type) + (((game-option-type slider)) + (set! (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + (-> *progress-state* slider-backup) + ) + ) + (((game-option-type language)) + (set! (-> (the-as (pointer language-enum) (-> s5-0 (-> obj option-index) value-to-modify)) 0) + (-> *progress-state* language-backup) + ) + ) + (((game-option-type on-off)) + (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) + (-> *progress-state* on-off-backup) + ) + ) + (((game-option-type center-screen)) + (set! (-> *setting-control* default screenx) (-> *progress-state* center-x-backup)) + (set! (-> *setting-control* default screeny) (-> *progress-state* center-y-backup)) + ) + (((game-option-type aspect-ratio) (game-option-type video-mode)) + (set! (-> (the-as (pointer symbol) (-> s5-0 (-> obj option-index) value-to-modify)) 0) + (-> *progress-state* aspect-ratio-backup) + ) + ) ) (sound-play-by-name (static-sound-name "cursor-options") (new-sound-id) 1024 0 0 1 #t) (set! (-> obj selected-option) #f) ) - ((or (dummy-32 obj) + ((or (can-go-back? obj) (= (-> obj display-state) (progress-screen load-game)) (= (-> obj display-state) (progress-screen save-game)) (= (-> obj display-state) (progress-screen save-game-title)) @@ -1778,7 +1770,7 @@ (cond ((not (-> obj selected-option)) (cond - ((= (-> s5-0 (-> obj option-index) option-type) 6) + ((= (-> s5-0 (-> obj option-index) option-type) (game-option-type menu)) (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons x)) (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons x)) (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons circle)) @@ -1788,11 +1780,11 @@ (set! (-> obj next-display-state) (the-as progress-screen (-> s5-0 (-> obj option-index) param3))) (case (-> obj next-display-state) (((progress-screen load-game) (progress-screen save-game) (progress-screen save-game-title)) - (set! (-> obj next-display-state) (dummy-53 obj (-> obj next-display-state))) + (set! (-> obj next-display-state) (set-memcard-screen obj (-> obj next-display-state))) ) ) ) - ((= (-> s5-0 (-> obj option-index) option-type) 8) + ((= (-> s5-0 (-> obj option-index) option-type) (game-option-type button)) (cond ((= (-> s5-0 (-> obj option-index) name) (game-text-id exit-demo)) (set! *master-exit* 'force) @@ -1808,34 +1800,32 @@ ) ) ) - ((!= (-> s5-0 (-> obj option-index) option-type) 7) - (let ((v1-427 (-> s5-0 (-> obj option-index) option-type))) - (cond - ((zero? v1-427) - (set! (-> *progress-state* slider-backup) - (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) - ) - ) - ((= v1-427 1) - (set! (-> *progress-state* language-backup) - (the-as int (-> (the-as (pointer uint64) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - ) - ((= v1-427 2) - (set! (-> *progress-state* on-off-backup) - (the-as symbol (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - ) - ((= v1-427 3) - (set! (-> *progress-state* center-x-backup) (-> *setting-control* default screenx)) - (set! (-> *progress-state* center-y-backup) (-> *setting-control* default screeny)) - ) - ((or (= v1-427 4) (= v1-427 5)) - (set! (-> *progress-state* aspect-ratio-backup) - (the-as symbol (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) - ) - ) - ) + ((!= (-> s5-0 (-> obj option-index) option-type) (game-option-type yes-no)) + (case (-> s5-0 (-> obj option-index) option-type) + (((game-option-type slider)) + (set! (-> *progress-state* slider-backup) + (-> (the-as (pointer float) (-> s5-0 (-> obj option-index) value-to-modify))) + ) + ) + (((game-option-type language)) + (set! (-> *progress-state* language-backup) + (the-as language-enum (-> (the-as (pointer uint64) (-> s5-0 (-> obj option-index) value-to-modify)))) + ) + ) + (((game-option-type on-off)) + (set! (-> *progress-state* on-off-backup) + (the-as symbol (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) + ) + ) + (((game-option-type center-screen)) + (set! (-> *progress-state* center-x-backup) (-> *setting-control* default screenx)) + (set! (-> *progress-state* center-y-backup) (-> *setting-control* default screeny)) + ) + (((game-option-type aspect-ratio) (game-option-type video-mode)) + (set! (-> *progress-state* aspect-ratio-backup) + (the-as symbol (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) + ) + ) ) (sound-play-by-name (static-sound-name "select-option") (new-sound-id) 1024 0 0 1 #t) (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons x)) @@ -1843,8 +1833,8 @@ (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons circle)) (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons circle)) (set! (-> obj selected-option) #t) - (when (= (-> s5-0 (-> obj option-index) option-type) 1) - (set! (-> obj language-selection) (the-as uint (-> *setting-control* current language))) + (when (= (-> s5-0 (-> obj option-index) option-type) (game-option-type language)) + (set! (-> obj language-selection) (-> *setting-control* current language)) (set! (-> obj language-direction) #t) (set! (-> obj language-transition) #f) (set! (-> obj language-x-offset) 0) @@ -1857,12 +1847,12 @@ (sound-play-by-name (static-sound-name "start-options") (new-sound-id) 1024 0 0 1 #t) (set! (-> obj selected-option) #f) (case (-> s5-0 (-> obj option-index) option-type) - ((4) + (((game-option-type aspect-ratio)) (set! (-> *setting-control* default aspect-ratio) (the-as symbol (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify)))) ) ) - ((5) + (((game-option-type video-mode)) (case (-> (the-as (pointer uint32) (-> s5-0 (-> obj option-index) value-to-modify))) (('pal) (set! (-> *setting-control* default video-mode) @@ -1875,7 +1865,7 @@ ) ) ) - ((1) + (((game-option-type language)) (if (not (-> obj language-transition)) (load-level-text-files (-> obj display-level-index)) ) @@ -2238,8 +2228,8 @@ ) ) ) - (dummy-29 self) - (set! (-> self next-display-state) (dummy-53 self (-> self next-display-state))) + (respond-common self) + (set! (-> self next-display-state) (set-memcard-screen self (-> self next-display-state))) (let ((v1-74 (-> self display-state))) (cond ((or (= v1-74 (progress-screen fuel-cell)) @@ -2270,7 +2260,7 @@ (= v1-74 (progress-screen bad-disc)) (= v1-74 (progress-screen quit)) ) - (dummy-31 self) + (respond-memcard self) ) ) ) diff --git a/test/decompiler/reference/levels/beach/lurkercrab_REF.gc b/test/decompiler/reference/levels/beach/lurkercrab_REF.gc index 6c52171b24..23ad8d07ea 100644 --- a/test/decompiler/reference/levels/beach/lurkercrab_REF.gc +++ b/test/decompiler/reference/levels/beach/lurkercrab_REF.gc @@ -89,7 +89,7 @@ ;; definition for method 44 of type lurkercrab ;; INFO: Return type mismatch symbol vs object. (defmethod dummy-44 lurkercrab ((obj lurkercrab) (arg0 process) (arg1 event-message-block)) - (if (and (logtest? (-> obj nav-enemy-flags) 64) + (if (and (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf6)) ((method-of-type touching-shapes-entry prims-touching?) (the-as touching-shapes-entry (-> arg1 param 0)) (-> obj collide-info) @@ -106,7 +106,7 @@ 6144.0 16384.0 ) - (the-as object (if (zero? (logand (-> obj nav-enemy-flags) 256)) + (the-as object (if (zero? (logand (-> obj nav-enemy-flags) (nav-enemy-flags navenmf8))) (do-push-aways! (-> obj collide-info)) ) ) @@ -125,7 +125,7 @@ ) ((= v1-1 'punch) (cond - ((logtest? (-> obj nav-enemy-flags) 32) + ((logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf5)) (logclear! (-> obj mask) (process-mask actor-pause)) (go (method-of-object obj nav-enemy-die)) ) @@ -147,7 +147,7 @@ ) ) ) - ((logtest? (-> obj nav-enemy-flags) 32) + ((logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf5)) (logclear! (-> obj mask) (process-mask actor-pause)) (go (method-of-object obj nav-enemy-die)) ) @@ -178,7 +178,7 @@ nav-enemy-default-event-handler ;; INFO: Return type mismatch int vs none. (defmethod TODO-RENAME-37 lurkercrab ((obj lurkercrab)) (when (-> obj orient) - (if (logtest? (nav-control-flags bit19) (-> obj nav flags)) + (if (logtest? (nav-control-flags navcf19) (-> obj nav flags)) (seek-to-point-toward-point! (-> obj collide-info) (-> obj nav target-pos) @@ -293,7 +293,7 @@ nav-enemy-default-event-handler ;; definition for function lurkercrab-invulnerable (defbehavior lurkercrab-invulnerable lurkercrab () - (set! (-> self nav-enemy-flags) (logand -33 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf5)) (let ((v1-3 (find-prim-by-id (-> self collide-info) (the-as uint 2)))) (when v1-3 (let ((v0-1 4)) @@ -306,7 +306,7 @@ nav-enemy-default-event-handler ;; definition for function lurkercrab-vulnerable (defbehavior lurkercrab-vulnerable lurkercrab () - (logior! (-> self nav-enemy-flags) 32) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf5)) (let ((v1-3 (find-prim-by-id (-> self collide-info) (the-as uint 2)))) (when v1-3 (let ((v0-1 1)) @@ -328,8 +328,8 @@ nav-enemy-default-event-handler :exit (behavior () (lurkercrab-invulnerable) - (set! (-> self nav-enemy-flags) (logand -65 (-> self nav-enemy-flags))) - (logior! (-> self nav-enemy-flags) 8) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf6)) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (none) ) :code @@ -384,7 +384,7 @@ nav-enemy-default-event-handler (joint-control-channel-group! a0-12 (the-as art-joint-anim #f) num-func-loop!) ) (ja-channel-push! 1 180) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (nav-enemy-rnd-int-range 2 6) (until (not (nav-enemy-rnd-go-idle? 0.2)) (let ((gp-1 (-> self skel root-channel 0))) @@ -401,7 +401,7 @@ nav-enemy-default-event-handler ) ) ) - (logior! (-> self nav-enemy-flags) 8) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (let ((a0-19 (-> self skel root-channel 0))) (set! (-> a0-19 frame-group) (the-as art-joint-anim (-> self draw art-group data 5))) (set! (-> a0-19 param 0) @@ -436,7 +436,7 @@ nav-enemy-default-event-handler ) ) (lurkercrab-vulnerable) - (logior! (-> self nav-enemy-flags) 64) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf6)) (dotimes (gp-5 2) (let ((s5-0 (-> self skel root-channel 0))) (set! (-> s5-0 frame-group) (the-as art-joint-anim (-> self draw art-group data 7))) @@ -455,7 +455,7 @@ nav-enemy-default-event-handler ) ) (lurkercrab-invulnerable) - (set! (-> self nav-enemy-flags) (logand -65 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf6)) (let ((gp-6 (-> self skel root-channel 0))) (set! (-> gp-6 frame-group) (the-as art-joint-anim (-> self draw art-group data 8))) (set! (-> gp-6 param 0) (ja-aframe 90.0 0)) @@ -502,7 +502,7 @@ nav-enemy-default-event-handler :exit (behavior () (lurkercrab-invulnerable) - (set! (-> self nav-enemy-flags) (logand -65 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf6)) (none) ) :trans @@ -517,7 +517,7 @@ nav-enemy-default-event-handler ) :code (behavior () - (logior! (-> self nav-enemy-flags) 8) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (ja-channel-push! 1 22) (while #t (let ((a0-1 (-> self skel root-channel 0))) @@ -538,7 +538,7 @@ nav-enemy-default-event-handler ) ) (lurkercrab-vulnerable) - (logior! (-> self nav-enemy-flags) 64) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf6)) (let ((gp-0 (-> self skel root-channel 0))) (set! (-> gp-0 frame-group) (the-as art-joint-anim (-> self draw art-group data 7))) (set! (-> gp-0 param 0) (ja-aframe 30.0 0)) @@ -600,7 +600,7 @@ nav-enemy-default-event-handler ) ) (lurkercrab-invulnerable) - (set! (-> self nav-enemy-flags) (logand -65 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf6)) (let ((gp-8 (-> self skel root-channel 0))) (set! (-> gp-8 frame-group) (the-as art-joint-anim (-> self draw art-group data 8))) (set! (-> gp-8 param 0) (ja-aframe 90.0 0)) @@ -819,7 +819,7 @@ nav-enemy-default-event-handler :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -874,7 +874,7 @@ nav-enemy-default-event-handler (TODO-RENAME-45 obj *lurkercrab-nav-enemy-info*) (set! (-> obj part) (create-launch-control (-> *part-group-id-table* 159) obj)) (set! (-> obj orient) #t) - (set! (-> obj nav-enemy-flags) (logand -97 (-> obj nav-enemy-flags))) + (logclear! (-> obj nav-enemy-flags) (nav-enemy-flags navenmf5 navenmf6)) (set! (-> obj target-speed) 0.0) (set! (-> obj momentum-speed) 0.0) (set! (-> obj draw force-lod) 2) diff --git a/test/decompiler/reference/levels/beach/lurkerpuppy_REF.gc b/test/decompiler/reference/levels/beach/lurkerpuppy_REF.gc index 6057850018..3f191d6faf 100644 --- a/test/decompiler/reference/levels/beach/lurkerpuppy_REF.gc +++ b/test/decompiler/reference/levels/beach/lurkerpuppy_REF.gc @@ -123,7 +123,7 @@ nav-enemy-default-event-handler (joint-control-channel-group! a0-14 (the-as art-joint-anim (-> self draw art-group data 7)) num-func-seek!) ) (until (ja-done? 0) - (if (logtest? (-> self nav-enemy-flags) 256) + (if (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (go-virtual nav-enemy-attack) ) (suspend) @@ -151,10 +151,10 @@ nav-enemy-default-event-handler (behavior () (set! (-> self rotate-speed) 1456355.5) (set! (-> self turn-time) (seconds 0.1)) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((f30-0 (rand-vu-float-range 0.8 1.2))) (while #t - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (ja-channel-push! 1 30) (let ((gp-0 (-> self skel root-channel 0))) (set! (-> gp-0 frame-group) (the-as art-joint-anim (-> self draw art-group data 8))) @@ -165,9 +165,9 @@ nav-enemy-default-event-handler ) (until (ja-done? 0) (let ((f0-3 (ja-aframe-num 0))) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (if (and (>= f0-3 2.5) (>= 7.5 f0-3)) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) ) ) (suspend) @@ -177,7 +177,7 @@ nav-enemy-default-event-handler (joint-control-channel-group-eval! gp-1 (the-as art-joint-anim #f) num-func-seek!) ) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((a0-11 (-> self skel root-channel 0))) (set! (-> a0-11 param 0) 1.0) (joint-control-channel-group! a0-11 (the-as art-joint-anim #f) num-func-loop!) @@ -238,7 +238,7 @@ nav-enemy-default-event-handler (joint-control-channel-group-eval! a0-2 (the-as art-joint-anim #f) num-func-seek!) ) ) - (logclear! (-> self nav flags) (nav-control-flags bit17 bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf17 navcf19)) (nav-enemy-get-new-patrol-point) (let ((a0-7 (-> self skel root-channel 0))) (set! (-> a0-7 frame-group) (the-as art-joint-anim (-> self draw art-group data 5))) @@ -294,12 +294,12 @@ nav-enemy-default-event-handler ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (none) ) :code (behavior () - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (ja-channel-push! 1 22) (dotimes (gp-0 4) (let ((a0-2 (-> self skel root-channel 0))) @@ -313,9 +313,9 @@ nav-enemy-default-event-handler ) (until (ja-done? 0) (let ((f0-4 (ja-aframe-num 0))) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (if (and (>= f0-4 2.5) (>= 7.5 f0-4)) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) ) ) (suspend) @@ -382,7 +382,7 @@ nav-enemy-default-event-handler :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/test/decompiler/reference/levels/citadel/citb-bunny_REF.gc b/test/decompiler/reference/levels/citadel/citb-bunny_REF.gc index 0a72302986..f117da816c 100644 --- a/test/decompiler/reference/levels/citadel/citb-bunny_REF.gc +++ b/test/decompiler/reference/levels/citadel/citb-bunny_REF.gc @@ -77,7 +77,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/test/decompiler/reference/levels/common/babak_REF.gc b/test/decompiler/reference/levels/common/babak_REF.gc index c50a3e2f3b..36d566adeb 100644 --- a/test/decompiler/reference/levels/common/babak_REF.gc +++ b/test/decompiler/reference/levels/common/babak_REF.gc @@ -145,7 +145,7 @@ (behavior () (set! (-> self turn-time) (seconds 0.2)) (let ((f30-0 (nav-enemy-rnd-float-range 0.8 1.2))) - (when (or (logtest? (-> self nav-enemy-flags) 256) + (when (or (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (and (nav-enemy-player-vulnerable?) (nav-enemy-rnd-percent? 0.5)) ) (ja-channel-push! 1 30) @@ -167,7 +167,7 @@ ) (while #t (when (not (nav-enemy-facing-player? 2730.6667)) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((a0-9 (-> self skel root-channel 0))) (set! (-> a0-9 param 0) 1.0) (joint-control-channel-group! a0-9 (the-as art-joint-anim #f) num-func-loop!) @@ -188,7 +188,7 @@ (joint-control-channel-group-eval! a0-15 (the-as art-joint-anim #f) num-func-loop!) ) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) ) (if (not (= (if (> (-> self skel active-channels) 0) (-> self skel root-channel 0 frame-group) @@ -274,7 +274,7 @@ ) ) ) - (logclear! (-> self nav flags) (nav-control-flags bit17 bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf17 navcf19)) (nav-enemy-get-new-patrol-point) (let ((a0-12 (-> self skel root-channel 0))) (set! (-> a0-12 frame-group) (the-as art-joint-anim (-> self draw art-group data 10))) @@ -392,7 +392,7 @@ :use-proximity-notice #t :use-jump-blocked #t :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/test/decompiler/reference/levels/common/battlecontroller_REF.gc b/test/decompiler/reference/levels/common/battlecontroller_REF.gc index 019ddbc45b..460842be66 100644 --- a/test/decompiler/reference/levels/common/battlecontroller_REF.gc +++ b/test/decompiler/reference/levels/common/battlecontroller_REF.gc @@ -208,7 +208,7 @@ battlecontroller-default-event-handler (let* ((s5-0 (-> self spawner-array gp-0)) (s4-0 (handle->process (-> s5-0 creature))) ) - (when (and s4-0 (logtest? (-> (the-as nav-enemy s4-0) nav-enemy-flags) 2048)) + (when (and s4-0 (logtest? (-> (the-as nav-enemy s4-0) nav-enemy-flags) (nav-enemy-flags navenmf11))) (cond ((< (-> s5-0 state) (-> s5-0 path curve num-cverts)) (when (or (-> self noticed-player) (= (-> s5-0 state) 1)) @@ -216,7 +216,7 @@ battlecontroller-default-event-handler (eval-path-curve-div! (-> s5-0 path) s3-0 (the float (-> s5-0 state)) 'interp) (send-event s4-0 'cue-jump-to-point s3-0) ) - (if (zero? (logand (-> (the-as nav-enemy s4-0) nav-enemy-flags) 2048)) + (if (zero? (logand (-> (the-as nav-enemy s4-0) nav-enemy-flags) (nav-enemy-flags navenmf11))) (+! (-> s5-0 state) 1) ) ) @@ -266,7 +266,7 @@ battlecontroller-default-event-handler (when (the-as (pointer nav-enemy) gp-0) (logclear! (-> (the-as (pointer nav-enemy) gp-0) 0 mask) (process-mask actor-pause)) (if (-> self misty-ambush-collision-hack) - (logior! (-> (the-as (pointer nav-enemy) gp-0) 0 nav-enemy-flags) #x8000) + (logior! (-> (the-as (pointer nav-enemy) gp-0) 0 nav-enemy-flags) (nav-enemy-flags navenmf15)) ) (+! (-> self spawn-count) 1) (-> self fact pickup-type) diff --git a/test/decompiler/reference/levels/common/joint-exploder_REF.gc b/test/decompiler/reference/levels/common/joint-exploder_REF.gc index 5280ae892c..a07684e18d 100644 --- a/test/decompiler/reference/levels/common/joint-exploder_REF.gc +++ b/test/decompiler/reference/levels/common/joint-exploder_REF.gc @@ -505,7 +505,7 @@ (-> arg0 bbox) (collide-kind background) obj - (new 'static 'pat-surface :skip #x1 :noentity #x1) + (new 'static 'pat-surface :noentity #x1) ) (let ((gp-1 (-> obj joints)) (v1-2 (-> arg0 head)) diff --git a/test/decompiler/reference/levels/common/nav-enemy-h_REF.gc b/test/decompiler/reference/levels/common/nav-enemy-h_REF.gc index a86789d0b5..40dc649660 100644 --- a/test/decompiler/reference/levels/common/nav-enemy-h_REF.gc +++ b/test/decompiler/reference/levels/common/nav-enemy-h_REF.gc @@ -3,57 +3,57 @@ ;; definition of type nav-enemy-info (deftype nav-enemy-info (basic) - ((idle-anim int32 :offset-assert 4) - (walk-anim int32 :offset-assert 8) - (turn-anim int32 :offset-assert 12) - (notice-anim int32 :offset-assert 16) - (run-anim int32 :offset-assert 20) - (jump-anim int32 :offset-assert 24) - (jump-land-anim int32 :offset-assert 28) - (victory-anim int32 :offset-assert 32) - (taunt-anim int32 :offset-assert 36) - (die-anim int32 :offset-assert 40) - (neck-joint int32 :offset-assert 44) - (player-look-at-joint int32 :offset-assert 48) - (run-travel-speed meters :offset-assert 52) - (run-rotate-speed degrees :offset-assert 56) - (run-acceleration meters :offset-assert 60) - (run-turn-time seconds :offset-assert 64) - (walk-travel-speed meters :offset-assert 72) - (walk-rotate-speed degrees :offset-assert 76) - (walk-acceleration meters :offset-assert 80) - (walk-turn-time seconds :offset-assert 88) - (attack-shove-back meters :offset-assert 96) - (attack-shove-up meters :offset-assert 100) - (shadow-size meters :offset-assert 104) - (notice-nav-radius meters :offset-assert 108) - (nav-nearest-y-threshold meters :offset-assert 112) - (notice-distance meters :offset-assert 116) - (proximity-notice-distance meters :offset-assert 120) - (stop-chase-distance meters :offset-assert 124) - (frustration-distance meters :offset-assert 128) - (frustration-time time-frame :offset-assert 136) - (die-anim-hold-frame float :offset-assert 144) - (jump-anim-start-frame float :offset-assert 148) - (jump-land-anim-end-frame float :offset-assert 152) - (jump-height-min meters :offset-assert 156) - (jump-height-factor float :offset-assert 160) - (jump-start-anim-speed float :offset-assert 164) - (shadow-max-y meters :offset-assert 168) - (shadow-min-y meters :offset-assert 172) - (shadow-locus-dist meters :offset-assert 176) - (use-align symbol :offset-assert 180) - (draw-shadow symbol :offset-assert 184) - (move-to-ground symbol :offset-assert 188) - (hover-if-no-ground symbol :offset-assert 192) - (use-momentum symbol :offset-assert 196) - (use-flee symbol :offset-assert 200) - (use-proximity-notice symbol :offset-assert 204) - (use-jump-blocked symbol :offset-assert 208) - (use-jump-patrol symbol :offset-assert 212) - (gnd-collide-with uint64 :offset-assert 216) - (debug-draw-neck symbol :offset-assert 224) - (debug-draw-jump symbol :offset-assert 228) + ((idle-anim int32 :offset-assert 4) + (walk-anim int32 :offset-assert 8) + (turn-anim int32 :offset-assert 12) + (notice-anim int32 :offset-assert 16) + (run-anim int32 :offset-assert 20) + (jump-anim int32 :offset-assert 24) + (jump-land-anim int32 :offset-assert 28) + (victory-anim int32 :offset-assert 32) + (taunt-anim int32 :offset-assert 36) + (die-anim int32 :offset-assert 40) + (neck-joint int32 :offset-assert 44) + (player-look-at-joint int32 :offset-assert 48) + (run-travel-speed meters :offset-assert 52) + (run-rotate-speed degrees :offset-assert 56) + (run-acceleration meters :offset-assert 60) + (run-turn-time seconds :offset-assert 64) + (walk-travel-speed meters :offset-assert 72) + (walk-rotate-speed degrees :offset-assert 76) + (walk-acceleration meters :offset-assert 80) + (walk-turn-time seconds :offset-assert 88) + (attack-shove-back meters :offset-assert 96) + (attack-shove-up meters :offset-assert 100) + (shadow-size meters :offset-assert 104) + (notice-nav-radius meters :offset-assert 108) + (nav-nearest-y-threshold meters :offset-assert 112) + (notice-distance meters :offset-assert 116) + (proximity-notice-distance meters :offset-assert 120) + (stop-chase-distance meters :offset-assert 124) + (frustration-distance meters :offset-assert 128) + (frustration-time time-frame :offset-assert 136) + (die-anim-hold-frame float :offset-assert 144) + (jump-anim-start-frame float :offset-assert 148) + (jump-land-anim-end-frame float :offset-assert 152) + (jump-height-min meters :offset-assert 156) + (jump-height-factor float :offset-assert 160) + (jump-start-anim-speed float :offset-assert 164) + (shadow-max-y meters :offset-assert 168) + (shadow-min-y meters :offset-assert 172) + (shadow-locus-dist meters :offset-assert 176) + (use-align symbol :offset-assert 180) + (draw-shadow symbol :offset-assert 184) + (move-to-ground symbol :offset-assert 188) + (hover-if-no-ground symbol :offset-assert 192) + (use-momentum symbol :offset-assert 196) + (use-flee symbol :offset-assert 200) + (use-proximity-notice symbol :offset-assert 204) + (use-jump-blocked symbol :offset-assert 208) + (use-jump-patrol symbol :offset-assert 212) + (gnd-collide-with collide-kind :offset-assert 216) + (debug-draw-neck symbol :offset-assert 224) + (debug-draw-jump symbol :offset-assert 228) ) :method-count-assert 9 :size-assert #xe8 @@ -141,7 +141,7 @@ (state-timeout time-frame :offset-assert 352) (free-time time-frame :offset-assert 360) (touch-time time-frame :offset-assert 368) - (nav-enemy-flags uint32 :offset-assert 376) + (nav-enemy-flags nav-enemy-flags :offset-assert 376) (incomming-attack-id handle :offset-assert 384) (jump-return-state (state process) :offset-assert 392) (rand-gen random-generator :offset-assert 396) diff --git a/test/decompiler/reference/levels/common/nav-enemy_REF.gc b/test/decompiler/reference/levels/common/nav-enemy_REF.gc index 103119cac7..5cbc13f78a 100644 --- a/test/decompiler/reference/levels/common/nav-enemy_REF.gc +++ b/test/decompiler/reference/levels/common/nav-enemy_REF.gc @@ -79,14 +79,14 @@ ;; definition for method 39 of type nav-enemy ;; INFO: Return type mismatch int vs none. (defmethod common-post nav-enemy ((obj nav-enemy)) - (when (and (logtest? (-> obj nav-enemy-flags) 256) + (when (and (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf8)) (or (not *target*) (and (zero? (logand (-> *target* state-flags) #x80f8)) (>= (- (-> *display* base-frame-counter) (-> obj touch-time)) (seconds 0.05)) ) ) ) (set-collide-offense (-> obj collide-info) 2 (collide-offense touch)) - (set! (-> obj nav-enemy-flags) (logand -257 (-> obj nav-enemy-flags))) + (logclear! (-> obj nav-enemy-flags) (nav-enemy-flags navenmf8)) ) (update-direction-from-time-of-day (-> obj draw shadow-ctrl)) (when *target* @@ -94,13 +94,13 @@ (look-at-enemy! (-> *target* neck) (the-as vector (-> obj collide-info root-prim prim-core)) - (if (logtest? (-> obj nav-enemy-flags) 4) + (if (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf2)) 'attacking ) obj ) ) - (if (and (nonzero? (-> obj neck)) (logtest? (-> obj nav-enemy-flags) #x4000)) + (if (and (nonzero? (-> obj neck)) (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf14))) (set-target! (-> obj neck) (target-pos (-> obj nav-info player-look-at-joint))) ) ) @@ -116,11 +116,12 @@ ;; definition for method 44 of type nav-enemy (defmethod dummy-44 nav-enemy ((obj nav-enemy) (arg0 process) (arg1 event-message-block)) - (if (and (logtest? (-> obj nav-enemy-flags) 64) ((method-of-type touching-shapes-entry prims-touching?) - (the-as touching-shapes-entry (-> arg1 param 0)) - (-> obj collide-info) - (the-as uint 1) - ) + (if (and (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf6)) + ((method-of-type touching-shapes-entry prims-touching?) + (the-as touching-shapes-entry (-> arg1 param 0)) + (-> obj collide-info) + (the-as uint 1) + ) ) (nav-enemy-send-attack arg0 (the-as touching-shapes-entry (-> arg1 param 0)) 'generic) ) @@ -128,11 +129,12 @@ ;; definition for method 72 of type nav-enemy (defmethod nav-enemy-touch-handler nav-enemy ((obj nav-enemy) (arg0 process) (arg1 event-message-block)) - (if (and (logtest? (-> obj nav-enemy-flags) 64) ((method-of-type touching-shapes-entry prims-touching?) - (the-as touching-shapes-entry (-> arg1 param 0)) - (-> obj collide-info) - (the-as uint 1) - ) + (if (and (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf6)) + ((method-of-type touching-shapes-entry prims-touching?) + (the-as touching-shapes-entry (-> arg1 param 0)) + (-> obj collide-info) + (the-as uint 1) + ) ) (nav-enemy-send-attack arg0 (the-as touching-shapes-entry (-> arg1 param 0)) 'generic) ) @@ -150,7 +152,7 @@ ;; definition for method 43 of type nav-enemy (defmethod dummy-43 nav-enemy ((obj nav-enemy) (arg0 process) (arg1 event-message-block)) (cond - ((logtest? (-> obj nav-enemy-flags) 32) + ((logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf5)) (send-event arg0 'get-attack-count 1) (logclear! (-> obj mask) (process-mask actor-pause attackable)) (go (method-of-object obj nav-enemy-die)) @@ -177,7 +179,7 @@ ) (the-as object (when (send-event-function arg0 v1-0) (set-collide-offense (-> self collide-info) 2 (collide-offense no-offense)) - (logior! (-> self nav-enemy-flags) 256) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) #t ) ) @@ -215,9 +217,9 @@ ) ) (('cue-jump-to-point) - (when (logtest? (-> self nav-enemy-flags) 2048) + (when (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf11)) (set! (-> self event-param-point quad) (-> (the-as vector (-> arg3 param 0)) quad)) - (set! (-> self nav-enemy-flags) (logand -2049 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf11)) ) ) (('cue-chase) @@ -344,8 +346,10 @@ nav-enemy-default-event-handler ;; definition for method 37 of type nav-enemy ;; INFO: Return type mismatch int vs none. (defmethod TODO-RENAME-37 nav-enemy ((obj nav-enemy)) - (when (logtest? (-> obj nav-enemy-flags) 16) - (if (or (logtest? (-> obj nav-enemy-flags) 128) (logtest? (nav-control-flags bit19) (-> obj nav flags))) + (when (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags enable-travel)) + (if (or (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf7)) + (logtest? (nav-control-flags navcf19) (-> obj nav flags)) + ) (seek-to-point-toward-point! (-> obj collide-info) (-> obj nav target-pos) @@ -366,11 +370,11 @@ nav-enemy-default-event-handler (integrate-for-enemy-with-move-to-ground! (-> obj collide-info) (-> obj collide-info transv) - (the-as collide-kind (-> obj nav-info gnd-collide-with)) + (-> obj nav-info gnd-collide-with) 8192.0 #f (-> obj nav-info hover-if-no-ground) - (logtest? (-> obj nav-enemy-flags) #x8000) + (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf15)) ) (dummy-58 (-> obj collide-info) (-> obj collide-info transv)) ) @@ -382,7 +386,7 @@ nav-enemy-default-event-handler ;; INFO: Return type mismatch int vs none. (defbehavior nav-enemy-travel-post nav-enemy () (cond - ((logtest? (-> self nav-enemy-flags) 8) + ((logtest? (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (TODO-RENAME-9 (-> self align)) (dummy-40 self) (dummy-41 self) @@ -415,9 +419,9 @@ nav-enemy-default-event-handler ;; definition for function nav-enemy-patrol-post ;; INFO: Return type mismatch int vs none. (defbehavior nav-enemy-patrol-post nav-enemy () - (when (or (logtest? (nav-control-flags bit19) (-> self nav flags)) (< 2.0 (-> self nav block-count))) + (when (or (logtest? (nav-control-flags navcf19) (-> self nav flags)) (< 2.0 (-> self nav block-count))) (set! (-> self nav block-count) 2.0) - (logior! (-> self nav flags) (nav-control-flags bit10)) + (logior! (-> self nav flags) (nav-control-flags navcf10)) (nav-enemy-get-new-patrol-point) ) (dummy-19 @@ -427,8 +431,8 @@ nav-enemy-default-event-handler (-> self nav destination-pos) (-> self rotate-speed) ) - (if (logtest? (nav-control-flags bit21) (-> self nav flags)) - (logclear! (-> self nav flags) (nav-control-flags bit10)) + (if (logtest? (nav-control-flags navcf21) (-> self nav flags)) + (logclear! (-> self nav flags) (nav-control-flags navcf10)) ) (nav-enemy-travel-post) 0 @@ -467,7 +471,7 @@ nav-enemy-default-event-handler ;; definition for function nav-enemy-face-player-post ;; INFO: Return type mismatch int vs none. (defbehavior nav-enemy-face-player-post nav-enemy () - (if (and *target* (logtest? (-> self nav-enemy-flags) 16)) + (if (and *target* (logtest? (-> self nav-enemy-flags) (nav-enemy-flags enable-travel))) (seek-to-point-toward-point! (-> self collide-info) (target-pos 0) (-> self rotate-speed) (-> self turn-time)) ) (nav-enemy-simple-post) @@ -510,7 +514,7 @@ nav-enemy-default-event-handler ;; definition for function nav-enemy-neck-control-look-at ;; INFO: Return type mismatch int vs none. (defbehavior nav-enemy-neck-control-look-at nav-enemy () - (logior! (-> self nav-enemy-flags) #x4000) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf14)) (if (nonzero? (-> self neck)) (set-mode! (-> self neck) (joint-mod-handler-mode look-at)) ) @@ -521,8 +525,8 @@ nav-enemy-default-event-handler ;; definition for function nav-enemy-neck-control-inactive ;; INFO: Return type mismatch int vs none. (defbehavior nav-enemy-neck-control-inactive nav-enemy () - (when (and (nonzero? (-> self neck)) (logtest? (-> self nav-enemy-flags) #x4000)) - (set! (-> self nav-enemy-flags) (logand -16385 (-> self nav-enemy-flags))) + (when (and (nonzero? (-> self neck)) (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf14))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf14)) (shut-down! (-> self neck)) ) 0 @@ -539,7 +543,7 @@ nav-enemy-default-event-handler (defmethod TODO-RENAME-46 nav-enemy ((obj nav-enemy) (arg0 float)) (and *target* (zero? (logand (-> *target* state-flags) #x80f8)) - (and (or (zero? (logand (-> obj nav-enemy-flags) 4096)) + (and (or (zero? (logand (-> obj nav-enemy-flags) (nav-enemy-flags navenmf12))) (< (vector-vector-distance (target-pos 0) (-> obj collide-info trans)) arg0) ) (nav-enemy-test-point-near-nav-mesh? (-> *target* control shadow-pos)) @@ -551,10 +555,10 @@ nav-enemy-default-event-handler (defbehavior nav-enemy-notice-player? nav-enemy () (let ((gp-0 #f)) (cond - ((logtest? (-> self nav-enemy-flags) 1) + ((logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf0)) (when (>= (- (-> *display* base-frame-counter) (-> self notice-time)) (-> self reaction-time)) (set! gp-0 #t) - (set! (-> self nav-enemy-flags) (logand -2 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf0)) ) ) (else @@ -566,7 +570,7 @@ nav-enemy-default-event-handler ) ) ) - (logior! (-> self nav-enemy-flags) 1) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf0)) (set! (-> self notice-time) (-> *display* base-frame-counter)) ) ) @@ -830,15 +834,9 @@ nav-enemy-default-event-handler (nav-enemy-neck-control-inactive) (set! (-> self state-time) (-> *display* base-frame-counter)) (if (-> self nav-info move-to-ground) - (move-to-ground - (-> self collide-info) - 40960.0 - 40960.0 - #t - (the-as collide-kind (-> self nav-info gnd-collide-with)) - ) + (move-to-ground (-> self collide-info) 40960.0 40960.0 #t (-> self nav-info gnd-collide-with)) ) - (set! (-> self nav-enemy-flags) (logand -7 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1 navenmf2)) (set! (-> self state-timeout) (seconds 1)) (none) ) @@ -895,10 +893,10 @@ nav-enemy-default-event-handler (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) (set! (-> self nav flags) - (the-as nav-control-flags (the-as int (logior (nav-control-flags bit19) (-> self nav flags)))) + (the-as nav-control-flags (the-as int (logior (nav-control-flags navcf19) (-> self nav flags)))) ) - (set! (-> self nav-enemy-flags) (logand -5 (-> self nav-enemy-flags))) - (logior! (-> self nav-enemy-flags) 8) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (set! (-> self state-timeout) (seconds 1)) (set! (-> self target-speed) (-> self nav-info walk-travel-speed)) (set! (-> self acceleration) (-> self nav-info walk-acceleration)) @@ -908,7 +906,7 @@ nav-enemy-default-event-handler ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 8) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (none) ) :trans @@ -986,7 +984,7 @@ nav-enemy-default-event-handler (joint-control-channel-group! a0-5 (the-as art-joint-anim #f) num-func-loop!) ) (ja-channel-push! 1 180) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (let ((a0-8 (-> self skel root-channel 0))) (set! (-> a0-8 frame-group) (the-as art-joint-anim (-> self draw art-group data (-> self nav-info idle-anim))) @@ -1040,7 +1038,7 @@ nav-enemy-default-event-handler ) ) ) - (logior! (-> self nav-enemy-flags) 8) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (let ((a0-15 (-> self skel root-channel 0))) (set! (-> a0-15 param 0) 1.0) (joint-control-channel-group! a0-15 (the-as art-joint-anim #f) num-func-loop!) @@ -1091,12 +1089,12 @@ nav-enemy-default-event-handler ) :enter (behavior () - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (nav-enemy-neck-control-look-at) - (if (logtest? (-> self nav-enemy-flags) 2) + (if (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (go-virtual nav-enemy-chase) ) - (logior! (-> self nav-enemy-flags) 2) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (let ((gp-0 (-> self nav)) (v1-10 (target-pos 0)) ) @@ -1262,7 +1260,7 @@ nav-enemy-default-event-handler ;; INFO: Return type mismatch int vs none. ;; Used lq/sq (defbehavior nav-enemy-reset-frustration nav-enemy () - (set! (-> self nav-enemy-flags) (logand -8193 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf13)) (if *target* (set! (-> self frustration-point quad) (-> *target* control shadow-pos quad)) ) @@ -1280,7 +1278,9 @@ nav-enemy-default-event-handler ;; definition for function nav-enemy-frustrated? (defbehavior nav-enemy-frustrated? nav-enemy () - (and (logtest? (-> self nav-enemy-flags) 8192) (nav-enemy-player-at-frustration-point?)) + (and (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf13)) + (nav-enemy-player-at-frustration-point?) + ) ) ;; failed to figure out what this is: @@ -1296,7 +1296,7 @@ nav-enemy-default-event-handler (nav-enemy-neck-control-look-at) (set! (-> self state-time) (-> *display* base-frame-counter)) (set! (-> self free-time) (-> *display* base-frame-counter)) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (set! (-> self target-speed) (-> self nav-info run-travel-speed)) (set! (-> self acceleration) (-> self nav-info run-acceleration)) (set! (-> self rotate-speed) (-> self nav-info run-rotate-speed)) @@ -1309,7 +1309,7 @@ nav-enemy-default-event-handler (if (logtest? (-> *target* state-flags) 128) (go-virtual nav-enemy-patrol) ) - (if (logtest? (-> self nav-enemy-flags) 256) + (if (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (go-virtual nav-enemy-victory) ) (if (or (not (nav-enemy-player-at-frustration-point?)) @@ -1323,15 +1323,15 @@ nav-enemy-default-event-handler (if (>= (- (-> *display* base-frame-counter) (-> self frustration-time)) (+ (-> self reaction-time) (-> self nav-info frustration-time)) ) - (logior! (-> self nav-enemy-flags) 8192) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf13)) ) (if (or (not (TODO-RENAME-46 self (-> self nav-info stop-chase-distance))) - (logtest? (-> self nav-enemy-flags) 8192) + (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf13)) ) (go-virtual nav-enemy-stop-chase) ) (cond - ((logtest? (nav-control-flags bit17) (-> self nav flags)) + ((logtest? (nav-control-flags navcf17) (-> self nav flags)) (if (>= (- (-> *display* base-frame-counter) (-> self free-time)) (seconds 1)) (go-virtual nav-enemy-patrol) ) @@ -1406,7 +1406,7 @@ nav-enemy-default-event-handler (vector-vector-distance (-> self collide-info trans) (-> *target* control trans)) ) ) - (logtest? (nav-control-flags bit17) (-> self nav flags)) + (logtest? (nav-control-flags navcf17) (-> self nav flags)) (>= (- (-> *display* base-frame-counter) (-> self state-time)) (-> self state-timeout)) ) (go-virtual nav-enemy-stare) @@ -1452,7 +1452,7 @@ nav-enemy-default-event-handler :enter (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((f0-0 (vector-vector-distance (-> self collide-info trans) (target-pos 0)))) (set! (-> self state-timeout) (the-as @@ -1468,7 +1468,7 @@ nav-enemy-default-event-handler ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (none) ) :trans @@ -1499,7 +1499,7 @@ nav-enemy-default-event-handler ) ) ) - (set! (-> self nav-enemy-flags) (logand -5 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (if (>= (- (-> *display* base-frame-counter) (-> self state-time)) (-> self state-timeout)) (go-virtual nav-enemy-give-up) ) @@ -1508,7 +1508,7 @@ nav-enemy-default-event-handler (vector-vector-distance (-> self collide-info trans) (-> *target* control trans)) ) ) - (logtest? (nav-control-flags bit17) (-> self nav flags)) + (logtest? (nav-control-flags navcf17) (-> self nav flags)) ) (go-virtual nav-enemy-give-up) ) @@ -1536,7 +1536,7 @@ nav-enemy-default-event-handler (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) (nav-enemy-neck-control-inactive) - (set! (-> self nav-enemy-flags) (logand -5 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (none) ) :trans @@ -1705,7 +1705,7 @@ nav-enemy-default-event-handler ;; INFO: Return type mismatch int vs none. ;; Used lq/sq (defbehavior nav-enemy-jump-post nav-enemy () - (if (logtest? (-> self nav-enemy-flags) 16) + (if (logtest? (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (seek-to-point-toward-point! (-> self collide-info) (-> self jump-dest) @@ -1713,7 +1713,7 @@ nav-enemy-default-event-handler (-> self turn-time) ) ) - (when (logtest? (-> self nav-enemy-flags) 8) + (when (logtest? (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (let ((f30-0 (the float (- (-> *display* base-frame-counter) (-> self jump-time))))) (let ((v1-12 (eval-position! (-> self jump-trajectory) f30-0 (new 'stack-no-clear 'vector)))) (set! (-> self collide-info trans quad) (-> v1-12 quad)) @@ -1744,24 +1744,24 @@ nav-enemy-default-event-handler (set! (-> s2-2 y) 0.0) (vector-xz-normalize! s1-1 1.0) (vector-xz-normalize! s2-2 1.0) - (set! (-> self nav-enemy-flags) (logand -1537 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags standing-jump drop-jump)) (if (or (>= (* 0.5 (-> self nav-info run-travel-speed)) f24-0) (>= (cos 3640.889) (vector-dot s1-1 s2-2))) - (logior! (-> self nav-enemy-flags) 512) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags standing-jump)) ) ) (if (or (and (< f26-0 0.0) (< f28-0 (fabs f26-0))) (and (< (fabs f26-0) 12288.0) (< f28-0 20480.0))) - (logior! (-> self nav-enemy-flags) 1024) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags drop-jump)) ) ) - (when (and arg1 (logtest? (-> self nav-enemy-flags) 1024)) - (set! (-> self nav-enemy-flags) (logand -513 (-> self nav-enemy-flags))) + (when (and arg1 (logtest? (-> self nav-enemy-flags) (nav-enemy-flags drop-jump))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags standing-jump)) (set! f30-0 2048.0) ) (setup-from-to-height! (-> self jump-trajectory) s4-0 arg0 f30-0 (* 0.000011111111 arg4)) ) (set! (-> self nav extra-nav-sphere quad) (-> arg0 quad)) (set! (-> self nav extra-nav-sphere w) (-> self collide-info nav-radius)) - (logior! (-> self collide-info nav-flags) 2) + (logior! (-> self collide-info nav-flags) (nav-flags navf1)) 0 (none) ) @@ -1784,13 +1784,13 @@ nav-enemy-default-event-handler ;; INFO: Return type mismatch int vs none. ;; Used lq/sq (defbehavior nav-enemy-execute-custom-jump nav-enemy ((arg0 int) (arg1 float) (arg2 float)) - (when (logtest? (-> self nav-enemy-flags) 512) + (when (logtest? (-> self nav-enemy-flags) (nav-enemy-flags standing-jump)) (let ((a0-1 (-> self skel root-channel 0))) (set! (-> a0-1 param 0) 1.0) (joint-control-channel-group! a0-1 (the-as art-joint-anim #f) num-func-loop!) ) (ja-channel-push! 1 30) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (let ((s3-0 (-> self skel root-channel 0))) (set! (-> s3-0 frame-group) (the-as art-joint-anim (-> self draw art-group data arg0))) (set! (-> s3-0 param 0) (ja-aframe arg1 0)) @@ -1810,9 +1810,9 @@ nav-enemy-default-event-handler ) (set! (-> self collide-info status) (logand -8 (-> self collide-info status))) (set! (-> self jump-time) (-> *display* base-frame-counter)) - (logior! (-> self nav-enemy-flags) 8) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (cond - ((logtest? (-> self nav-enemy-flags) 1024) + ((logtest? (-> self nav-enemy-flags) (nav-enemy-flags drop-jump)) (cond ((= (if (> (-> self skel active-channels) 0) (-> self skel root-channel 0 frame-group) @@ -1864,7 +1864,7 @@ nav-enemy-default-event-handler ) (set! (-> self collide-info trans quad) (-> self jump-dest quad)) (set! (-> self collide-info transv y) 0.0) - (set! (-> self collide-info nav-flags) (logand -3 (-> self collide-info nav-flags))) + (logclear! (-> self collide-info nav-flags) (nav-flags navf1)) 0 (none) ) @@ -1938,7 +1938,7 @@ nav-enemy-default-event-handler ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 24) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) (none) ) :code @@ -1977,7 +1977,9 @@ nav-enemy-default-event-handler (set! (-> self collide-info transv x) (-> v1-9 x)) (set! (-> self collide-info transv z) (-> v1-9 z)) ) - (if (or (logtest? (-> self nav-enemy-flags) 128) (logtest? (nav-control-flags bit19) (-> self nav flags))) + (if (or (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf7)) + (logtest? (nav-control-flags navcf19) (-> self nav flags)) + ) (seek-to-point-toward-point! (-> self collide-info) (-> self nav target-pos) @@ -1998,7 +2000,7 @@ nav-enemy-default-event-handler (integrate-for-enemy-with-move-to-ground! (-> self collide-info) (-> self collide-info transv) - (the-as collide-kind (-> self nav-info gnd-collide-with)) + (-> self nav-info gnd-collide-with) 8192.0 #f (-> self nav-info hover-if-no-ground) @@ -2019,7 +2021,7 @@ nav-enemy-default-event-handler :enter (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (logclear! (-> self nav flags) (nav-control-flags bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf19)) (let ((gp-0 (new 'stack-no-clear 'vector))) (set! (-> gp-0 quad) (-> self collide-info transv quad)) (set! (-> gp-0 y) 0.0) @@ -2033,7 +2035,7 @@ nav-enemy-default-event-handler :trans (behavior () (if (or (>= (- (-> *display* base-frame-counter) (-> self state-time)) (seconds 0.5)) - (logtest? (nav-control-flags bit19) (-> self nav flags)) + (logtest? (nav-control-flags navcf19) (-> self nav flags)) ) (go-virtual nav-enemy-chase) ) @@ -2125,7 +2127,7 @@ nav-enemy-default-event-handler :code (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (logior! (-> self nav-enemy-flags) 2048) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf11)) (ja-channel-push! 1 30) (let ((f30-0 (nav-enemy-rnd-float-range 0.8 1.2))) (let ((v1-6 (-> self skel root-channel 0))) @@ -2137,7 +2139,7 @@ nav-enemy-default-event-handler (set! (-> v1-9 num-func) num-func-identity) (set! (-> v1-9 frame-num) 0.0) ) - (while (logtest? (-> self nav-enemy-flags) 2048) + (while (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf11)) (suspend) (let ((a0-8 (-> self skel root-channel 0))) (set! (-> a0-8 param 0) f30-0) @@ -2172,7 +2174,7 @@ nav-enemy-default-event-handler nav-enemy-jump-event-handler :exit (behavior () - (logior! (-> self nav-enemy-flags) 24) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) (none) ) :trans @@ -2185,15 +2187,15 @@ nav-enemy-default-event-handler (set! (-> self state-time) (-> *display* base-frame-counter)) (nav-enemy-initialize-jump (-> self event-param-point)) (nav-enemy-neck-control-look-at) - (logior! (-> self nav-enemy-flags) 16) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (when (not (nav-enemy-facing-point? (-> self jump-dest) 5461.3335)) (ja-channel-push! 1 60) (nav-enemy-turn-to-face-point (-> self jump-dest) 1820.4445) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (nav-enemy-execute-jump) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (nav-enemy-jump-land-anim) (go-virtual nav-enemy-wait-for-cue) (none) @@ -2239,7 +2241,7 @@ nav-enemy-default-event-handler ) (set! (-> obj align) (new 'process 'align-control obj)) (set! (-> obj nav) (new 'process 'nav-control (-> obj collide-info) 16 (-> arg0 nav-nearest-y-threshold))) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj nav gap-event) 'jump) (TODO-RENAME-26 (-> obj nav)) (set! (-> obj path) (new 'process 'path-control obj 'path 0.0)) @@ -2249,7 +2251,7 @@ nav-enemy-default-event-handler ) (set! (-> obj reaction-time) (nav-enemy-rnd-int-range (seconds 0.1) (seconds 0.8))) (set! (-> obj speed-scale) 1.0) - (logior! (-> obj nav-enemy-flags) 4216) + (logior! (-> obj nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel navenmf5 navenmf6 navenmf12)) 0 (none) ) @@ -2291,8 +2293,8 @@ nav-enemy-default-event-handler (vector-identity! (-> self collide-info scale)) (set! (-> self entity) (-> arg0 entity)) (TODO-RENAME-48 self) - (set! (-> self nav-enemy-flags) (logand -4097 (-> self nav-enemy-flags))) - (logior! (-> self nav-enemy-flags) 2) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf12)) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (go-virtual nav-enemy-wait-for-cue) (none) ) diff --git a/test/decompiler/reference/levels/common/sharkey_REF.gc b/test/decompiler/reference/levels/common/sharkey_REF.gc index 58ac7002e9..5c0560002a 100644 --- a/test/decompiler/reference/levels/common/sharkey_REF.gc +++ b/test/decompiler/reference/levels/common/sharkey_REF.gc @@ -273,7 +273,7 @@ nav-enemy-default-event-handler :enter (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (set! (-> self nav-enemy-flags) (logand -2 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf0)) (none) ) :exit @@ -295,8 +295,8 @@ nav-enemy-default-event-handler ) ) ((sharkey-notice-player?) - (when (zero? (logand (-> self nav-enemy-flags) 1)) - (logior! (-> self nav-enemy-flags) 1) + (when (zero? (logand (-> self nav-enemy-flags) (nav-enemy-flags navenmf0))) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf0)) (set! (-> self notice-time) (-> *display* base-frame-counter)) ) (let ((a0-4 (dummy-16 (-> self nav) (-> *target* control trans)))) @@ -313,7 +313,7 @@ nav-enemy-default-event-handler ) (else (if (>= (- (-> *display* base-frame-counter) (-> self notice-time)) (seconds 10)) - (set! (-> self nav-enemy-flags) (logand -2 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf0)) ) ) ) @@ -863,7 +863,7 @@ nav-enemy-default-event-handler :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/test/decompiler/reference/levels/finalboss/green-eco-lurker_REF.gc b/test/decompiler/reference/levels/finalboss/green-eco-lurker_REF.gc index 76c068bd70..1ee6719af5 100644 --- a/test/decompiler/reference/levels/finalboss/green-eco-lurker_REF.gc +++ b/test/decompiler/reference/levels/finalboss/green-eco-lurker_REF.gc @@ -120,7 +120,8 @@ :use-proximity-notice #f :use-jump-blocked #t :use-jump-patrol #f - :gnd-collide-with #x805 + :gnd-collide-with + (collide-kind background cak-2 ground-object) :debug-draw-neck #f :debug-draw-jump #f ) @@ -367,11 +368,12 @@ ;; definition for method 44 of type green-eco-lurker (defmethod dummy-44 green-eco-lurker ((obj green-eco-lurker) (arg0 process) (arg1 event-message-block)) - (when (and (logtest? (-> obj nav-enemy-flags) 64) ((method-of-type touching-shapes-entry prims-touching?) - (the-as touching-shapes-entry (-> arg1 param 0)) - (-> obj collide-info) - (the-as uint 1) - ) + (when (and (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf6)) + ((method-of-type touching-shapes-entry prims-touching?) + (the-as touching-shapes-entry (-> arg1 param 0)) + (-> obj collide-info) + (the-as uint 1) + ) ) (if (nav-enemy-send-attack arg0 (the-as touching-shapes-entry (-> arg1 param 0)) 'generic) (send-event (ppointer->process (-> obj parent)) 'blob-hit-jak) @@ -381,11 +383,12 @@ ;; definition for method 72 of type green-eco-lurker (defmethod nav-enemy-touch-handler green-eco-lurker ((obj green-eco-lurker) (arg0 process) (arg1 event-message-block)) - (when (and (logtest? (-> obj nav-enemy-flags) 64) ((method-of-type touching-shapes-entry prims-touching?) - (the-as touching-shapes-entry (-> arg1 param 0)) - (-> obj collide-info) - (the-as uint 1) - ) + (when (and (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf6)) + ((method-of-type touching-shapes-entry prims-touching?) + (the-as touching-shapes-entry (-> arg1 param 0)) + (-> obj collide-info) + (the-as uint 1) + ) ) (if (nav-enemy-send-attack arg0 (the-as touching-shapes-entry (-> arg1 param 0)) 'generic) (send-event (ppointer->process (-> obj parent)) 'blob-hit-jak) @@ -521,7 +524,7 @@ (+ (-> (the-as green-eco-lurker-gen (-> self parent 0)) root trans x) (fmax -32768.0 (fmin 32768.0 f0-1))) ) ) - (logior! (-> self collide-info nav-flags) 2) + (logior! (-> self collide-info nav-flags) (nav-flags navf1)) (set! (-> self nav extra-nav-sphere quad) (-> self appear-dest quad)) (set! (-> self nav extra-nav-sphere w) 8192.0) (setup-from-to-duration! (-> self traj) (-> self collide-info trans) (-> self appear-dest) 225.0 -9.102222) @@ -551,8 +554,8 @@ (let ((f30-0 (fmin (the float (- (-> *display* base-frame-counter) (-> self state-time))) (-> self traj time)))) (eval-position! (-> self traj) f30-0 (-> self collide-info trans)) (when (= f30-0 (-> self traj time)) - (logior! (-> self collide-info nav-flags) 1) - (set! (-> self collide-info nav-flags) (logand -3 (-> self collide-info nav-flags))) + (logior! (-> self collide-info nav-flags) (nav-flags navf0)) + (logclear! (-> self collide-info nav-flags) (nav-flags navf1)) (go green-eco-lurker-appear-land) ) ) @@ -687,7 +690,7 @@ (joint-control-channel-group-eval! a0-16 (the-as art-joint-anim #f) num-func-seek!) ) ) - (logior! (-> self nav-enemy-flags) 2) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (go-virtual nav-enemy-chase) (none) ) @@ -942,7 +945,7 @@ (defmethod TODO-RENAME-48 green-eco-lurker ((obj green-eco-lurker)) (initialize-skeleton obj *green-eco-lurker-sg* '()) (set! (-> obj draw origin-joint-index) (the-as uint 3)) - (set! (-> obj collide-info nav-flags) (logand -2 (-> obj collide-info nav-flags))) + (logclear! (-> obj collide-info nav-flags) (nav-flags navf0)) (TODO-RENAME-45 obj *green-eco-lurker-nav-enemy-info*) (logior! (-> obj draw shadow-ctrl settings flags) 4) (set! (-> obj neck up) (the-as uint 0)) diff --git a/test/decompiler/reference/levels/finalboss/robotboss_REF.gc b/test/decompiler/reference/levels/finalboss/robotboss_REF.gc index a793375441..9da1985ff0 100644 --- a/test/decompiler/reference/levels/finalboss/robotboss_REF.gc +++ b/test/decompiler/reference/levels/finalboss/robotboss_REF.gc @@ -4574,8 +4574,8 @@ (initialize-skeleton obj *robotboss-sg* '()) (aybabtu 2) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 (the-as float 40960.0))) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) - (set! (-> obj root-override nav-flags) (logand -2 (-> obj root-override nav-flags))) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) + (logclear! (-> obj root-override nav-flags) (nav-flags navf0)) (set! (-> obj path) (new 'process 'path-control obj 'path (the-as float 0.0))) (logior! (-> obj path flags) (path-control-flag display draw-line draw-point draw-text)) (logclear! (-> obj mask) (process-mask actor-pause)) diff --git a/test/decompiler/reference/levels/jungle/hopper_REF.gc b/test/decompiler/reference/levels/jungle/hopper_REF.gc index c9a34325aa..573f782373 100644 --- a/test/decompiler/reference/levels/jungle/hopper_REF.gc +++ b/test/decompiler/reference/levels/jungle/hopper_REF.gc @@ -57,9 +57,16 @@ nav-enemy-default-event-handler ) (set! (-> s5-0 quad) (-> arg0 quad)) (set! (-> s5-0 y) (+ 20480.0 (-> s5-0 y))) - (let ((f0-2 - (fill-and-probe-using-y-probe *collide-cache* s5-0 f30-0 (collide-kind background) self t1-0 (the-as uint 1)) - ) + (let ((f0-2 (fill-and-probe-using-y-probe + *collide-cache* + s5-0 + f30-0 + (collide-kind background) + self + t1-0 + (new 'static 'pat-surface :noentity #x1) + ) + ) ) (if (< f0-2 0.0) (return (the-as object #f)) @@ -88,18 +95,18 @@ nav-enemy-default-event-handler (-> self nav-info jump-height-factor) -409600.0 ) - (set! (-> self nav-enemy-flags) (logand -513 (-> self nav-enemy-flags))) - (set! (-> self nav-enemy-flags) (logand -1025 (-> self nav-enemy-flags))) - (logior! (-> self nav-enemy-flags) 16) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags standing-jump)) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags drop-jump)) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (when (not (nav-enemy-facing-point? (-> self jump-dest) 5461.3335)) (ja-channel-push! 1 60) (nav-enemy-turn-to-face-point (-> self jump-dest) 1820.4445) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (nav-enemy-execute-jump) (set! (-> self shadow-min-y) (+ (-> self collide-info trans y) (-> self nav-info shadow-min-y))) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (nav-enemy-jump-land-anim) 0 (none) @@ -181,7 +188,7 @@ nav-enemy-default-event-handler ) :trans (behavior () - (if (zero? (logand (-> self nav-enemy-flags) 8)) + (if (zero? (logand (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate))) ((-> (method-of-type nav-enemy nav-enemy-patrol) trans)) ) (none) @@ -190,7 +197,7 @@ nav-enemy-default-event-handler (behavior () (vector-reset! (-> self collide-info transv)) (set! (-> self jump-length) 16384.0) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (while #t (cond ((= (if (> (-> self skel active-channels) 0) @@ -263,9 +270,9 @@ nav-enemy-default-event-handler (joint-control-channel-group-eval! a0-21 (the-as art-joint-anim #f) num-func-loop!) ) ) - (when (or (logtest? (nav-control-flags bit19) (-> self nav flags)) (< 2.0 (-> self nav block-count))) + (when (or (logtest? (nav-control-flags navcf19) (-> self nav flags)) (< 2.0 (-> self nav block-count))) (set! (-> self nav block-count) 0.0) - (logior! (-> self nav flags) (nav-control-flags bit10)) + (logior! (-> self nav flags) (nav-control-flags navcf10)) (nav-enemy-get-new-patrol-point) (set! (-> self nav target-pos quad) (-> self nav destination-pos quad)) ) @@ -302,7 +309,7 @@ nav-enemy-default-event-handler ) :trans (behavior () - (if (zero? (logand (-> self nav-enemy-flags) 8)) + (if (zero? (logand (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate))) ((-> (method-of-type nav-enemy nav-enemy-chase) trans)) ) (none) @@ -311,7 +318,7 @@ nav-enemy-default-event-handler (behavior () (vector-reset! (-> self collide-info transv)) (set! (-> self jump-length) 32768.0) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (while #t (cond ((= (if (> (-> self skel active-channels) 0) @@ -457,7 +464,7 @@ nav-enemy-default-event-handler :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #t ) diff --git a/test/decompiler/reference/levels/jungle/junglefish_REF.gc b/test/decompiler/reference/levels/jungle/junglefish_REF.gc index db0883cbf0..6275cad9ed 100644 --- a/test/decompiler/reference/levels/jungle/junglefish_REF.gc +++ b/test/decompiler/reference/levels/jungle/junglefish_REF.gc @@ -392,7 +392,7 @@ nav-enemy-default-event-handler :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/test/decompiler/reference/levels/jungleb/aphid_REF.gc b/test/decompiler/reference/levels/jungleb/aphid_REF.gc index 4fbaa44517..02e935535a 100644 --- a/test/decompiler/reference/levels/jungleb/aphid_REF.gc +++ b/test/decompiler/reference/levels/jungleb/aphid_REF.gc @@ -32,14 +32,14 @@ ;; definition for function aphid-invulnerable (defbehavior aphid-invulnerable aphid () - (set! (-> self nav-enemy-flags) (logand -33 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf5)) (set-collide-offense (-> self collide-info) 2 (collide-offense indestructible)) (none) ) ;; definition for function aphid-vulnerable (defbehavior aphid-vulnerable aphid () - (logior! (-> self nav-enemy-flags) 32) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf5)) (set-collide-offense (-> self collide-info) 2 (collide-offense touch)) (none) ) @@ -47,7 +47,9 @@ ;; definition for method 43 of type aphid (defmethod dummy-43 aphid ((obj aphid) (arg0 process) (arg1 event-message-block)) (cond - ((or (logtest? (-> obj nav-enemy-flags) 32) (= arg0 (ppointer->process (-> obj parent)))) + ((or (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf5)) + (= arg0 (ppointer->process (-> obj parent))) + ) (send-event arg0 'get-attack-count 1) (logclear! (-> obj mask) (process-mask actor-pause attackable)) (go (method-of-object obj nav-enemy-die)) @@ -177,7 +179,7 @@ (behavior () (set! (-> self turn-time) (seconds 0.2)) (let ((f30-0 (nav-enemy-rnd-float-range 0.8 1.2))) - (when (or (logtest? (-> self nav-enemy-flags) 256) + (when (or (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (and (nav-enemy-player-vulnerable?) (nav-enemy-rnd-percent? 0.5)) ) (ja-channel-push! 1 30) @@ -201,7 +203,7 @@ ) (while #t (when (not (nav-enemy-facing-player? 2730.6667)) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((a0-7 (-> self skel root-channel 0))) (set! (-> a0-7 param 0) 1.0) (joint-control-channel-group! a0-7 (the-as art-joint-anim #f) num-func-loop!) @@ -222,7 +224,7 @@ (joint-control-channel-group-eval! a0-13 (the-as art-joint-anim #f) num-func-loop!) ) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) ) (when (nav-enemy-rnd-percent? 0.3) (if (not (= (if (> (-> self skel active-channels) 0) @@ -292,7 +294,7 @@ ) ) ) - (logclear! (-> self nav flags) (nav-control-flags bit17 bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf17 navcf19)) (nav-enemy-get-new-patrol-point) (let ((a0-12 (-> self skel root-channel 0))) (set! (-> a0-12 frame-group) (the-as art-joint-anim (-> self draw art-group data 8))) @@ -371,7 +373,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -431,7 +433,7 @@ (vector-identity! (-> self collide-info scale)) (set! (-> self entity) (-> arg0 entity)) (TODO-RENAME-48 self) - (set! (-> self nav-enemy-flags) (logand -4097 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf12)) (let ((a1-3 (new 'stack-no-clear 'event-message-block))) (set! (-> a1-3 from) self) (set! (-> a1-3 num-params) 0) diff --git a/test/decompiler/reference/levels/maincave/baby-spider_REF.gc b/test/decompiler/reference/levels/maincave/baby-spider_REF.gc index c4a5d034a1..d5e66580f7 100644 --- a/test/decompiler/reference/levels/maincave/baby-spider_REF.gc +++ b/test/decompiler/reference/levels/maincave/baby-spider_REF.gc @@ -146,7 +146,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -200,7 +200,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -656,7 +656,7 @@ baby-spider-default-event-handler (set! (-> self turn-time) (seconds 0.07333333)) (let ((f30-0 (rand-vu-float-range 0.8 1.2))) (while #t - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (ja-channel-push! 1 30) (let ((a0-2 (-> self skel root-channel 0))) (set! (-> a0-2 frame-group) (the-as art-joint-anim (-> self draw art-group data 12))) @@ -679,7 +679,7 @@ baby-spider-default-event-handler (set! (-> a0-5 param 0) 1.0) (joint-control-channel-group! a0-5 (the-as art-joint-anim #f) num-func-loop!) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((gp-0 (rand-vu-int-range 300 600)) (s5-0 (-> *display* base-frame-counter)) ) @@ -736,7 +736,7 @@ baby-spider-default-event-handler (joint-control-channel-group-eval! a0-2 (the-as art-joint-anim #f) num-func-seek!) ) ) - (logclear! (-> self nav flags) (nav-control-flags bit17 bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf17 navcf19)) (nav-enemy-get-new-patrol-point) (let ((a0-7 (-> self skel root-channel 0))) (set! (-> a0-7 frame-group) (the-as art-joint-anim (-> self draw art-group data 6))) @@ -976,7 +976,7 @@ baby-spider-default-event-handler (set! (-> obj mask) (logior (process-mask enemy) (-> obj mask))) (logior! (-> obj mask) (process-mask actor-pause)) (set! (-> obj nav) (new 'process 'nav-control (-> obj collide-info) 24 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj path) (new 'process 'path-control obj 'path 0.0)) (logior! (-> obj path flags) (path-control-flag display draw-line draw-point draw-text)) (create-connection! diff --git a/test/decompiler/reference/levels/maincave/mother-spider-egg_REF.gc b/test/decompiler/reference/levels/maincave/mother-spider-egg_REF.gc index 3ed33f301f..169293aca9 100644 --- a/test/decompiler/reference/levels/maincave/mother-spider-egg_REF.gc +++ b/test/decompiler/reference/levels/maincave/mother-spider-egg_REF.gc @@ -605,8 +605,8 @@ (logior! (-> v1-8 settings flags) 32) ) 0 - (set! (-> self root-override nav-flags) (logand -2 (-> self root-override nav-flags))) - (set! (-> self root-override nav-flags) (logand -3 (-> self root-override nav-flags))) + (logclear! (-> self root-override nav-flags) (nav-flags navf0)) + (logclear! (-> self root-override nav-flags) (nav-flags navf1)) (clear-collide-with-as (-> self root-override)) (until (not (-> self child)) (suspend) @@ -652,9 +652,9 @@ (setup-lods! (-> self broken-look) *mother-spider-egg-broken-sg* (-> self draw art-group) (-> self entity)) (set! (-> self draw shadow-ctrl) (new 'process 'shadow-control 0.0 0.0 614400.0 (the-as float 60) 245760.0)) (set! (-> self nav) (new 'process 'nav-control (-> self root-override) 16 40960.0)) - (logior! (-> self nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) - (set! (-> self root-override nav-flags) (logand -2 (-> self root-override nav-flags))) - (logior! (-> self root-override nav-flags) 2) + (logior! (-> self nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) + (logclear! (-> self root-override nav-flags) (nav-flags navf0)) + (logior! (-> self root-override nav-flags) (nav-flags navf1)) (set! (-> self nav extra-nav-sphere quad) (-> self fall-dest quad)) (set! (-> self nav extra-nav-sphere w) 4096.0) (setup-from-to-height! (-> self traj) (-> self root-override trans) arg2 4096.0 -4.551111) diff --git a/test/decompiler/reference/levels/maincave/mother-spider-proj_REF.gc b/test/decompiler/reference/levels/maincave/mother-spider-proj_REF.gc index 01dd1b9570..1dc1654e70 100644 --- a/test/decompiler/reference/levels/maincave/mother-spider-proj_REF.gc +++ b/test/decompiler/reference/levels/maincave/mother-spider-proj_REF.gc @@ -275,7 +275,7 @@ (the-as vector #f) f0-5 (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) 0.0 81920.0 ) diff --git a/test/decompiler/reference/levels/maincave/mother-spider_REF.gc b/test/decompiler/reference/levels/maincave/mother-spider_REF.gc index 48075121c7..b03c6e6835 100644 --- a/test/decompiler/reference/levels/maincave/mother-spider_REF.gc +++ b/test/decompiler/reference/levels/maincave/mother-spider_REF.gc @@ -2150,10 +2150,10 @@ (process-drawable-from-entity! obj arg0) (initialize-skeleton obj *mother-spider-sg* '()) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj nav nearest-y-threshold) 409600.0) - (set! (-> obj root-override nav-flags) (logand -2 (-> obj root-override nav-flags))) - (set! (-> obj root-override nav-flags) (logand -3 (-> obj root-override nav-flags))) + (logclear! (-> obj root-override nav-flags) (nav-flags navf0)) + (logclear! (-> obj root-override nav-flags) (nav-flags navf1)) (set! (-> obj path) (new 'process 'path-control obj 'path 0.0)) (logior! (-> obj path flags) (path-control-flag display draw-line draw-point draw-text)) (set! (-> obj fact) diff --git a/test/decompiler/reference/levels/misty/babak-with-cannon_REF.gc b/test/decompiler/reference/levels/misty/babak-with-cannon_REF.gc index 6025751ac4..31b44fe6a1 100644 --- a/test/decompiler/reference/levels/misty/babak-with-cannon_REF.gc +++ b/test/decompiler/reference/levels/misty/babak-with-cannon_REF.gc @@ -145,7 +145,7 @@ nav-enemy-default-event-handler (if (nav-enemy-notice-player?) (go-virtual nav-enemy-chase) ) - (if (logtest? (nav-control-flags bit19) (-> self nav flags)) + (if (logtest? (nav-control-flags navcf19) (-> self nav flags)) (go babak-with-cannon-jump-onto-cannon) ) (none) @@ -243,7 +243,7 @@ nav-enemy-default-event-handler ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 24) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) (none) ) :code @@ -251,7 +251,7 @@ nav-enemy-default-event-handler (set! (-> self state-time) (-> *display* base-frame-counter)) (set! (-> self rotate-speed) (-> self nav-info run-rotate-speed)) (set! (-> self turn-time) (-> self nav-info run-turn-time)) - (set! (-> self nav-enemy-flags) (logand -25 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) (nav-enemy-neck-control-inactive) (let* ((v1-7 (-> self cannon-ent)) (gp-0 (if v1-7 @@ -277,9 +277,9 @@ nav-enemy-default-event-handler (ja-channel-push! 1 60) (nav-enemy-turn-to-face-point (-> self jump-dest) 1820.4445) ) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (nav-enemy-execute-jump) - (set! (-> self nav-enemy-flags) (logand -25 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) (let* ((v1-20 (-> self cannon-ent)) (gp-1 (if v1-20 (-> v1-20 extra process) @@ -334,7 +334,7 @@ nav-enemy-default-event-handler ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 24) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) (none) ) :code @@ -342,7 +342,7 @@ nav-enemy-default-event-handler (set! (-> self state-time) (-> *display* base-frame-counter)) (nav-enemy-initialize-jump (-> self entity extra trans)) (nav-enemy-neck-control-look-at) - (set! (-> self nav-enemy-flags) (logand -25 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) (let ((a0-2 (-> self skel root-channel 0))) (set! (-> a0-2 frame-group) (the-as art-joint-anim (-> self draw art-group data 17))) (set! (-> a0-2 param 0) 0.0) @@ -364,7 +364,7 @@ nav-enemy-default-event-handler (ja-channel-push! 1 60) (nav-enemy-turn-to-face-point (-> self jump-dest) 1820.4445) ) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (nav-enemy-execute-jump) (let ((a1-6 (dummy-16 (-> self nav) (-> self jump-dest)))) (set-current-poly! (-> self nav) a1-6) diff --git a/test/decompiler/reference/levels/misty/bonelurker_REF.gc b/test/decompiler/reference/levels/misty/bonelurker_REF.gc index 9c0d936f20..89298303a1 100644 --- a/test/decompiler/reference/levels/misty/bonelurker_REF.gc +++ b/test/decompiler/reference/levels/misty/bonelurker_REF.gc @@ -52,20 +52,19 @@ ;; definition for method 44 of type bonelurker ;; INFO: Return type mismatch symbol vs object. (defmethod dummy-44 bonelurker ((obj bonelurker) (arg0 process) (arg1 event-message-block)) - (the-as - object - (when (and (logtest? (-> obj nav-enemy-flags) 64) ((method-of-type touching-shapes-entry prims-touching?) - (the-as touching-shapes-entry (-> arg1 param 0)) - (-> obj collide-info) - (the-as uint 1) - ) - ) - (when (nav-enemy-send-attack arg0 (the-as touching-shapes-entry (-> arg1 param 0)) 'generic) - (set! (-> obj speed-scale) 0.5) - #t - ) - ) - ) + (the-as object (when (and (logtest? (-> obj nav-enemy-flags) (nav-enemy-flags navenmf6)) + ((method-of-type touching-shapes-entry prims-touching?) + (the-as touching-shapes-entry (-> arg1 param 0)) + (-> obj collide-info) + (the-as uint 1) + ) + ) + (when (nav-enemy-send-attack arg0 (the-as touching-shapes-entry (-> arg1 param 0)) 'generic) + (set! (-> obj speed-scale) 0.5) + #t + ) + ) + ) ) ;; definition for method 43 of type bonelurker @@ -134,7 +133,7 @@ (send-event-function arg0 a1-6) ) (set! (-> obj bump-player-time) (-> *display* base-frame-counter)) - (set! (-> obj nav-enemy-flags) (logand -65 (-> obj nav-enemy-flags))) + (logclear! (-> obj nav-enemy-flags) (nav-enemy-flags navenmf6)) 'push ) ) @@ -256,10 +255,10 @@ nav-enemy-default-event-handler :trans (behavior () ((-> (method-of-type nav-enemy nav-enemy-chase) trans)) - (if (and (zero? (logand (-> self nav-enemy-flags) 64)) + (if (and (zero? (logand (-> self nav-enemy-flags) (nav-enemy-flags navenmf6))) (>= (- (-> *display* base-frame-counter) (-> self bump-player-time)) (seconds 0.5)) ) - (logior! (-> self nav-enemy-flags) 64) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf6)) ) (none) ) @@ -363,7 +362,7 @@ nav-enemy-default-event-handler (joint-control-channel-group-eval! a0-23 (the-as art-joint-anim #f) num-func-seek!) ) ) - (if (logtest? (-> self nav-enemy-flags) 256) + (if (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (go-virtual nav-enemy-victory) ) (let ((a0-25 (-> self skel root-channel 0))) @@ -383,7 +382,7 @@ nav-enemy-default-event-handler (joint-control-channel-group-eval! a0-26 (the-as art-joint-anim #f) num-func-seek!) ) ) - (if (logtest? (-> self nav-enemy-flags) 256) + (if (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (go-virtual nav-enemy-victory) ) (let ((a0-28 (-> self skel root-channel 0))) @@ -456,7 +455,7 @@ nav-enemy-default-event-handler ) (while #t (when (not (nav-enemy-facing-player? 2730.6667)) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (ja-channel-push! 1 60) (let ((v1-20 (-> self skel root-channel 0))) (set! (-> v1-20 frame-group) (the-as art-joint-anim (-> self draw art-group data 16))) @@ -473,7 +472,7 @@ nav-enemy-default-event-handler (joint-control-channel-group-eval! a0-14 (the-as art-joint-anim #f) num-func-loop!) ) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) ) (ja-channel-push! 1 75) (let ((a0-18 (-> self skel root-channel 0))) @@ -595,7 +594,7 @@ nav-enemy-default-event-handler ) ) ) - (logclear! (-> self nav flags) (nav-control-flags bit17 bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf17 navcf19)) (nav-enemy-get-new-patrol-point) (let ((a0-18 (-> self skel root-channel 0))) (set! (-> a0-18 frame-group) (the-as art-joint-anim (-> self draw art-group data 5))) @@ -732,7 +731,7 @@ nav-enemy-default-event-handler :use-proximity-notice #f :use-jump-blocked #t :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/test/decompiler/reference/levels/misty/mistycannon_REF.gc b/test/decompiler/reference/levels/misty/mistycannon_REF.gc index 44f4914c24..2f1c79bbc7 100644 --- a/test/decompiler/reference/levels/misty/mistycannon_REF.gc +++ b/test/decompiler/reference/levels/misty/mistycannon_REF.gc @@ -917,7 +917,7 @@ (-> self root-override shadow-pos) 8192.0 (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) 0.0 81920.0 ) diff --git a/test/decompiler/reference/levels/misty/muse_REF.gc b/test/decompiler/reference/levels/misty/muse_REF.gc index 3558eb1971..366e9ae4c3 100644 --- a/test/decompiler/reference/levels/misty/muse_REF.gc +++ b/test/decompiler/reference/levels/misty/muse_REF.gc @@ -409,8 +409,8 @@ nav-enemy-default-event-handler (-> self nav destination-pos) 546133.3 ) - (if (logtest? (nav-control-flags bit21) (-> self nav flags)) - (logclear! (-> self nav flags) (nav-control-flags bit10)) + (if (logtest? (nav-control-flags navcf21) (-> self nav flags)) + (logclear! (-> self nav flags) (nav-control-flags navcf10)) ) (nav-enemy-travel-post) (none) @@ -428,7 +428,7 @@ nav-enemy-default-event-handler :enter (behavior () ((-> (method-of-type nav-enemy nav-enemy-jump) enter)) - (set! (-> self nav-enemy-flags) (logand -513 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags standing-jump)) (none) ) :code @@ -641,7 +641,7 @@ nav-enemy-default-event-handler :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/test/decompiler/reference/levels/misty/quicksandlurker_REF.gc b/test/decompiler/reference/levels/misty/quicksandlurker_REF.gc index 4333127f5f..e01cc58a06 100644 --- a/test/decompiler/reference/levels/misty/quicksandlurker_REF.gc +++ b/test/decompiler/reference/levels/misty/quicksandlurker_REF.gc @@ -396,7 +396,7 @@ (the-as vector #f) 8192.0 (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) 0.0 81920.0 ) @@ -1240,7 +1240,7 @@ (set-yaw-angle-clear-roll-pitch! (-> obj root-override) (rand-vu-float-range 0.0 65536.0)) (initialize-skeleton obj *quicksandlurker-sg* '()) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj fact) (new 'process 'fact-info-enemy obj (pickup-type eco-pill-random) (-> *FACT-bank* default-pill-inc)) ) diff --git a/test/decompiler/reference/levels/ogre/ogreboss_REF.gc b/test/decompiler/reference/levels/ogre/ogreboss_REF.gc index 0eaeb00ec5..6e2358f82a 100644 --- a/test/decompiler/reference/levels/ogre/ogreboss_REF.gc +++ b/test/decompiler/reference/levels/ogre/ogreboss_REF.gc @@ -1179,7 +1179,7 @@ (the-as vector #f) (the-as float 49152.0) (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) (-> (new 'static 'array float 1 0.0) 0) (the-as float 409600.0) ) diff --git a/test/decompiler/reference/levels/racer_common/racer-states_REF.gc b/test/decompiler/reference/levels/racer_common/racer-states_REF.gc index ca1a6064ac..c9978a2507 100644 --- a/test/decompiler/reference/levels/racer_common/racer-states_REF.gc +++ b/test/decompiler/reference/levels/racer_common/racer-states_REF.gc @@ -1073,7 +1073,7 @@ (send-event (ppointer->process (-> self manipy)) 'draw #t) (send-event (ppointer->process (-> self manipy)) 'anim-mode 'clone-anim) (target-timed-invulnerable-off self) - (set! (-> self control pat-ignore-mask) (new 'static 'pat-surface :skip #x1 :noentity #x1)) + (set! (-> self control pat-ignore-mask) (new 'static 'pat-surface :noentity #x1)) (restore-collide-with-as (-> self control)) ((-> target-racing-start exit)) (target-exit) diff --git a/test/decompiler/reference/levels/robocave/cave-trap_REF.gc b/test/decompiler/reference/levels/robocave/cave-trap_REF.gc index 6560ed7c7d..00c4121ef2 100644 --- a/test/decompiler/reference/levels/robocave/cave-trap_REF.gc +++ b/test/decompiler/reference/levels/robocave/cave-trap_REF.gc @@ -398,9 +398,9 @@ ) (process-drawable-from-entity! obj arg0) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj nav nearest-y-threshold) 409600.0) - (set! (-> obj root-override nav-flags) (logand -2 (-> obj root-override nav-flags))) + (logclear! (-> obj root-override nav-flags) (nav-flags navf0)) (set! (-> obj path) (new 'process 'path-control obj 'path 0.0)) (logior! (-> obj path flags) (path-control-flag display draw-line draw-point draw-text)) (let ((s4-1 (entity-actor-count arg0 'alt-actor))) diff --git a/test/decompiler/reference/levels/rolling/rolling-lightning-mole_REF.gc b/test/decompiler/reference/levels/rolling/rolling-lightning-mole_REF.gc index afa746e30f..f5de402a0e 100644 --- a/test/decompiler/reference/levels/rolling/rolling-lightning-mole_REF.gc +++ b/test/decompiler/reference/levels/rolling/rolling-lightning-mole_REF.gc @@ -503,13 +503,13 @@ :virtual #t :enter (behavior () - (logior! (-> self nav flags) (nav-control-flags bit12)) + (logior! (-> self nav flags) (nav-control-flags navcf12)) ((-> (method-of-type nav-enemy nav-enemy-chase) enter)) (none) ) :exit (behavior () - (logclear! (-> self nav flags) (nav-control-flags bit12)) + (logclear! (-> self nav flags) (nav-control-flags navcf12)) (none) ) :trans @@ -1143,7 +1143,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -1173,7 +1173,7 @@ (process-drawable-from-entity! obj arg0) (initialize-skeleton obj *lightning-mole-sg* '()) (TODO-RENAME-45 obj *lightning-mole-nav-enemy-info*) - (logclear! (-> obj nav flags) (nav-control-flags bit5 bit6 bit7)) + (logclear! (-> obj nav flags) (nav-control-flags navcf5 navcf6 navcf7)) (set! (-> obj draw origin-joint-index) (the-as uint 3)) (set! (-> obj reaction-time) (seconds 0.05)) (set! (-> obj last-reflection-time) 0) diff --git a/test/decompiler/reference/levels/snow/ice-cube_REF.gc b/test/decompiler/reference/levels/snow/ice-cube_REF.gc index 8d6eb1430a..428d1b6c37 100644 --- a/test/decompiler/reference/levels/snow/ice-cube_REF.gc +++ b/test/decompiler/reference/levels/snow/ice-cube_REF.gc @@ -135,7 +135,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -463,7 +463,7 @@ (= (-> arg0 type) target) ) (set-collide-offense (-> self collide-info) 2 (collide-offense no-offense)) - (logior! (-> self nav-enemy-flags) 256) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (level-hint-spawn (game-text-id ice-cube-hint) "sksp0350" (the-as entity #f) *entity-pool* (game-task none)) ) ) @@ -497,8 +497,8 @@ (= (-> arg0 type) target) ) (set-collide-offense (-> self collide-info) 2 (collide-offense no-offense)) - (let ((v0-3 (the-as none (logior (-> self nav-enemy-flags) 256)))) - (set! (-> self nav-enemy-flags) (the-as uint v0-3)) + (let ((v0-3 (the-as none (logior (-> self nav-enemy-flags) (nav-enemy-flags navenmf8))))) + (set! (-> self nav-enemy-flags) (the-as nav-enemy-flags v0-3)) v0-3 ) ) @@ -744,7 +744,7 @@ (collide-kind background) (-> obj collide-info process) s4-0 - (the-as uint 1) + (new 'static 'pat-surface :noentity #x1) ) ) ) @@ -1038,7 +1038,7 @@ :code (behavior () (dummy-57 self) - (set! (-> self nav-enemy-flags) (logand -3 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (logclear! (-> self mask) (process-mask actor-pause)) (go ice-cube-face-player) (none) @@ -1054,7 +1054,7 @@ :enter (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (dummy-57 self) (logclear! (-> self mask) (process-mask actor-pause)) (if (or (not *target*) @@ -1233,7 +1233,7 @@ :enter (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (dummy-58 self) (if (or (not *target*) (logtest? (-> *target* state-flags) #x80f8) @@ -1347,7 +1347,7 @@ (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) (dummy-58 self) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (set! (-> self next-skid-sound-time) (-> *display* base-frame-counter)) (if (or (not *target*) (logtest? (-> *target* state-flags) #x80f8) @@ -1359,7 +1359,7 @@ (set! (-> self acceleration) (-> self nav-info run-acceleration)) (set! (-> self rotate-speed) (-> self nav-info run-rotate-speed)) (set! (-> self turn-time) (-> self nav-info run-turn-time)) - (logclear! (-> self nav flags) (nav-control-flags bit8)) + (logclear! (-> self nav flags) (nav-control-flags navcf8)) (set-root-prim-collide-with! (-> self collide-info) (collide-kind cak-2 cak-3 target crate enemy)) (set! (-> self track-target?) #t) (set! (-> self slow-down?) #f) @@ -1373,7 +1373,7 @@ ) :exit (behavior () - (logior! (-> self nav flags) (nav-control-flags bit8)) + (logior! (-> self nav flags) (nav-control-flags navcf8)) (set-root-prim-collide-with! (-> self collide-info) (collide-kind target)) (none) ) diff --git a/test/decompiler/reference/levels/snow/snow-bunny_REF.gc b/test/decompiler/reference/levels/snow/snow-bunny_REF.gc index dc6544ad27..7c973e28f0 100644 --- a/test/decompiler/reference/levels/snow/snow-bunny_REF.gc +++ b/test/decompiler/reference/levels/snow/snow-bunny_REF.gc @@ -123,7 +123,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -147,7 +147,7 @@ (when (send-event-function arg0 a1-5) (set! (-> self touch-time) (-> *display* base-frame-counter)) (set-collide-offense (-> self collide-info) 2 (collide-offense no-offense)) - (logior! (-> self nav-enemy-flags) 256) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (go-virtual snow-bunny-attack) ) ) @@ -292,8 +292,8 @@ ;; INFO: Return type mismatch int vs none. (defbehavior snow-bunny-initialize-jump snow-bunny ((arg0 vector)) (nav-enemy-initialize-custom-jump arg0 #f (-> self jump-height-min) (-> self jump-height-factor) -307200.0) - (set! (-> self nav-enemy-flags) (logand -1025 (-> self nav-enemy-flags))) - (logior! (-> self nav-enemy-flags) 512) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags drop-jump)) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags standing-jump)) 0 (none) ) @@ -479,9 +479,9 @@ (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) (dummy-76 self #f) - (set! (-> self nav flags) (logior (nav-control-flags bit19) (-> self nav flags))) - (set! (-> self nav-enemy-flags) (logand -5 (-> self nav-enemy-flags))) - (logior! (-> self nav-enemy-flags) 8) + (set! (-> self nav flags) (logior (nav-control-flags navcf19) (-> self nav flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (set! (-> self state-timeout) (seconds 0.1)) (none) ) @@ -583,7 +583,7 @@ (collide-kind background) (-> obj collide-info process) s4-0 - (the-as uint 1) + (new 'static 'pat-surface :noentity #x1) ) ) ) @@ -719,8 +719,8 @@ ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 24) - (set! (-> self collide-info nav-flags) (logand -3 (-> self collide-info nav-flags))) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) + (logclear! (-> self collide-info nav-flags) (nav-flags navf1)) (none) ) :trans @@ -753,12 +753,12 @@ snow-bunny-default-event-handler :enter (behavior () - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (nav-enemy-neck-control-look-at) - (if (logtest? (-> self nav-enemy-flags) 2) + (if (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (go-virtual nav-enemy-chase) ) - (logior! (-> self nav-enemy-flags) 2) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (dummy-76 self #t) (set-vector! (-> self collide-info transv) 0.0 (nav-enemy-rnd-float-range 102400.0 131072.0) 0.0 1.0) (none) @@ -958,7 +958,7 @@ (go-virtual snow-bunny-defend) ) (when (not (dummy-52 self)) - (set! (-> self nav-enemy-flags) (logand -3 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (go-virtual nav-enemy-notice) ) (set-jump-height-factor! self 1) @@ -970,8 +970,8 @@ ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 24) - (set! (-> self collide-info nav-flags) (logand -3 (-> self collide-info nav-flags))) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) + (logclear! (-> self collide-info nav-flags) (nav-flags navf1)) (none) ) :trans @@ -1268,8 +1268,8 @@ ) :exit (behavior () - (logior! (-> self nav-enemy-flags) 24) - (set! (-> self collide-info nav-flags) (logand -3 (-> self collide-info nav-flags))) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate enable-travel)) + (logclear! (-> self collide-info nav-flags) (nav-flags navf1)) (none) ) :trans diff --git a/test/decompiler/reference/levels/snow/snow-ram-boss_REF.gc b/test/decompiler/reference/levels/snow/snow-ram-boss_REF.gc index 289f3ba9f1..18e53ee293 100644 --- a/test/decompiler/reference/levels/snow/snow-ram-boss_REF.gc +++ b/test/decompiler/reference/levels/snow/snow-ram-boss_REF.gc @@ -157,7 +157,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -211,7 +211,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -537,7 +537,7 @@ (the-as vector #f) f0-9 (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) 0.0 81920.0 ) @@ -998,7 +998,7 @@ v0-4 ) ((begin - (if (zero? (logand (-> self nav-enemy-flags) 256)) + (if (zero? (logand (-> self nav-enemy-flags) (nav-enemy-flags navenmf8))) (do-push-aways! (-> self collide-info)) ) (level-hint-spawn @@ -1055,7 +1055,7 @@ ) ) (('touch) - (if (zero? (logand (-> self nav-enemy-flags) 256)) + (if (zero? (logand (-> self nav-enemy-flags) (nav-enemy-flags navenmf8))) (do-push-aways! (-> self collide-info)) ) (cond @@ -1320,7 +1320,7 @@ ) (else (ja-post) - (logior! (-> self nav-enemy-flags) 2) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (go ram-boss-idle) ) ) @@ -1472,7 +1472,7 @@ ) :code (behavior () - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (while #t (clone-anim-once (ppointer->handle (-> self parent-override)) @@ -1513,7 +1513,7 @@ :enter (behavior ((arg0 basic)) (dummy-52 self) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (let ((s5-0 (new 'stack-no-clear 'vector)) (gp-0 (-> self node-list data 0 bone transform)) ) @@ -1596,7 +1596,7 @@ (-> ram-boss-jump-down event) :code (behavior () - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (activate! *camera-smush-control* 409.6 37 150 1.0 0.99) (let ((a0-1 (-> self skel root-channel 0))) (set! (-> a0-1 frame-group) (the-as art-joint-anim (-> self draw art-group data 17))) @@ -1615,7 +1615,7 @@ (joint-control-channel-group-eval! a0-2 (the-as art-joint-anim #f) num-func-seek!) ) ) - (logior! (-> self nav-enemy-flags) 2) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1)) (go ram-boss-nav-start) (none) ) @@ -1627,7 +1627,7 @@ (defstate ram-boss-already-down (ram-boss) :code (behavior ((arg0 basic)) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (dummy-52 self) (let ((a1-0 (new 'stack-no-clear 'vector)) (a2-0 (-> self parent-override 0 node-list data 0 bone transform)) @@ -1750,7 +1750,7 @@ ) ) (cond - ((logtest? (nav-control-flags bit17) (-> self nav flags)) + ((logtest? (nav-control-flags navcf17) (-> self nav flags)) (if (>= (- (-> *display* base-frame-counter) (-> self free-time)) (seconds 1)) (go-virtual nav-enemy-patrol) ) @@ -1812,7 +1812,7 @@ (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) (set! (-> self facing-y) (quaternion-y-angle (-> self collide-info quat))) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (none) ) :trans @@ -2016,7 +2016,7 @@ :enter (behavior () (set! (-> self frustration) 0) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (none) ) :trans @@ -2057,7 +2057,7 @@ :enter (behavior () (set! (-> self frustration) 0) - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (none) ) :trans @@ -2171,7 +2171,7 @@ ram-boss-on-ground-event-handler :enter (behavior () - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (let ((gp-0 (-> self child))) (while gp-0 (send-event (ppointer->process gp-0) 'launch) @@ -2241,7 +2241,7 @@ (defstate ram-boss-lose-shield (ram-boss) :enter (behavior () - (logior! (-> self nav-enemy-flags) 4) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags navenmf2)) (nav-enemy-neck-control-inactive) (dummy-53 self) (TODO-RENAME-49 self *ram-boss-nav-enemy-info-no-shield*) diff --git a/test/decompiler/reference/levels/snow/yeti_REF.gc b/test/decompiler/reference/levels/snow/yeti_REF.gc index 791f9cc3e2..97dcc98826 100644 --- a/test/decompiler/reference/levels/snow/yeti_REF.gc +++ b/test/decompiler/reference/levels/snow/yeti_REF.gc @@ -122,7 +122,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -251,7 +251,7 @@ (if (-> self nav-info move-to-ground) (move-to-ground (-> self collide-info) 40960.0 40960.0 #t (collide-kind background)) ) - (set! (-> self nav-enemy-flags) (logand -7 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags navenmf1 navenmf2)) (set! (-> self state-timeout) (seconds 1)) (set! (-> self ground-y) (-> self collide-info trans y)) (spawn (-> self part) (-> self collide-info trans)) @@ -413,7 +413,7 @@ (joint-control-channel-group! a0-14 (the-as art-joint-anim #f) num-func-loop!) ) (ja-channel-push! 1 180) - (set! (-> self nav-enemy-flags) (logand -9 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (let ((gp-1 (nav-enemy-rnd-int-range 2 6))) (dotimes (s5-0 gp-1) (let ((a0-18 (-> self skel root-channel 0))) @@ -436,7 +436,7 @@ ) ) ) - (logior! (-> self nav-enemy-flags) 8) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-rotate)) (let ((a0-21 (-> self skel root-channel 0))) (set! (-> a0-21 param 0) 1.0) (joint-control-channel-group! a0-21 (the-as art-joint-anim #f) num-func-loop!) @@ -541,7 +541,7 @@ (behavior () (set! (-> self turn-time) (seconds 0.2)) (let ((f30-0 (nav-enemy-rnd-float-range 0.8 1.2))) - (when (or (logtest? (-> self nav-enemy-flags) 256) + (when (or (logtest? (-> self nav-enemy-flags) (nav-enemy-flags navenmf8)) (and (nav-enemy-player-vulnerable?) (nav-enemy-rnd-percent? 0.5)) ) (ja-channel-push! 1 30) @@ -563,7 +563,7 @@ ) (while #t (when (not (nav-enemy-facing-player? 2730.6667)) - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((a0-9 (-> self skel root-channel 0))) (set! (-> a0-9 param 0) 1.0) (joint-control-channel-group! a0-9 (the-as art-joint-anim #f) num-func-loop!) @@ -584,7 +584,7 @@ (joint-control-channel-group-eval! a0-15 (the-as art-joint-anim #f) num-func-loop!) ) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) ) (if (not (= (if (> (-> self skel active-channels) 0) (-> self skel root-channel 0 frame-group) @@ -670,7 +670,7 @@ ) ) ) - (logclear! (-> self nav flags) (nav-control-flags bit17 bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf17 navcf19)) (nav-enemy-get-new-patrol-point) (let ((a0-12 (-> self skel root-channel 0))) (set! (-> a0-12 frame-group) (the-as art-joint-anim (-> self draw art-group data 7))) diff --git a/test/decompiler/reference/levels/sunken/bully_REF.gc b/test/decompiler/reference/levels/sunken/bully_REF.gc index 4d57d2274e..7bcfbdc6d9 100644 --- a/test/decompiler/reference/levels/sunken/bully_REF.gc +++ b/test/decompiler/reference/levels/sunken/bully_REF.gc @@ -1106,7 +1106,7 @@ (initialize-skeleton obj *bully-sg* '()) (set! (-> obj draw shadow-ctrl) *bully-shadow-control*) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj part) (create-launch-control (-> *part-group-id-table* 454) obj)) (set! (-> obj fact-override) (new 'process 'fact-info-enemy obj (pickup-type eco-pill-random) (-> *FACT-bank* default-pill-inc)) diff --git a/test/decompiler/reference/levels/sunken/double-lurker_REF.gc b/test/decompiler/reference/levels/sunken/double-lurker_REF.gc index ee679e5862..82fc4384ac 100644 --- a/test/decompiler/reference/levels/sunken/double-lurker_REF.gc +++ b/test/decompiler/reference/levels/sunken/double-lurker_REF.gc @@ -136,7 +136,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -191,7 +191,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -246,7 +246,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) @@ -352,8 +352,8 @@ (set! (-> v1-3 settings flags) (logand -33 (-> v1-3 settings flags))) ) 0 - (set! (-> self collide-info nav-flags) (logand -2 (-> self collide-info nav-flags))) - (logior! (-> self collide-info nav-flags) 2) + (logclear! (-> self collide-info nav-flags) (nav-flags navf0)) + (logior! (-> self collide-info nav-flags) (nav-flags navf1)) (set! (-> self nav extra-nav-sphere quad) (-> self fall-dest quad)) (set! (-> self nav extra-nav-sphere w) 9011.2) (let ((gp-0 (new 'stack-no-clear 'vector))) @@ -383,8 +383,8 @@ ) ) ) - (logior! (-> self collide-info nav-flags) 1) - (set! (-> self collide-info nav-flags) (logand -3 (-> self collide-info nav-flags))) + (logior! (-> self collide-info nav-flags) (nav-flags navf0)) + (logclear! (-> self collide-info nav-flags) (nav-flags navf1)) (TODO-RENAME-27 (-> self nav)) (go double-lurker-top-resume) (none) @@ -466,7 +466,7 @@ ;; definition for method 51 of type double-lurker-top (defmethod dummy-51 double-lurker-top ((obj double-lurker-top)) (restore-collide-with-as (-> obj collide-info)) - (logior! (-> obj collide-info nav-flags) 1) + (logior! (-> obj collide-info nav-flags) (nav-flags navf0)) (TODO-RENAME-27 (-> obj nav)) (none) ) @@ -543,7 +543,7 @@ ) ;; definition for method 48 of type double-lurker-top -;; INFO: Return type mismatch uint vs none. +;; INFO: Return type mismatch nav-flags vs none. ;; Used lq/sq (defmethod TODO-RENAME-48 double-lurker-top ((obj double-lurker-top)) (initialize-skeleton obj *double-lurker-top-sg* '()) @@ -554,7 +554,7 @@ (set-vector! (-> obj collide-info scale) 1.0 1.0 1.0 1.0) (quaternion-copy! (-> obj collide-info quat) (-> v1-5 0 collide-info quat)) ) - (set! (-> obj collide-info nav-flags) (logand -2 (-> obj collide-info nav-flags))) + (logclear! (-> obj collide-info nav-flags) (nav-flags navf0)) (none) ) diff --git a/test/decompiler/reference/levels/sunken/orbit-plat_REF.gc b/test/decompiler/reference/levels/sunken/orbit-plat_REF.gc index 95433dd76d..d5599c641c 100644 --- a/test/decompiler/reference/levels/sunken/orbit-plat_REF.gc +++ b/test/decompiler/reference/levels/sunken/orbit-plat_REF.gc @@ -591,7 +591,7 @@ ;; Used lq/sq (defun get-nav-point! ((arg0 vector) (arg1 orbit-plat) (arg2 vector) (arg3 float)) (set! (-> arg1 nav target-pos quad) (-> arg2 quad)) - (logclear! (-> arg1 nav flags) (nav-control-flags bit19)) + (logclear! (-> arg1 nav flags) (nav-control-flags navcf19)) (dummy-11 (-> arg1 nav) (-> arg1 nav target-pos)) (let ((f0-0 (vector-length (-> arg1 nav travel)))) (if (< arg3 f0-0) @@ -759,7 +759,7 @@ ) ) (when (>= 614.4 (vector-vector-xz-distance (-> obj basetrans) (-> obj reset-trans))) - (set! v0-11 (logior (nav-control-flags bit19) (-> obj nav flags))) + (set! v0-11 (logior (nav-control-flags navcf19) (-> obj nav flags))) (set! (-> obj nav flags) (the-as nav-control-flags v0-11)) v0-11 ) @@ -786,7 +786,7 @@ (vector-normalize! s5-2 (-> obj reset-length)) (vector+! s5-2 s5-2 s4-1) (when (not (dummy-16 (-> obj nav) s5-2)) - (logclear! (-> obj nav flags) (nav-control-flags bit19)) + (logclear! (-> obj nav flags) (nav-control-flags navcf19)) (get-rotate-point! s5-2 s4-1 (-> obj basetrans) (the-as vector (-> obj reset-length)) 0.0 40960.0) (when (not (dummy-16 (-> obj nav) s5-2)) (get-rotate-point! @@ -855,13 +855,13 @@ :code (behavior () (set! (-> self plat-status) (the-as uint 3)) - (logclear! (-> self nav flags) (nav-control-flags bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf19)) (let ((a0-3 (-> self skel root-channel 0))) (set! (-> a0-3 param 0) 0.0) (set! (-> a0-3 param 1) 1.0) (joint-control-channel-group! a0-3 (the-as art-joint-anim #f) num-func-seek!) ) - (while (zero? (logand (nav-control-flags bit19) (-> self nav flags))) + (while (zero? (logand (nav-control-flags navcf19) (-> self nav flags))) (dummy-27 self) (when (nonzero? (-> self root-override riders num-riders)) (let ((a1-1 (new 'stack-no-clear 'event-message-block))) @@ -974,7 +974,7 @@ (update-transforms! (-> obj root-override)) (dummy-21 obj) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj nav gap-event) 'blocked) (set! (-> obj other) (entity-actor-lookup arg0 'alt-actor 0)) (let ((f0-7 (res-lump-float arg0 'scale :default 1.0))) diff --git a/test/decompiler/reference/levels/sunken/puffer_REF.gc b/test/decompiler/reference/levels/sunken/puffer_REF.gc index a205477759..bd2a20a0b4 100644 --- a/test/decompiler/reference/levels/sunken/puffer_REF.gc +++ b/test/decompiler/reference/levels/sunken/puffer_REF.gc @@ -1276,7 +1276,7 @@ (set! (-> obj notice-dist) (res-lump-float arg0 'notice-dist :default 57344.0)) (set! (-> obj give-up-dist) (+ 20480.0 (-> obj notice-dist))) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (TODO-RENAME-26 (-> obj nav)) (set! (-> obj path) (new 'process 'path-control obj 'path 0.0)) (logior! (-> obj path flags) (path-control-flag display draw-line draw-point draw-text)) diff --git a/test/decompiler/reference/levels/swamp/billy_REF.gc b/test/decompiler/reference/levels/swamp/billy_REF.gc index 6217dd4b08..f2286b8fe0 100644 --- a/test/decompiler/reference/levels/swamp/billy_REF.gc +++ b/test/decompiler/reference/levels/swamp/billy_REF.gc @@ -329,7 +329,7 @@ ) ) (send-event (ppointer->process (-> self billy)) 'billy-rat-needs-destination) - (logclear! (-> self nav flags) (nav-control-flags bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf19)) (go-virtual nav-enemy-chase) (none) ) @@ -400,8 +400,8 @@ (t9-1) ) ) - (when (logtest? (nav-control-flags bit19) (-> self nav flags)) - (logclear! (-> self nav flags) (nav-control-flags bit19)) + (when (logtest? (nav-control-flags navcf19) (-> self nav flags)) + (logclear! (-> self nav flags) (nav-control-flags navcf19)) (if (rat-about-to-eat? self (-> self billy 0)) (go billy-rat-salivate) (send-event (ppointer->process (-> self billy)) 'billy-rat-needs-destination) @@ -427,7 +427,7 @@ :trans (behavior () (set! (-> self speed-scale) (-> self billy 0 rat-speed)) - (if (or (logtest? (nav-control-flags bit19) (-> self nav flags)) + (if (or (logtest? (nav-control-flags navcf19) (-> self nav flags)) (>= (- (-> *display* base-frame-counter) (-> self state-time)) (-> self chase-rest-time)) ) (go-virtual nav-enemy-victory) diff --git a/test/decompiler/reference/levels/swamp/kermit_REF.gc b/test/decompiler/reference/levels/swamp/kermit_REF.gc index ad7429941b..7110dba8bc 100644 --- a/test/decompiler/reference/levels/swamp/kermit_REF.gc +++ b/test/decompiler/reference/levels/swamp/kermit_REF.gc @@ -650,7 +650,7 @@ (the-as vector #f) 8192.0 (collide-kind background) - (the-as process #f) + (the-as process-drawable #f) 0.0 81920.0 ) @@ -1016,7 +1016,7 @@ ;; Used lq/sq (defbehavior kermit-set-rotate-dir-to-nav-target kermit () (cond - ((logtest? (nav-control-flags bit19) (-> self nav flags)) + ((logtest? (nav-control-flags navcf19) (-> self nav flags)) (vector-! (-> self rotate-dir) (-> self nav target-pos) (-> self collide-info trans)) ) (else @@ -1180,7 +1180,7 @@ nav-enemy-default-event-handler (if (and (not (-> self airborne)) (nav-enemy-test-point-in-nav-mesh? (target-pos 0))) (go kermit-notice) ) - (if (logtest? (nav-control-flags bit19) (-> self nav flags)) + (if (logtest? (nav-control-flags navcf19) (-> self nav flags)) (kermit-get-new-patrol-point) ) (none) @@ -1300,7 +1300,7 @@ nav-enemy-default-event-handler (behavior () (when (not (-> self airborne)) (if (or (>= (- (-> *display* base-frame-counter) (-> self state-time)) (seconds 3)) - (and (logtest? (nav-control-flags bit19) (-> self nav flags)) + (and (logtest? (nav-control-flags navcf19) (-> self nav flags)) (>= (- (-> *display* base-frame-counter) (-> self state-time)) (seconds 0.5)) ) ) @@ -1739,7 +1739,7 @@ nav-enemy-default-event-handler :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/test/decompiler/reference/levels/swamp/swamp-rat-nest_REF.gc b/test/decompiler/reference/levels/swamp/swamp-rat-nest_REF.gc index 13c281039b..b04b1721cb 100644 --- a/test/decompiler/reference/levels/swamp/swamp-rat-nest_REF.gc +++ b/test/decompiler/reference/levels/swamp/swamp-rat-nest_REF.gc @@ -994,7 +994,7 @@ (set! (-> self entity) gp-0) ) (set! (-> self nav) (new 'process 'nav-control (-> self root-override) 16 40960.0)) - (logior! (-> self nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> self nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set-current-poly! (-> self nav) (find-poly (-> self nav) (-> self root-override trans))) (+! (-> self parent-process 0 hit-points) 3) (dummy-21 self) diff --git a/test/decompiler/reference/levels/swamp/swamp-rat_REF.gc b/test/decompiler/reference/levels/swamp/swamp-rat_REF.gc index 8809656567..4ca44f90a4 100644 --- a/test/decompiler/reference/levels/swamp/swamp-rat_REF.gc +++ b/test/decompiler/reference/levels/swamp/swamp-rat_REF.gc @@ -327,7 +327,7 @@ swamp-rat-default-event-handler (set! (-> self turn-time) (seconds 0.07333333)) (let ((f30-0 (rand-vu-float-range 0.8 1.2))) (while #t - (logior! (-> self nav-enemy-flags) 16) + (logior! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (ja-channel-push! 1 30) (let ((a0-2 (-> self skel root-channel 0))) (set! (-> a0-2 frame-group) (the-as art-joint-anim (-> self draw art-group data 10))) @@ -350,7 +350,7 @@ swamp-rat-default-event-handler (set! (-> a0-5 param 0) 1.0) (joint-control-channel-group! a0-5 (the-as art-joint-anim #f) num-func-loop!) ) - (set! (-> self nav-enemy-flags) (logand -17 (-> self nav-enemy-flags))) + (logclear! (-> self nav-enemy-flags) (nav-enemy-flags enable-travel)) (let ((gp-0 (rand-vu-int-range 300 600)) (s5-0 (-> *display* base-frame-counter)) ) @@ -395,7 +395,7 @@ swamp-rat-default-event-handler (joint-control-channel-group-eval! a0-2 (the-as art-joint-anim #f) num-func-seek!) ) ) - (logclear! (-> self nav flags) (nav-control-flags bit17 bit19)) + (logclear! (-> self nav flags) (nav-control-flags navcf17 navcf19)) (nav-enemy-get-new-patrol-point) (let ((a0-7 (-> self skel root-channel 0))) (set! (-> a0-7 frame-group) (the-as art-joint-anim (-> self draw art-group data 4))) @@ -595,7 +595,7 @@ swamp-rat-default-event-handler :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/test/decompiler/reference/levels/village1/village-obs_REF.gc b/test/decompiler/reference/levels/village1/village-obs_REF.gc index 97686c851e..427f404dfe 100644 --- a/test/decompiler/reference/levels/village1/village-obs_REF.gc +++ b/test/decompiler/reference/levels/village1/village-obs_REF.gc @@ -827,7 +827,7 @@ :enter (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (set! (-> self nav flags) (logior (nav-control-flags bit19) (-> self nav flags))) + (set! (-> self nav flags) (logior (nav-control-flags navcf19) (-> self nav flags))) (none) ) :trans @@ -918,7 +918,7 @@ :use-proximity-notice #f :use-jump-blocked #f :use-jump-patrol #f - :gnd-collide-with #x1 + :gnd-collide-with (collide-kind background) :debug-draw-neck #f :debug-draw-jump #f ) diff --git a/test/decompiler/reference/levels/village1/yakow_REF.gc b/test/decompiler/reference/levels/village1/yakow_REF.gc index 1405733244..f3ad0d6f1f 100644 --- a/test/decompiler/reference/levels/village1/yakow_REF.gc +++ b/test/decompiler/reference/levels/village1/yakow_REF.gc @@ -691,7 +691,7 @@ yakow-default-event-handler :enter (behavior ((arg0 vector)) (set! (-> self state-time) (-> *display* base-frame-counter)) - (logior! (-> self nav flags) (nav-control-flags bit10)) + (logior! (-> self nav flags) (nav-control-flags navcf10)) (set! (-> self nav destination-pos quad) (-> arg0 quad)) (set! (-> self rotate-speed) (-> *YAKOW-bank* walk-rotate-speed)) (set! (-> self turn-time) (-> *YAKOW-bank* walk-turn-time)) @@ -710,7 +710,7 @@ yakow-default-event-handler (go yakow-notice) ) (when (>= (- (-> *display* base-frame-counter) (-> self state-time)) (seconds 0.05)) - (when (or (logtest? (nav-control-flags bit19) (-> self nav flags)) + (when (or (logtest? (nav-control-flags navcf19) (-> self nav flags)) (< (vector-vector-xz-distance (-> self root-override trans) (-> self nav destination-pos)) 4096.0) ) (if (-> self in-pen) @@ -738,8 +738,8 @@ yakow-default-event-handler (-> self nav destination-pos) 131072.0 ) - (if (logtest? (nav-control-flags bit21) (-> self nav flags)) - (logclear! (-> self nav flags) (nav-control-flags bit10)) + (if (logtest? (nav-control-flags navcf21) (-> self nav flags)) + (logclear! (-> self nav flags) (nav-control-flags navcf10)) ) (yakow-post) (none) @@ -872,7 +872,7 @@ yakow-default-event-handler :enter (behavior () (set! (-> self state-time) (-> *display* base-frame-counter)) - (logior! (-> self nav flags) (nav-control-flags bit10)) + (logior! (-> self nav flags) (nav-control-flags navcf10)) (set! (-> self rotate-speed) (-> *YAKOW-bank* run-rotate-speed)) (set! (-> self turn-time) (-> *YAKOW-bank* run-turn-time)) (none) @@ -1064,7 +1064,7 @@ yakow-default-event-handler (process-drawable-from-entity! obj arg0) (set! (-> obj align) (new 'process 'align-control obj)) (set! (-> obj nav) (new 'process 'nav-control (-> obj root-override) 16 40960.0)) - (logior! (-> obj nav flags) (nav-control-flags display-marks bit3 bit5 bit6 bit7)) + (logior! (-> obj nav flags) (nav-control-flags display-marks navcf3 navcf5 navcf6 navcf7)) (set! (-> obj nav nearest-y-threshold) 409600.0) (set! (-> obj fact-override) (new 'process 'fact-info-enemy obj (pickup-type eco-pill-random) (-> *FACT-bank* default-pill-inc)) diff --git a/test/goalc/test_with_game.cpp b/test/goalc/test_with_game.cpp index 0e8bb764ce..32a43b1e24 100644 --- a/test/goalc/test_with_game.cpp +++ b/test/goalc/test_with_game.cpp @@ -30,7 +30,7 @@ class WithGameTests : public ::testing::Test { shared_compiler->compiler.run_test_no_load( "test/goalc/source_templates/with_game/test-build-game.gc"); shared_compiler->compiler.run_front_end_on_string( - "(asm-data-file game-text \"test/test_data/test_game_text.txt\")"); + "(asm-text-file text 10 :files (\"test/test_data/test_game_text.txt\"))"); } catch (std::exception& e) { fprintf(stderr, "caught exception %s\n", e.what()); EXPECT_TRUE(false); diff --git a/test/test_data/test_game_text.txt b/test/test_data/test_game_text.txt index 2d22520fa1..6d8e660ad4 100644 --- a/test/test_data/test_game_text.txt +++ b/test/test_data/test_game_text.txt @@ -1,5 +1,5 @@ -(language-count 3) (group-name "test") +(language-id 0 1 2) (#x123 "language 0" "language 1" diff --git a/test/test_reader.cpp b/test/test_reader.cpp index 124a22acfc..d49d075e91 100644 --- a/test/test_reader.cpp +++ b/test/test_reader.cpp @@ -206,9 +206,9 @@ TEST(GoosReader, Symbol) { namespace { bool first_list_matches(Object o, std::vector stuff) { - auto lst = o.as_pair()->cdr.as_pair()->car; + auto& lst = o.as_pair()->cdr.as_pair()->car; for (const auto& x : stuff) { - const auto check = x.as_pair()->cdr.as_pair()->car; + const auto& check = x.as_pair()->cdr.as_pair()->car; if (lst.as_pair()->car != check) { return false; } @@ -233,11 +233,11 @@ bool first_array_matches(Object o, std::vector stuff) { } bool first_pair_matches(Object o, Object car, Object cdr) { - auto lst = o.as_pair()->cdr.as_pair()->car; + auto& lst = o.as_pair()->cdr.as_pair()->car; return (lst.as_pair()->car == car) && (lst.as_pair()->cdr == cdr); } -bool print_matches(Object o, std::string expected) { +bool print_matches(Object o, const std::string& expected) { return o.as_pair()->cdr.as_pair()->car.print() == expected; } From b263e33e9457c90e76b59024d014e33c6e29e0de Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Mon, 11 Apr 2022 20:53:24 -0400 Subject: [PATCH 019/172] [goalc] fix mod bug and add div tests (#1296) * fix mod bug and add div tests * update changelog --- docs/progress-notes/changelog.md | 3 ++- goalc/compiler/IR.cpp | 17 ++++++++++-- goalc/compiler/IR.h | 1 + goalc/compiler/compilation/Math.cpp | 6 ++++- .../arithmetic/divide-2.static.gc | 3 ++- .../arithmetic/divide-signs.static.gc | 7 +++++ .../arithmetic/mod-unsigned.static.gc | 3 +++ test/goalc/test_arithmetic.cpp | 9 +++++++ test/offline/readme.md | 26 +++++++++++++++++++ 9 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 test/goalc/source_templates/arithmetic/divide-signs.static.gc create mode 100644 test/goalc/source_templates/arithmetic/mod-unsigned.static.gc create mode 100644 test/offline/readme.md diff --git a/docs/progress-notes/changelog.md b/docs/progress-notes/changelog.md index 46753db894..c07624719e 100644 --- a/docs/progress-notes/changelog.md +++ b/docs/progress-notes/changelog.md @@ -219,4 +219,5 @@ ## V0.9 Large change to macro expansion and constant propagation The compiler is now much more aggressive in where and how it expands macros and handles expressions at compiler time. - Several places where macros could be incorrectly executed more than once (possibly causing unwanted side effects) have been fixed. -- Fixed bug in size calculation of non-inline stack arrays. Previous behavior was a compiler assert. \ No newline at end of file +- Fixed bug in size calculation of non-inline stack arrays. Previous behavior was a compiler assert. +- Correctly handle `mod` for unsigned numbers. Previous behavior was to treat all inputs as 32-bit signed integers. \ No newline at end of file diff --git a/goalc/compiler/IR.cpp b/goalc/compiler/IR.cpp index 9c908f810c..2dfc109737 100644 --- a/goalc/compiler/IR.cpp +++ b/goalc/compiler/IR.cpp @@ -553,6 +553,8 @@ std::string IR_IntegerMath::print() { return fmt::format("udiv {}, {}", m_dest->print(), m_arg->print()); case IntegerMathKind::IMOD_32: return fmt::format("imod {}, {}", m_dest->print(), m_arg->print()); + case IntegerMathKind::UMOD_32: + return fmt::format("umod {}, {}", m_dest->print(), m_arg->print()); case IntegerMathKind::SARV_64: return fmt::format("sarv {}, {}", m_dest->print(), m_arg->print()); case IntegerMathKind::SHLV_64: @@ -589,7 +591,7 @@ RegAllocInstr IR_IntegerMath::to_rai() { } if (m_kind == IntegerMathKind::IDIV_32 || m_kind == IntegerMathKind::IMOD_32 || - m_kind == IntegerMathKind::UDIV_32) { + m_kind == IntegerMathKind::UDIV_32 || m_kind == IntegerMathKind::UMOD_32) { rai.exclude.emplace_back(emitter::RDX); } return rai; @@ -645,8 +647,10 @@ void IR_IntegerMath::do_codegen(emitter::ObjectGenerator* gen, gen->add_instr(IGen::sar_gpr64_u8(get_reg(m_dest, allocs, irec), m_shift_amount), irec); break; case IntegerMathKind::IMUL_32: { + // just a 32-bit multiply, signed/unsigned doesn't affect lower 32 bits of result. auto dr = get_reg(m_dest, allocs, irec); gen->add_instr(IGen::imul_gpr32_gpr32(dr, get_reg(m_arg, allocs, irec)), irec); + // the PS2 sign extends the result even if we used multu. We replicate this here. gen->add_instr(IGen::movsx_r64_r32(dr, dr), irec); } break; case IntegerMathKind::IMUL_64: { @@ -662,6 +666,9 @@ void IR_IntegerMath::do_codegen(emitter::ObjectGenerator* gen, // zero extend, not sign extend to avoid overflow gen->add_instr(IGen::xor_gpr64_gpr64(Register(RDX), Register(RDX)), irec); gen->add_instr(IGen::unsigned_div_gpr32(get_reg(m_arg, allocs, irec)), irec); + // note: this probably needs hardware testing to know for sure if the PS2 actually sign + // extends here or not. Nothing seems to break either way, and PCSX2/Dobie interpreters both + // sign extend, so that seems like the safest option. gen->add_instr(IGen::movsx_r64_r32(get_reg(m_dest, allocs, irec), emitter::RAX), irec); } break; case IntegerMathKind::IMOD_32: { @@ -669,7 +676,13 @@ void IR_IntegerMath::do_codegen(emitter::ObjectGenerator* gen, gen->add_instr(IGen::idiv_gpr32(get_reg(m_arg, allocs, irec)), irec); gen->add_instr(IGen::movsx_r64_r32(get_reg(m_dest, allocs, irec), emitter::RDX), irec); } break; - + case IntegerMathKind::UMOD_32: { + // zero extend, not sign extend to avoid overflow + gen->add_instr(IGen::xor_gpr64_gpr64(Register(RDX), Register(RDX)), irec); + gen->add_instr(IGen::unsigned_div_gpr32(get_reg(m_arg, allocs, irec)), irec); + // see note on udiv, same applies here. + gen->add_instr(IGen::movsx_r64_r32(get_reg(m_dest, allocs, irec), emitter::RDX), irec); + } break; default: ASSERT(false); } diff --git a/goalc/compiler/IR.h b/goalc/compiler/IR.h index c56da37ab9..6b37e6716b 100644 --- a/goalc/compiler/IR.h +++ b/goalc/compiler/IR.h @@ -201,6 +201,7 @@ enum class IntegerMathKind { SAR_64, SHR_64, IMOD_32, + UMOD_32, OR_64, AND_64, XOR_64, diff --git a/goalc/compiler/compilation/Math.cpp b/goalc/compiler/compilation/Math.cpp index d4ca7cc8a6..aa04024b6c 100644 --- a/goalc/compiler/compilation/Math.cpp +++ b/goalc/compiler/compilation/Math.cpp @@ -621,7 +621,11 @@ Val* Compiler::compile_mod(const goos::Object& form, const goos::Object& rest, E con.desired_register = emitter::RAX; fenv->constrain(con); - env->emit_ir(form, IntegerMathKind::IMOD_32, result, second); + env->emit_ir(form, + is_singed_integer_or_binteger(first->type()) + ? IntegerMathKind::IMOD_32 + : IntegerMathKind::UMOD_32, + result, second); auto result_moved = env->make_gpr(first->type()); env->emit_ir(form, result_moved, result); diff --git a/test/goalc/source_templates/arithmetic/divide-2.static.gc b/test/goalc/source_templates/arithmetic/divide-2.static.gc index bb66062495..2e26692748 100644 --- a/test/goalc/source_templates/arithmetic/divide-2.static.gc +++ b/test/goalc/source_templates/arithmetic/divide-2.static.gc @@ -1,3 +1,4 @@ (let ((x 30)) - (+ (/ x 10) 4) + ;; setting upper 32 bits should be ignored + (+ (/ (logior #x111111100000000 x) (logior #x1231234400000000 10)) 4) ) \ No newline at end of file diff --git a/test/goalc/source_templates/arithmetic/divide-signs.static.gc b/test/goalc/source_templates/arithmetic/divide-signs.static.gc new file mode 100644 index 0000000000..dc0295e1f6 --- /dev/null +++ b/test/goalc/source_templates/arithmetic/divide-signs.static.gc @@ -0,0 +1,7 @@ + +(_format #t "~X ~X ~X ~X~%" + (/ -10 2) ;; should be -5 + (/ (the uint -10) 2) ;; should use 64-bit shift logical: #x7ffffffffffffffb + (/ -10 3) ;; should be -3 + (/ (the uint -10) 3) ;; should use integer unsigned divide: #x55555552 + ) \ No newline at end of file diff --git a/test/goalc/source_templates/arithmetic/mod-unsigned.static.gc b/test/goalc/source_templates/arithmetic/mod-unsigned.static.gc new file mode 100644 index 0000000000..1e0ec1bc38 --- /dev/null +++ b/test/goalc/source_templates/arithmetic/mod-unsigned.static.gc @@ -0,0 +1,3 @@ +(_format #t "~X ~X~%" + (mod -1 10) ;; -1 + (mod (the uint #xffffffff) 10)) \ No newline at end of file diff --git a/test/goalc/test_arithmetic.cpp b/test/goalc/test_arithmetic.cpp index d40bb7e844..8b8ac040d9 100644 --- a/test/goalc/test_arithmetic.cpp +++ b/test/goalc/test_arithmetic.cpp @@ -289,3 +289,12 @@ TEST_F(ArithmeticTests, LogicalOperators) { TEST_F(ArithmeticTests, Comparison) { runner->run_static_test(env, testCategory, "signed-int-compare.static.gc", {"12\n"}); } + +TEST_F(ArithmeticTests, DivideSigns) { + runner->run_static_test(env, testCategory, "divide-signs.static.gc", + {"fffffffffffffffb 7ffffffffffffffb fffffffffffffffd 55555552\n0\n"}); +} + +TEST_F(ArithmeticTests, ModUnsigned) { + runner->run_static_test(env, testCategory, "mod-unsigned.static.gc", {"ffffffffffffffff 5\n0\n"}); +} \ No newline at end of file diff --git a/test/offline/readme.md b/test/offline/readme.md new file mode 100644 index 0000000000..52668ea0c4 --- /dev/null +++ b/test/offline/readme.md @@ -0,0 +1,26 @@ +# Offline Reference Test +The offline reference test runs the decompiler on all files that have a corresponding `_REF.gc`, then compiles them. +The test passes if all files compile and all decompiler outputs match the `_REF.gc`. + +The purpose of the offline reference test is: +- To make sure the output of the decompiler can be compiled +- To let us easily see "what source should change, if I changed this type?". This allows us to safely update types without worrying that we forgot to update some other file. + +This test doesn't run as part of CI, so it relies on us running it manually. As a result, from time to time, it can be broken on master. + +## Running the test +Just run `offline-test` in the build directory. It takes about a minute and will display diffs of any files that don't match and compiler errors on the first failing file. + +## What to do if the diff test fails +First, manually read the diff and make sure that it's a good change. + +If so, re-run the `offline-test` program with the `--dump-mode` flag. It will save copies of any differing output in a `failures` folder (make sure this is empty before running). To apply these to the `_REF.gc` files automatically, there's a python script that you can run like this: +``` +cd jak-project/build +python3 ../scripts/update_decomp_reference.py ./failures ../test/decompiler/referenc +``` + +Next, make sure the actual `.gc` files in `goal_src/` are updated, if they need to be. For large changes, this part can be pretty annoying. There is a `update-goal-src.py` script that is helpful for huge changes. + +## What to do if the compile test fails +Ideally we'd make all code compile successfully without any manual changes. But sometimes there's just one function that doesn't work in a big file, and you'd like to get the rest of it. There's a `config.jsonc` file in the `test/offline` folder that lets you identify functions by name to skip compiling in the ref tests. From c4a92571b291852fddaf5739c30698756c383a1b Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Tue, 12 Apr 2022 18:48:27 -0400 Subject: [PATCH 020/172] Improve `ASSERT` macro, fix linux file paths in `Taskfile` and hopefully fix the windows release (#1295) * ci: fix windows releases (hopefully) * scripts: fix Taskfile file references for linux * asserts: add `ASSERT_MSG` macro and ensure `stdout` is flushed before `abort`ing * asserts: refactor all `assert(false);` with a preceeding message instances * lint: format * temp... * fix compiler errors * assert: allow for string literals in `ASSERT_MSG` * lint: formatting * revert temp change for testing --- .github/workflows/linter-workflow.yaml | 4 ++- .github/workflows/windows-workflow.yaml | 2 +- Taskfile.yml | 8 ++--- common/audio/audio_formats.cpp | 3 +- common/custom_data/TFrag3Data.cpp | 11 ++++--- common/dma/dma.cpp | 4 +-- common/dma/dma.h | 4 +-- common/util/Assert.cpp | 29 ++++++++++++++++-- common/util/Assert.h | 14 ++++++++- common/util/FileUtil.cpp | 3 +- common/util/compress.cpp | 7 ++--- decompiler/Disasm/InstructionParser.cpp | 10 +++---- decompiler/Disasm/Register.cpp | 6 ++-- decompiler/Function/CfgVtx.cpp | 3 +- decompiler/IR2/Form.cpp | 8 ++--- decompiler/ObjectFile/LinkedObjectFile.cpp | 10 +++---- .../ObjectFile/LinkedObjectFileCreation.cpp | 3 +- decompiler/VuDisasm/VuDisassembler.cpp | 15 ++++------ decompiler/analysis/type_analysis.cpp | 3 +- .../config/jak1_ntsc_black_label/hacks.jsonc | 2 +- .../jak1_ntsc_black_label/label_types.jsonc | 4 +-- .../jak1_ntsc_black_label/type_casts.jsonc | 30 ++++++------------- decompiler/data/LinkedWordReader.h | 3 +- decompiler/data/game_text.cpp | 3 +- decompiler/data/tpage.cpp | 3 +- decompiler/level_extractor/BspHeader.cpp | 5 ++-- decompiler/level_extractor/extract_level.cpp | 5 ++-- decompiler/level_extractor/extract_shrub.cpp | 18 +++++------ decompiler/level_extractor/extract_tfrag.cpp | 29 ++++++++---------- decompiler/level_extractor/extract_tie.cpp | 21 ++++++------- .../opengl_renderer/DirectRenderer.cpp | 15 ++++------ .../opengl_renderer/DirectRenderer2.cpp | 8 ++--- .../opengl_renderer/GenericProgram.cpp | 5 ++-- .../opengl_renderer/GenericRenderer.cpp | 23 ++++++-------- game/graphics/opengl_renderer/MercProgram.cpp | 3 +- .../graphics/opengl_renderer/MercRenderer.cpp | 3 +- .../opengl_renderer/ShadowRenderer.cpp | 9 +++--- game/graphics/opengl_renderer/Shadow_PS2.cpp | 9 ++---- game/graphics/opengl_renderer/Sprite3.cpp | 3 +- .../opengl_renderer/SpriteRenderer.cpp | 3 +- .../foreground/Generic2_DMA.cpp | 5 ++-- .../foreground/Generic2_OpenGL.cpp | 5 ++-- .../opengl_renderer/ocean/OceanMid.cpp | 8 ++--- .../opengl_renderer/ocean/OceanNear.cpp | 5 ++-- game/kernel/klink.cpp | 10 +++---- game/kernel/kscheme.cpp | 3 +- game/mips2c/functions/generic_merc.cpp | 6 ++-- game/overlord/srpc.cpp | 7 ++--- goalc/debugger/Debugger.cpp | 4 +-- goalc/emitter/CodeTester.cpp | 4 +-- goalc/regalloc/Allocator.cpp | 5 ++-- 51 files changed, 187 insertions(+), 226 deletions(-) diff --git a/.github/workflows/linter-workflow.yaml b/.github/workflows/linter-workflow.yaml index 5f02880af4..77e7bd74f0 100644 --- a/.github/workflows/linter-workflow.yaml +++ b/.github/workflows/linter-workflow.yaml @@ -21,7 +21,9 @@ jobs: uses: actions/checkout@v2 - name: Get Package Dependencies - run: sudo apt install clang-format clang-tidy + run: | + sudo apt install clang-format clang-tidy + clang-format -version - name: Check Clang-Formatting run: | diff --git a/.github/workflows/windows-workflow.yaml b/.github/workflows/windows-workflow.yaml index 3f4d5ec071..b155db1cf0 100644 --- a/.github/workflows/windows-workflow.yaml +++ b/.github/workflows/windows-workflow.yaml @@ -85,7 +85,7 @@ jobs: run: | mkdir -p ./ci-artifacts/out ./.github/scripts/releases/extract_build_windows.sh ./ci-artifacts/out ./ - 7z a -tzip ./ci-artifacts/windows.zip ./ci-artfacts/out + 7z a -tzip ./ci-artifacts/windows.zip ./ci-artifacts/out - name: Upload Assets and Potential Publish Release if: github.repository == 'open-goal/jak-project' && startsWith(github.ref, 'refs/tags/') && matrix.compiler == 'clang' diff --git a/Taskfile.yml b/Taskfile.yml index 22e82f5a9b..2c4244c2e7 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -13,19 +13,19 @@ tasks: - '{{.DECOMP_BIN_RELEASE_DIR}}/decompiler "./decompiler/config/jak1_ntsc_black_label.jsonc" "./iso_data" "./decompiler_out" "decompile_code=false"' boot-game: preconditions: - - sh: test -f {{.DECOMP_BIN_RELEASE_DIR}}/gk{{.EXE_FILE_EXTENSION}} + - sh: test -f {{.GK_BIN_RELEASE_DIR}}/gk{{.EXE_FILE_EXTENSION}} msg: "Couldn't locate runtime executable -- Have you compiled in release mode?" cmds: - "{{.GK_BIN_RELEASE_DIR}}/gk -boot -fakeiso -debug -v" run-game: preconditions: - - sh: test -f {{.DECOMP_BIN_RELEASE_DIR}}/gk{{.EXE_FILE_EXTENSION}} + - sh: test -f {{.GK_BIN_RELEASE_DIR}}/gk{{.EXE_FILE_EXTENSION}} msg: "Couldn't locate runtime executable -- Have you compiled in release mode?" cmds: - "{{.GK_BIN_RELEASE_DIR}}/gk -fakeiso -debug -v" run-game-quiet: preconditions: - - sh: test -f {{.DECOMP_BIN_RELEASE_DIR}}/gk{{.EXE_FILE_EXTENSION}} + - sh: test -f {{.GK_BIN_RELEASE_DIR}}/gk{{.EXE_FILE_EXTENSION}} msg: "Couldn't locate runtime executable -- Have you compiled in release mode?" cmds: - "{{.GK_BIN_RELEASE_DIR}}/gk -fakeiso" @@ -33,7 +33,7 @@ tasks: env: OPENGOAL_DECOMP_DIR: "jak1/" preconditions: - - sh: test -f {{.DECOMP_BIN_RELEASE_DIR}}/goalc{{.EXE_FILE_EXTENSION}} + - sh: test -f {{.GOALC_BIN_RELEASE_DIR}}/goalc{{.EXE_FILE_EXTENSION}} msg: "Couldn't locate compiler executable -- Have you compiled in release mode?" cmds: - "{{.GOALC_BIN_RELEASE_DIR}}/goalc" diff --git a/common/audio/audio_formats.cpp b/common/audio/audio_formats.cpp index db2a104104..33abd67a28 100644 --- a/common/audio/audio_formats.cpp +++ b/common/audio/audio_formats.cpp @@ -289,8 +289,7 @@ void test_encode_adpcm(const std::vector& samples, for (int i = 0; i < 5; i++) { fmt::print(" [{}] {} {}\n", i, filter_errors[i], filter_shifts[i]); } - fmt::print("prev: {} {}\n", prev_block_samples[0], prev_block_samples[1]); - ASSERT(false); + ASSERT_MSG(false, fmt::format("prev: {} {}", prev_block_samples[0], prev_block_samples[1])); } prev_block_samples[0] = samples.at(block_idx * 28 + 27); diff --git a/common/custom_data/TFrag3Data.cpp b/common/custom_data/TFrag3Data.cpp index 8774a93e5c..cd46ba29ec 100644 --- a/common/custom_data/TFrag3Data.cpp +++ b/common/custom_data/TFrag3Data.cpp @@ -236,9 +236,8 @@ void Texture::serialize(Serializer& ser) { void Level::serialize(Serializer& ser) { ser.from_ptr(&version); if (ser.is_loading() && version != TFRAG3_VERSION) { - fmt::print("version mismatch when loading tfrag3 data. Got {}, expected {}\n", version, - TFRAG3_VERSION); - ASSERT(false); + ASSERT_MSG(false, fmt::format("version mismatch when loading tfrag3 data. Got {}, expected {}", + version, TFRAG3_VERSION)); } ser.from_str(&level_name); @@ -285,9 +284,9 @@ void Level::serialize(Serializer& ser) { ser.from_ptr(&version2); if (ser.is_loading() && version2 != TFRAG3_VERSION) { - fmt::print("version mismatch when loading tfrag3 data (at end). Got {}, expected {}\n", - version2, TFRAG3_VERSION); - ASSERT(false); + ASSERT_MSG(false, fmt::format( + "version mismatch when loading tfrag3 data (at end). Got {}, expected {}", + version2, TFRAG3_VERSION)); } } diff --git a/common/dma/dma.cpp b/common/dma/dma.cpp index 4e8ed3f62c..e05a2cdd72 100644 --- a/common/dma/dma.cpp +++ b/common/dma/dma.cpp @@ -115,10 +115,8 @@ std::string VifCode::print() { } default: - fmt::print("Unhandled vif code {}\n", (int)kind); - result = "???"; - ASSERT(false); + ASSERT_MSG(false, fmt::format("Unhandled vif code {}", (int)kind)); break; } // TODO: the rest of the VIF code. diff --git a/common/dma/dma.h b/common/dma/dma.h index 984b890e11..46a4823e13 100644 --- a/common/dma/dma.h +++ b/common/dma/dma.h @@ -9,6 +9,7 @@ #include #include "common/common_types.h" #include "common/util/Assert.h" +#include "third-party/fmt/core.h" struct DmaStats { double sync_time_ms = 0; @@ -91,8 +92,7 @@ inline void emulate_dma(const void* source_base, void* dest_base, u32 tadr, u32 // does this transfer anything in TTE??? return; default: - printf("bad tag: %d\n", (int)tag.kind); - ASSERT(false); + ASSERT_MSG(false, fmt::format("bad tag: {}", (int)tag.kind)); } } } diff --git a/common/util/Assert.cpp b/common/util/Assert.cpp index 3d923e9be1..1f8d630202 100644 --- a/common/util/Assert.cpp +++ b/common/util/Assert.cpp @@ -2,8 +2,33 @@ #include #include "Assert.h" +#include -void private_assert_failed(const char* expr, const char* file, int line, const char* function) { - fprintf(stderr, "%s:%d: Assertion failed: %s\nFunction: %s\n", file, line, expr, function); +void private_assert_failed(const char* expr, + const char* file, + int line, + const char* function, + const char* msg) { + if (!msg || msg[0] == '\0') { + fprintf(stderr, "Assertion failed: '%s'\n\tSource: %s:%d\n\tFunction: %s\n", expr, file, line, + function); + } else { + fprintf(stderr, "Assertion failed: '%s'\n\tMessage: %s\n\tSource: %s:%d\n\tFunction: %s\n", + expr, msg, file, line, function); + } + fflush(stdout); // ensure any stdout logs are flushed before we terminate + fflush(stderr); abort(); } + +void private_assert_failed(const char* expr, + const char* file, + int line, + const char* function, + const std::string_view& msg) { + if (msg.empty()) { + private_assert_failed(expr, file, line, function); + } else { + private_assert_failed(expr, file, line, function, msg.data()); + } +} diff --git a/common/util/Assert.h b/common/util/Assert.h index 40f6750dda..e7b8f9a68d 100644 --- a/common/util/Assert.h +++ b/common/util/Assert.h @@ -5,10 +5,19 @@ #pragma once +#include + [[noreturn]] void private_assert_failed(const char* expr, const char* file, int line, - const char* function); + const char* function, + const char* msg = ""); + +[[noreturn]] void private_assert_failed(const char* expr, + const char* file, + int line, + const char* function, + const std::string_view& msg); #ifdef _WIN32 #define __PRETTY_FUNCTION__ __FUNCSIG__ @@ -16,3 +25,6 @@ #define ASSERT(EX) \ (void)((EX) || (private_assert_failed(#EX, __FILE__, __LINE__, __PRETTY_FUNCTION__), 0)) + +#define ASSERT_MSG(EXPR, STR) \ + (void)((EXPR) || (private_assert_failed(#EXPR, __FILE__, __LINE__, __PRETTY_FUNCTION__, STR), 0)) diff --git a/common/util/FileUtil.cpp b/common/util/FileUtil.cpp index ece3fc595b..1de428a36b 100644 --- a/common/util/FileUtil.cpp +++ b/common/util/FileUtil.cpp @@ -425,8 +425,7 @@ void MakeISOName(char* dst, const char* src) { void assert_file_exists(const char* path, const char* error_message) { if (!std::filesystem::exists(path)) { - fprintf(stderr, "File %s was not found: %s\n", path, error_message); - ASSERT(false); + ASSERT_MSG(false, fmt::format("File {} was not found: {}", path, error_message)); } } diff --git a/common/util/compress.cpp b/common/util/compress.cpp index a31a19f47f..fb931db3c4 100644 --- a/common/util/compress.cpp +++ b/common/util/compress.cpp @@ -4,6 +4,7 @@ #include "compress.h" #include "third-party/zstd/lib/zstd.h" #include "common/util/Assert.h" +#include "third-party/fmt/core.h" namespace compression { @@ -17,8 +18,7 @@ std::vector compress_zstd(const void* data, size_t size) { auto compressed_size = ZSTD_compress(result.data() + sizeof(size_t), max_compressed, data, size, 1); if (ZSTD_isError(compressed_size)) { - printf("ZSTD error: %s\n", ZSTD_getErrorName(compressed_size)); - ASSERT(false); + ASSERT_MSG(false, fmt::format("ZSTD error: {}", ZSTD_getErrorName(compressed_size))); } result.resize(sizeof(size_t) + compressed_size); return result; @@ -38,8 +38,7 @@ std::vector decompress_zstd(const void* data, size_t size) { auto decomp_size = ZSTD_decompress(result.data(), decompressed_size, (const u8*)data + sizeof(size_t), compressed_size); if (ZSTD_isError(decomp_size)) { - printf("ZSTD error: %s\n", ZSTD_getErrorName(compressed_size)); - ASSERT(false); + ASSERT_MSG(false, fmt::format("ZSTD error: {}", ZSTD_getErrorName(compressed_size))); } ASSERT(decomp_size == decompressed_size); diff --git a/decompiler/Disasm/InstructionParser.cpp b/decompiler/Disasm/InstructionParser.cpp index 91d5556631..1c62bbd707 100644 --- a/decompiler/Disasm/InstructionParser.cpp +++ b/decompiler/Disasm/InstructionParser.cpp @@ -4,6 +4,7 @@ #include "common/common_types.h" #include "InstructionParser.h" #include "common/util/Assert.h" +#include "third-party/fmt/core.h" namespace decompiler { InstructionParser::InstructionParser() { @@ -383,8 +384,7 @@ Instruction InstructionParser::parse_single_instruction( } else if (thing == "ni") { instr.il = 0; } else { - printf("Bad interlock specification. Got %s\n", thing.c_str()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Bad interlock specification. Got {}", thing.c_str())); } } break; @@ -399,14 +399,12 @@ Instruction InstructionParser::parse_single_instruction( } else if (thing == "w") { instr.cop2_bc = 3; } else { - printf("Bad broadcast. Got %s\n", thing.c_str()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Bad broadcast. Got {}", thing.c_str())); } } break; default: - printf("missing DecodeType: %d\n", (int)step.decode); - ASSERT(false); + ASSERT_MSG(false, fmt::format("missing DecodeType: {}", (int)step.decode)); } } diff --git a/decompiler/Disasm/Register.cpp b/decompiler/Disasm/Register.cpp index ba25b290b8..674fd64105 100644 --- a/decompiler/Disasm/Register.cpp +++ b/decompiler/Disasm/Register.cpp @@ -125,14 +125,12 @@ Register::Register(Reg::RegisterKind kind, uint32_t num) { case Reg::COP0: case Reg::VI: if (num > 32) { - fmt::print("RegisterKind: {}, greater than 32: {}\n", kind, num); - ASSERT(false); + ASSERT_MSG(false, fmt::format("RegisterKind: {}, greater than 32: {}", kind, num)); } break; case Reg::SPECIAL: if (num > 4) { - fmt::print("Special RegisterKind: {}, greater than 4: {}\n", kind, num); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Special RegisterKind: {}, greater than 4: {}", kind, num)); } break; default: diff --git a/decompiler/Function/CfgVtx.cpp b/decompiler/Function/CfgVtx.cpp index 37f84f69e1..b00961a10b 100644 --- a/decompiler/Function/CfgVtx.cpp +++ b/decompiler/Function/CfgVtx.cpp @@ -1307,8 +1307,7 @@ bool ControlFlowGraph::clean_up_asm_branches() { // build new sequence replaced = true; if (!b0->succ_branch) { - fmt::print("asm missing branch in block {}\n", b0->to_string()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("asm missing branch in block {}", b0->to_string())); } m_blocks.at(b0->succ_branch->get_first_block_id())->needs_label = true; diff --git a/decompiler/IR2/Form.cpp b/decompiler/IR2/Form.cpp index f4559f169c..9412b4c905 100644 --- a/decompiler/IR2/Form.cpp +++ b/decompiler/IR2/Form.cpp @@ -626,8 +626,8 @@ goos::Object TranslatedAsmBranch::to_form_internal(const Env& env) const { if (m_branch_delay) { if (m_branch_delay->parent_element != this) { - fmt::print("bad ptr. Parent is {}\n", m_branch_delay->parent_element->to_string(env)); - ASSERT(false); + ASSERT_MSG(false, fmt::format("bad ptr. Parent is {}", + m_branch_delay->parent_element->to_string(env))); } ASSERT(m_branch_delay->parent_element->parent_form); @@ -667,8 +667,8 @@ void TranslatedAsmBranch::collect_vars(RegAccessSet& vars, bool recursive) const m_branch_condition->collect_vars(vars, recursive); if (m_branch_delay) { if (m_branch_delay->parent_element != this) { - fmt::print("bad ptr. Parent is {}\n", (void*)m_branch_delay->parent_element); - ASSERT(false); + ASSERT_MSG(false, + fmt::format("bad ptr. Parent is {}", (void*)m_branch_delay->parent_element)); } for (auto& elt : m_branch_delay->elts()) { diff --git a/decompiler/ObjectFile/LinkedObjectFile.cpp b/decompiler/ObjectFile/LinkedObjectFile.cpp index ccd043958b..dc805fdf6b 100644 --- a/decompiler/ObjectFile/LinkedObjectFile.cpp +++ b/decompiler/ObjectFile/LinkedObjectFile.cpp @@ -530,8 +530,8 @@ void LinkedObjectFile::process_fp_relative_links() { } break; default: - printf("unknown fp using op: %s\n", instr.to_string(labels).c_str()); - ASSERT(false); + ASSERT_MSG(false, + fmt::format("unknown fp using op: {}", instr.to_string(labels).c_str())); } } } @@ -912,16 +912,14 @@ goos::Object LinkedObjectFile::to_form_script_object(int seg, } else { std::string debug; append_word_to_string(debug, word); - printf("don't know how to print %s\n", debug.c_str()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("don't know how to print {}", debug.c_str())); } } break; case 2: // bad, a pair snuck through. default: // pointers should be aligned! - printf("align %d\n", byte_idx & 7); - ASSERT(false); + ASSERT_MSG(false, fmt::format("align {}", byte_idx & 7)); } return result; diff --git a/decompiler/ObjectFile/LinkedObjectFileCreation.cpp b/decompiler/ObjectFile/LinkedObjectFileCreation.cpp index 6f96eb7bb8..395b43d950 100644 --- a/decompiler/ObjectFile/LinkedObjectFileCreation.cpp +++ b/decompiler/ObjectFile/LinkedObjectFileCreation.cpp @@ -807,8 +807,7 @@ LinkedObjectFile to_linked_object_file(const std::vector& data, } else if (header->version == 5) { link_v5(result, data, name, dts); } else { - printf("Unsupported version %d\n", header->version); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Unsupported version {}", header->version)); } return result; diff --git a/decompiler/VuDisasm/VuDisassembler.cpp b/decompiler/VuDisasm/VuDisassembler.cpp index dbbbc06dd6..84f099fee6 100644 --- a/decompiler/VuDisasm/VuDisassembler.cpp +++ b/decompiler/VuDisasm/VuDisassembler.cpp @@ -297,15 +297,13 @@ VuInstrK VuDisassembler::lower_kind(u32 in) { case 0b11110'1111'11: return VuInstrK::WAITP; } - fmt::print("Unknown lower special: 0b{:b}\n", in); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Unknown lower special: 0b{:b}", in)); } else { ASSERT((op & 0b1000000) == 0); ASSERT(op < 64); auto elt = m_lower_op6_table[(int)op]; if (!elt.known) { - fmt::print("Invalid lower op6: 0b{:b} 0b{:b} 0x{:x}\n", op, in, in); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Invalid lower op6: 0b{:b} 0b{:b} 0x{:x}", op, in, in)); } return elt.kind; } @@ -370,13 +368,11 @@ VuInstrK VuDisassembler::upper_kind(u32 in) { break; default: - fmt::print("Invalid op11: 0b{:b}\n", upper_op11(in)); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Invalid op11: 0b{:b}", upper_op11(in))); } } if (!upper_info.known) { - fmt::print("Invalid upper op6: 0b{:b}\n", upper_op6(in)); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Invalid upper op6: 0b{:b}", upper_op6(in))); } return upper_info.kind; } @@ -434,8 +430,7 @@ VuInstruction VuDisassembler::decode(VuInstrK kind, u32 data, int instr_idx) { instr.kind = kind; auto& inst = info(kind); if (!inst.known) { - fmt::print("instr idx {} is unknown\n", (int)kind); - ASSERT(false); + ASSERT_MSG(false, fmt::format("instr idx {} is unknown", (int)kind)); } for (auto& step : inst.decode) { s64 value = -1; diff --git a/decompiler/analysis/type_analysis.cpp b/decompiler/analysis/type_analysis.cpp index f1b7a1be25..b3ab4e50b0 100644 --- a/decompiler/analysis/type_analysis.cpp +++ b/decompiler/analysis/type_analysis.cpp @@ -49,8 +49,7 @@ void modify_input_types_for_casts( state->get(cast.reg) = type_from_cast; } } catch (std::exception& e) { - printf("failed to parse hint: %s\n", e.what()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("failed to parse hint: {}", e.what())); } } } diff --git a/decompiler/config/jak1_ntsc_black_label/hacks.jsonc b/decompiler/config/jak1_ntsc_black_label/hacks.jsonc index 254a73b49f..17244b1ac1 100644 --- a/decompiler/config/jak1_ntsc_black_label/hacks.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/hacks.jsonc @@ -424,7 +424,7 @@ "draw-drawable-tree-ice-tfrag": [6, 8, 13, 15], "draw-drawable-tree-instance-tie": [10, 12, 18, 20, 26, 28, 37, 39], "draw-drawable-tree-instance-shrub": [5, 7, 9, 11], - + "birth-pickup-at-point": [0], "draw-bones": [0, 1, 2, 8, 81], "draw-bones-hud": [7, 8], diff --git a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc index 1fb1823595..4f0e23cb28 100644 --- a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc @@ -2128,9 +2128,7 @@ ], "generic-vu0": [["L1", "vu-function"]], - "shrubbery": [ - ["L133", "vu-function"] - ], + "shrubbery": [["L133", "vu-function"]], // please do not add things after this entry! git is dumb. "object-file-that-doesnt-actually-exist-and-i-just-put-this-here-to-prevent-merge-conflicts-with-this-file": [] diff --git a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc index ba4a567d55..1f7095f662 100644 --- a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc @@ -7587,7 +7587,7 @@ [[30, 38], "a2", "dma-packet"] ], - "draw-bones-shadow" : [ + "draw-bones-shadow": [ [10, "t0", "terrain-context"], [[36, 100], "t0", "shadow-dma-packet"], [[53, 58], "t6", "(inline-array vector)"], @@ -7595,7 +7595,7 @@ [[103, 106], "v1", "dma-packet"] ], - "shadow-execute-all" : [ + "shadow-execute-all": [ [108, "gp", "shadow-dcache"], [113, "gp", "shadow-dcache"], [118, "gp", "shadow-dcache"], @@ -7606,7 +7606,7 @@ "shadow-dma-init": [ [[25, 29], "t6", "dma-packet"], - [[34,37], "t6", "gs-gif-tag"], + [[34, 37], "t6", "gs-gif-tag"], [41, "t4", "(pointer gs-reg)"], [43, "t4", "(pointer gs-reg)"], [45, "t4", "(pointer gs-test)"], @@ -7691,9 +7691,7 @@ [273, "t0", "(pointer uint64)"], [275, "t0", "(pointer gs-reg64)"] ], - "test-func": [ - [7, "f1", "float"] - ], + "test-func": [[7, "f1", "float"]], "(method 14 drawable-tree-instance-shrub)": [ [[12, 151], "gp", "prototype-bucket-shrub"], @@ -7705,9 +7703,7 @@ [151, "gp", "(inline-array prototype-bucket-shrub)"] ], - "(method 10 drawable-tree-instance-shrub)": [ - [3, "a1", "terrain-context"] - ], + "(method 10 drawable-tree-instance-shrub)": [[3, "a1", "terrain-context"]], "draw-prototype-inline-array-shrub": [ [[13, 55], "v1", "prototype-bucket-shrub"], @@ -7741,13 +7737,9 @@ [540, "v1", "terrain-context"] ], - "(method 8 drawable-tree-instance-shrub)": [ - [54, "v1", "drawable-group"] - ], + "(method 8 drawable-tree-instance-shrub)": [[54, "v1", "drawable-group"]], - "draw-drawable-tree-instance-shrub": [ - [85, "a0", "drawable-group"] - ], + "draw-drawable-tree-instance-shrub": [[85, "a0", "drawable-group"]], "shrub-init-frame": [ [[6, 12], "a0", "dma-packet"], @@ -7767,9 +7759,7 @@ [54, "v1", "(pointer uint32)"] ], - "shrub-upload-view-data": [ - [[3, 16], "a0", "dma-packet"] - ], + "shrub-upload-view-data": [[[3, 16], "a0", "dma-packet"]], "shrub-upload-model": [ [[17, 26], "a3", "dma-packet"], @@ -7777,8 +7767,6 @@ [[47, 55], "a0", "dma-packet"] ], - "(method 12 effect-control)": [ - ["_stack_", 112, "res-tag"] - ], + "(method 12 effect-control)": [["_stack_", 112, "res-tag"]], "placeholder-do-not-add-below": [] } diff --git a/decompiler/data/LinkedWordReader.h b/decompiler/data/LinkedWordReader.h index 83c533664a..7371b53069 100644 --- a/decompiler/data/LinkedWordReader.h +++ b/decompiler/data/LinkedWordReader.h @@ -17,8 +17,7 @@ class LinkedWordReader { m_offset++; return result; } else { - ASSERT(false); - throw std::runtime_error("LinkedWordReader::get_type_tag failed"); + ASSERT_MSG(false, "LinkedWordReader::get_type_tag failed"); } } diff --git a/decompiler/data/game_text.cpp b/decompiler/data/game_text.cpp index 7fbe7e83a4..759da032fa 100644 --- a/decompiler/data/game_text.cpp +++ b/decompiler/data/game_text.cpp @@ -125,8 +125,7 @@ GameTextResult process_game_text(ObjectFileData& data, GameTextVersion version) if (read_words[i] < 1) { std::string debug; data.linked_data.append_word_to_string(debug, words.at(i)); - printf("[%d] %d 0x%s\n", i, int(read_words[i]), debug.c_str()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("[{}] {} 0x{}", i, int(read_words[i]), debug.c_str())); } } diff --git a/decompiler/data/tpage.cpp b/decompiler/data/tpage.cpp index 78b6b2ff93..0774e43710 100644 --- a/decompiler/data/tpage.cpp +++ b/decompiler/data/tpage.cpp @@ -276,8 +276,7 @@ Texture read_texture(ObjectFileData& data, const std::vector& words, auto kv = psms.find(tex.psm); if (kv == psms.end()) { - printf("Got unsupported texture 0x%x!\n", tex.psm); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Got unsupported texture 0x{:x}!", tex.psm)); } return tex; diff --git a/decompiler/level_extractor/BspHeader.cpp b/decompiler/level_extractor/BspHeader.cpp index 9b9c75b4a0..e27016785e 100644 --- a/decompiler/level_extractor/BspHeader.cpp +++ b/decompiler/level_extractor/BspHeader.cpp @@ -298,8 +298,7 @@ void tfrag_debug_print_unpack(Ref start, int qwc_total) { case VifCode::Kind::NOP: break; default: - fmt::print("unknown: {}\n", next.print()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("unknown: {}", next.print())); } } fmt::print("-------------------------------------------\n"); @@ -1677,4 +1676,4 @@ std::string BspHeader::print(const PrintSettings& settings) const { result += drawable_tree_array.print(settings, next_indent); return result; } -} // namespace level_tools \ No newline at end of file +} // namespace level_tools diff --git a/decompiler/level_extractor/extract_level.cpp b/decompiler/level_extractor/extract_level.cpp index 39c6fb7e2e..2ea8d28d33 100644 --- a/decompiler/level_extractor/extract_level.cpp +++ b/decompiler/level_extractor/extract_level.cpp @@ -120,9 +120,8 @@ void confirm_textures_identical(TextureDB& tex_db) { } else { bool ok = it->second == tex.second.rgba_bytes; if (!ok) { - fmt::print("BAD duplicate: {} {} vs {}\n", name, tex.second.rgba_bytes.size(), - it->second.size()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("BAD duplicate: {} {} vs {}", name, + tex.second.rgba_bytes.size(), it->second.size())); } } } diff --git a/decompiler/level_extractor/extract_shrub.cpp b/decompiler/level_extractor/extract_shrub.cpp index 4224656055..dd56d633a8 100644 --- a/decompiler/level_extractor/extract_shrub.cpp +++ b/decompiler/level_extractor/extract_shrub.cpp @@ -129,8 +129,7 @@ u32 remap_texture(u32 original, const std::vector& ma auto masked = original & 0xffffff00; for (auto& t : map) { if (t.original_texid == masked) { - fmt::print("OKAY! remapped!\n"); - ASSERT(false); + ASSERT_MSG(false, "OKAY! remapped!"); return t.new_texid | 20; } } @@ -502,14 +501,13 @@ void make_draws(tfrag3::Level& lev, // we're missing a texture, just use the first one. tex_it = tdb.textures.begin(); } else { - fmt::print( - "texture {} wasn't found. make sure it is loaded somehow. You may need to " - "include " - "ART.DGO or GAME.DGO in addition to the level DGOs for shared textures.\n", - combo_tex); - fmt::print("tpage is {}\n", combo_tex >> 16); - fmt::print("id is {} (0x{:x})\n", combo_tex & 0xffff, combo_tex & 0xffff); - ASSERT(false); + ASSERT_MSG( + false, + fmt::format( + "texture {} wasn't found. make sure it is loaded somehow. You may need to " + "include ART.DGO or GAME.DGO in addition to the level DGOs for shared " + "textures. tpage is {} id is {} (0x{:x})", + combo_tex, combo_tex >> 16, combo_tex & 0xffff, combo_tex & 0xffff)); } } // add a new texture to the level data diff --git a/decompiler/level_extractor/extract_tfrag.cpp b/decompiler/level_extractor/extract_tfrag.cpp index 65fb5767c6..2af87aa9dc 100644 --- a/decompiler/level_extractor/extract_tfrag.cpp +++ b/decompiler/level_extractor/extract_tfrag.cpp @@ -1760,10 +1760,9 @@ void update_mode_from_alpha1(u64 val, DrawMode& mode) { mode.set_alpha_blend(DrawMode::AlphaBlend::SRC_0_FIX_DST); // src plus dest } else { - fmt::print("unsupported blend: a {} b {} c {} d {}\n", (int)reg.a_mode(), (int)reg.b_mode(), - (int)reg.c_mode(), (int)reg.d_mode()); mode.set_alpha_blend(DrawMode::AlphaBlend::SRC_DST_SRC_DST); - ASSERT(false); + ASSERT_MSG(false, fmt::format("unsupported blend: a {} b {} c {} d {}", (int)reg.a_mode(), + (int)reg.b_mode(), (int)reg.c_mode(), (int)reg.d_mode())); } } @@ -1786,9 +1785,8 @@ void update_mode_from_test1(u64 val, DrawMode& mode) { mode.set_alpha_test(DrawMode::AlphaTest::NEVER); break; default: - fmt::print("Alpha test: {} not supported\n", (int)test.alpha_test()); mode.set_alpha_test(DrawMode::AlphaTest::ALWAYS); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Alpha test: {} not supported", (int)test.alpha_test())); } // AREF @@ -1909,8 +1907,7 @@ void process_draw_mode(std::vector& all_draws, break; case GsRegisterAddress::CLAMP_1: if (!(val == 0b101 || val == 0 || val == 1 || val == 0b100)) { - fmt::print("clamp: 0x{:x}\n", val); - ASSERT(false); + ASSERT_MSG(false, fmt::format("clamp: 0x{:x}", val)); } // this isn't quite right, but I'm hoping it's enough! @@ -2014,13 +2011,14 @@ void make_tfrag3_data(std::map>& draws, // we're missing a texture, just use the first one. tex_it = tdb.textures.begin(); } else { - fmt::print( - "texture {} wasn't found. make sure it is loaded somehow. You may need to include " - "ART.DGO or GAME.DGO in addition to the level DGOs for shared textures.\n", - combo_tex_id); - fmt::print("tpage is {}\n", combo_tex_id >> 16); - fmt::print("id is {} (0x{:x})\n", combo_tex_id & 0xffff, combo_tex_id & 0xffff); - ASSERT(false); + ASSERT_MSG( + false, + fmt::format("texture {} wasn't found. make sure it is loaded somehow. You may need " + "to include " + "ART.DGO or GAME.DGO in addition to the level DGOs for shared textures." + "tpage is {}. id is {} (0x{:x})", + combo_tex_id, combo_tex_id >> 16, combo_tex_id & 0xffff, + combo_tex_id & 0xffff)); } } tfrag3_tex_id = texture_pool.size(); @@ -2239,8 +2237,7 @@ void extract_tfrag(const level_tools::DrawableTreeTfrag* tree, } else if (tree->my_type() == "drawable-tree-trans-tfrag") { this_tree.kind = tfrag3::TFragmentTreeKind::TRANS; } else { - fmt::print("unknown tfrag tree kind: {}\n", tree->my_type()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("unknown tfrag tree kind: {}", tree->my_type())); } ASSERT(tree->length == (int)tree->arrays.size()); diff --git a/decompiler/level_extractor/extract_tie.cpp b/decompiler/level_extractor/extract_tie.cpp index 4d444fe785..8dbf0597a5 100644 --- a/decompiler/level_extractor/extract_tie.cpp +++ b/decompiler/level_extractor/extract_tie.cpp @@ -464,8 +464,7 @@ u32 remap_texture(u32 original, const std::vector& ma auto masked = original & 0xffffff00; for (auto& t : map) { if (t.original_texid == masked) { - fmt::print("OKAY! remapped!\n"); - ASSERT(false); + ASSERT_MSG(false, "OKAY! remapped!"); return t.new_texid | 20; } } @@ -2012,8 +2011,7 @@ DrawMode process_draw_mode(const AdgifInfo& info, bool use_atest, bool use_decal // the clamp matters if (!(info.clamp_val == 0b101 || info.clamp_val == 0 || info.clamp_val == 1 || info.clamp_val == 0b100)) { - fmt::print("clamp: 0x{:x}\n", info.clamp_val); - ASSERT(false); + ASSERT_MSG(false, fmt::format("clamp: 0x{:x}", info.clamp_val)); } mode.set_clamp_s_enable(info.clamp_val & 0b1); @@ -2104,14 +2102,13 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree, // we're missing a texture, just use the first one. tex_it = tdb.textures.begin(); } else { - fmt::print( - "texture {} wasn't found. make sure it is loaded somehow. You may need to " - "include " - "ART.DGO or GAME.DGO in addition to the level DGOs for shared textures.\n", - combo_tex); - fmt::print("tpage is {}\n", combo_tex >> 16); - fmt::print("id is {} (0x{:x})\n", combo_tex & 0xffff, combo_tex & 0xffff); - ASSERT(false); + ASSERT_MSG( + false, + fmt::format( + "texture {} wasn't found. make sure it is loaded somehow. You may need to " + "include ART.DGO or GAME.DGO in addition to the level DGOs for shared " + "textures. tpage is {}. id is {} (0x{:x})", + combo_tex, combo_tex >> 16, combo_tex & 0xffff, combo_tex & 0xffff)); } } // add a new texture to the level data diff --git a/game/graphics/opengl_renderer/DirectRenderer.cpp b/game/graphics/opengl_renderer/DirectRenderer.cpp index 410731f7ef..04cc45885f 100644 --- a/game/graphics/opengl_renderer/DirectRenderer.cpp +++ b/game/graphics/opengl_renderer/DirectRenderer.cpp @@ -253,8 +253,7 @@ void DirectRenderer::update_gl_prim(SharedRenderState* render_state) { case GsTest::AlphaTest::NEVER: break; default: - fmt::print("unknown alpha test: {}\n", (int)m_test_state.alpha_test); - ASSERT(false); + ASSERT_MSG(false, fmt::format("unknown alpha test: {}", (int)m_test_state.alpha_test)); } } @@ -618,9 +617,8 @@ void DirectRenderer::render_gif(const u8* data, if (size != UINT32_MAX) { if ((offset + 15) / 16 != size / 16) { - fmt::print("DirectRenderer size failed in {}\n", name_and_id()); - fmt::print("expected: {}, got: {}\n", size, offset); - ASSERT(false); + ASSERT_MSG(false, fmt::format("DirectRenderer size failed in {}. expected: {}, got: {}", + name_and_id(), size, offset)); } } @@ -693,8 +691,7 @@ void DirectRenderer::handle_ad(const u8* data, } break; default: - fmt::print("Address {} is not supported\n", register_address_name(addr)); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Address {} is not supported", register_address_name(addr))); } } @@ -1053,8 +1050,8 @@ void DirectRenderer::handle_xyzf2_common(u32 x, } } break; default: - fmt::print("prim type {} is unsupported in {}.\n", (int)m_prim_building.kind, name_and_id()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("prim type {} is unsupported in {}.", (int)m_prim_building.kind, + name_and_id())); } } diff --git a/game/graphics/opengl_renderer/DirectRenderer2.cpp b/game/graphics/opengl_renderer/DirectRenderer2.cpp index b495c29df2..c535eb1778 100644 --- a/game/graphics/opengl_renderer/DirectRenderer2.cpp +++ b/game/graphics/opengl_renderer/DirectRenderer2.cpp @@ -235,8 +235,7 @@ void DirectRenderer2::setup_opengl_for_draw_mode(const Draw& draw, case DrawMode::AlphaTest::NEVER: break; default: - fmt::print("unknown alpha test: {}\n", (int)draw.mode.get_alpha_test()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("unknown alpha test: {}", (int)draw.mode.get_alpha_test())); } } @@ -540,8 +539,7 @@ void DirectRenderer2::handle_ad(const u8* data) { case GsRegisterAddress::TEXFLUSH: break; default: - fmt::print("Address {} is not supported\n", register_address_name(addr)); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Address {} is not supported", register_address_name(addr))); } } @@ -827,4 +825,4 @@ void DirectRenderer2::handle_alpha1(u64 val) { // ASSERT(false); } } -} \ No newline at end of file +} diff --git a/game/graphics/opengl_renderer/GenericProgram.cpp b/game/graphics/opengl_renderer/GenericProgram.cpp index 3ac9886654..f9e460a9a9 100644 --- a/game/graphics/opengl_renderer/GenericProgram.cpp +++ b/game/graphics/opengl_renderer/GenericProgram.cpp @@ -358,8 +358,7 @@ void GenericRenderer::mscal_dispatch(int imm, SharedRenderState* render_state, S mscal_noclip_nopipe(render_state, prof); return; default: - fmt::print("Generic dispatch mscal: {}\n", imm); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Generic dispatch mscal: {}", imm)); } L33: // R @@ -1094,4 +1093,4 @@ void GenericRenderer::mscal_dispatch(int imm, SharedRenderState* render_state, S // nop | nop 1093 return; -} \ No newline at end of file +} diff --git a/game/graphics/opengl_renderer/GenericRenderer.cpp b/game/graphics/opengl_renderer/GenericRenderer.cpp index 1f66576c09..308cdcae67 100644 --- a/game/graphics/opengl_renderer/GenericRenderer.cpp +++ b/game/graphics/opengl_renderer/GenericRenderer.cpp @@ -51,8 +51,7 @@ void GenericRenderer::render(DmaFollower& dma, case VifCode::Kind::NOP: break; default: - fmt::print("unknown vifcode0 empty tag: {}\n", v0.print()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("unknown vifcode0 empty tag: {}", v0.print())); } switch (v1.kind) { case VifCode::Kind::STCYCL: @@ -64,8 +63,7 @@ void GenericRenderer::render(DmaFollower& dma, mscal(v1.immediate, render_state, prof); break; default: - fmt::print("unknown vifcode1 empty tag: {}\n", v1.print()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("unknown vifcode1 empty tag: {}", v1.print())); } } else if (v0.kind == VifCode::Kind::FLUSHA && v1.kind == VifCode::Kind::DIRECT) { if (render_state->use_direct2) { @@ -129,11 +127,9 @@ void GenericRenderer::render(DmaFollower& dma, ASSERT(false); } } else { - fmt::print("Generic encountered unknown DMA.\n"); - fmt::print("Size bytes: {}\n", data.size_bytes); - fmt::print("VIF0: {}\n", data.vifcode0().print()); - fmt::print("VIF1: {}\n", data.vifcode1().print()); - ASSERT(false); + ASSERT_MSG(false, + fmt::format("Generic encountered unknown DMA. Size bytes: {}. VIF0: {}. VIF1: {}", + data.size_bytes, data.vifcode0().print(), data.vifcode1().print())); } m_skipped_tags++; } @@ -182,10 +178,9 @@ void GenericRenderer::handle_dma_stream(const u8* data, mscal(vc.immediate, render_state, prof); break; default: - fmt::print("Generic encountered unknown DMA in handle_dma_stream.\n"); - fmt::print("Bytes remaining: {}\n", bytes); - fmt::print("VIF: {}\n", vc.print()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Generic encountered unknown DMA in handle_dma_stream. Bytes " + "remaining: {}. VIF: {}", + bytes, vc.print())); } } } @@ -320,4 +315,4 @@ void GenericRenderer::xgkick(u16 addr, SharedRenderState* render_state, ScopedPr } } m_xgkick_idx++; -} \ No newline at end of file +} diff --git a/game/graphics/opengl_renderer/MercProgram.cpp b/game/graphics/opengl_renderer/MercProgram.cpp index a95bec9270..4a149472db 100644 --- a/game/graphics/opengl_renderer/MercProgram.cpp +++ b/game/graphics/opengl_renderer/MercProgram.cpp @@ -3141,8 +3141,7 @@ ASSERT(false); case 0x539: goto JUMP_539; default: - fmt::print("bad jump to {:x}\n", vu.vi08); - ASSERT(false); + ASSERT_MSG(false, fmt::format("bad jump to {:x}", vu.vi08)); } L94: // 3072.0 | mulax.xyzw ACC, vf01, vf11 :i diff --git a/game/graphics/opengl_renderer/MercRenderer.cpp b/game/graphics/opengl_renderer/MercRenderer.cpp index ce52d2895c..1411958d00 100644 --- a/game/graphics/opengl_renderer/MercRenderer.cpp +++ b/game/graphics/opengl_renderer/MercRenderer.cpp @@ -247,8 +247,7 @@ void MercRenderer::handle_merc_chain(DmaFollower& dma, } break; default: - fmt::print("unknown mscal: {}\n", mscal_addr); - ASSERT(false); + ASSERT_MSG(false, fmt::format("unknown mscal: {}", mscal_addr)); } // while (true) { diff --git a/game/graphics/opengl_renderer/ShadowRenderer.cpp b/game/graphics/opengl_renderer/ShadowRenderer.cpp index 6245f35f69..163dedef90 100644 --- a/game/graphics/opengl_renderer/ShadowRenderer.cpp +++ b/game/graphics/opengl_renderer/ShadowRenderer.cpp @@ -96,8 +96,8 @@ void ShadowRenderer::xgkick(u16 imm) { // fmt::print("rgba: {} {} {} {}: {}\n", rgba[0], rgba[1], rgba[2], rgba[3], Q); } break; default: - fmt::print("Address {} is not supported\n", register_address_name(addr)); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Address {} is not supported", + register_address_name(addr))); } } break; case GifTag::RegisterDescriptor::ST: { @@ -308,8 +308,7 @@ void ShadowRenderer::render(DmaFollower& dma, dma.read_and_advance(); } else { - fmt::print("{} {}\n", next.vifcode0().print(), next.vifcode1().print()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("{} {}", next.vifcode0().print(), next.vifcode1().print())); } } @@ -423,4 +422,4 @@ void ShadowRenderer::draw(SharedRenderState* render_state, ScopedProfilerNode& p glDepthMask(GL_TRUE); glDisable(GL_STENCIL_TEST); -} \ No newline at end of file +} diff --git a/game/graphics/opengl_renderer/Shadow_PS2.cpp b/game/graphics/opengl_renderer/Shadow_PS2.cpp index fed663f0b6..285cbb8f97 100644 --- a/game/graphics/opengl_renderer/Shadow_PS2.cpp +++ b/game/graphics/opengl_renderer/Shadow_PS2.cpp @@ -131,8 +131,7 @@ void ShadowRenderer::handle_jalr_to_end_block(u16 val, u32& first_flag, u32& sec // nop | nop 739 return; default: - fmt::print("unhandled end block: {}\n", val); - ASSERT(false); + ASSERT_MSG(false, fmt::format("unhandled end block: {}", val)); } } @@ -1715,8 +1714,7 @@ void ShadowRenderer::run_mscal_vu2c(u16 imm) { case 699: goto INSTR_699; default: - fmt::print("unknown vu.vi15 @ L46: {}\n", vu.vi15); - ASSERT(false); + ASSERT_MSG(false, fmt::format("unknown vu.vi15 @ L46: {}", vu.vi15)); } // clang-format off // nop | nop 663 @@ -1890,7 +1888,6 @@ void ShadowRenderer::run_mscal_vu2c(u16 imm) { case 527: goto INSTR_527; default: - fmt::print("unknown vu.vi15 @ 722: {}\n", vu.vi15); - ASSERT(false); + ASSERT_MSG(false, fmt::format("unknown vu.vi15 @ 722: {}", vu.vi15)); } } diff --git a/game/graphics/opengl_renderer/Sprite3.cpp b/game/graphics/opengl_renderer/Sprite3.cpp index 2b91d9c515..0dd2fc4666 100644 --- a/game/graphics/opengl_renderer/Sprite3.cpp +++ b/game/graphics/opengl_renderer/Sprite3.cpp @@ -577,8 +577,7 @@ void Sprite3::handle_clamp(u64 val, SharedRenderState* /*render_state*/, ScopedProfilerNode& /*prof*/) { if (!(val == 0b101 || val == 0 || val == 1 || val == 0b100)) { - fmt::print("clamp: 0x{:x}\n", val); - ASSERT(false); + ASSERT_MSG(false, fmt::format("clamp: 0x{:x}", val)); } m_current_mode.set_clamp_s_enable(val & 0b001); diff --git a/game/graphics/opengl_renderer/SpriteRenderer.cpp b/game/graphics/opengl_renderer/SpriteRenderer.cpp index ab51fd48b6..4e26d69511 100644 --- a/game/graphics/opengl_renderer/SpriteRenderer.cpp +++ b/game/graphics/opengl_renderer/SpriteRenderer.cpp @@ -526,8 +526,7 @@ void SpriteRenderer::handle_clamp(u64 val, SharedRenderState* /*render_state*/, ScopedProfilerNode& /*prof*/) { if (!(val == 0b101 || val == 0 || val == 1 || val == 0b100)) { - fmt::print("clamp: 0x{:x}\n", val); - ASSERT(false); + ASSERT_MSG(false, fmt::format("clamp: 0x{:x}", val)); } m_adgif_state.reg_clamp = val; diff --git a/game/graphics/opengl_renderer/foreground/Generic2_DMA.cpp b/game/graphics/opengl_renderer/foreground/Generic2_DMA.cpp index 2278d493f6..3f61a57c87 100644 --- a/game/graphics/opengl_renderer/foreground/Generic2_DMA.cpp +++ b/game/graphics/opengl_renderer/foreground/Generic2_DMA.cpp @@ -180,8 +180,7 @@ u32 Generic2::handle_fragments_after_unpack_v4_32(const u8* data, // continue in this transfer off += first_unpack_bytes; if (off == end_of_vif) { - fmt::print("nothing after header upload\n"); - ASSERT(false); + ASSERT_MSG(false, "nothing after header upload"); } // the next thing is the vertex positions. @@ -379,4 +378,4 @@ void Generic2::process_dma(DmaFollower& dma, u32 next_bucket) { } } } -} \ No newline at end of file +} diff --git a/game/graphics/opengl_renderer/foreground/Generic2_OpenGL.cpp b/game/graphics/opengl_renderer/foreground/Generic2_OpenGL.cpp index b65b2c7e28..4ca157dc04 100644 --- a/game/graphics/opengl_renderer/foreground/Generic2_OpenGL.cpp +++ b/game/graphics/opengl_renderer/foreground/Generic2_OpenGL.cpp @@ -106,8 +106,7 @@ void Generic2::setup_opengl_for_draw_mode(const DrawMode& draw_mode, case DrawMode::AlphaTest::NEVER: break; default: - fmt::print("unknown alpha test: {}\n", (int)draw_mode.get_alpha_test()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("unknown alpha test: {}", (int)draw_mode.get_alpha_test())); } } @@ -315,4 +314,4 @@ void Generic2::do_draws(SharedRenderState* render_state, ScopedProfilerNode& pro do_hud_draws(render_state, prof); } -} \ No newline at end of file +} diff --git a/game/graphics/opengl_renderer/ocean/OceanMid.cpp b/game/graphics/opengl_renderer/ocean/OceanMid.cpp index 9be7a481f5..0e192fa22d 100644 --- a/game/graphics/opengl_renderer/ocean/OceanMid.cpp +++ b/game/graphics/opengl_renderer/ocean/OceanMid.cpp @@ -122,12 +122,10 @@ void OceanMid::run(DmaFollower& dma, SharedRenderState* render_state, ScopedProf run_call43_vu2c(); break; default: - fmt::print("unknown call2: {}\n", v0.immediate); - ASSERT(false); + ASSERT_MSG(false, fmt::format("unknown call2: {}", v0.immediate)); } } else { - fmt::print("{} {}\n", data.vifcode0().print(), data.vifcode1().print()); - ASSERT(false); + ASSERT_MSG(false, fmt::format("{} {}", data.vifcode0().print(), data.vifcode1().print())); } } m_common_ocean_renderer.flush_mid(render_state, prof); @@ -139,4 +137,4 @@ void OceanMid::run_call0() { void OceanMid::xgkick(u16 addr) { m_common_ocean_renderer.kick_from_mid((const u8*)&m_vu_data[addr]); -} \ No newline at end of file +} diff --git a/game/graphics/opengl_renderer/ocean/OceanNear.cpp b/game/graphics/opengl_renderer/ocean/OceanNear.cpp index 554f5901ca..d6a0e76a09 100644 --- a/game/graphics/opengl_renderer/ocean/OceanNear.cpp +++ b/game/graphics/opengl_renderer/ocean/OceanNear.cpp @@ -102,8 +102,7 @@ void OceanNear::render(DmaFollower& dma, run_call39_vu2c(); break; default: - fmt::print("unknown ocean near call: {}\n", v0.immediate); - ASSERT(false); + ASSERT_MSG(false, fmt::format("unknown ocean near call: {}", v0.immediate)); } } } @@ -117,4 +116,4 @@ void OceanNear::render(DmaFollower& dma, void OceanNear::xgkick(u16 addr) { m_common_ocean_renderer.kick_from_near((const u8*)&m_vu_data[addr]); -} \ No newline at end of file +} diff --git a/game/kernel/klink.cpp b/game/kernel/klink.cpp index 6094a2d59c..38d0b1bcad 100644 --- a/game/kernel/klink.cpp +++ b/game/kernel/klink.cpp @@ -18,6 +18,7 @@ #include "common/goal_constants.h" #include "game/mips2c/mips2c_table.h" #include "common/util/Assert.h" +#include "third-party/fmt/core.h" namespace { // turn on printf's for debugging linking issues. @@ -143,8 +144,7 @@ void link_control::begin(Ptr object_file, } } } else { - printf("UNHANDLED OBJECT FILE VERSION\n"); - ASSERT(false); + ASSERT_MSG(false, "UNHANDLED OBJECT FILE VERSION"); } if ((m_flags & LINK_FLAG_FORCE_DEBUG) && MasterDebug && !DiskBoot) { @@ -254,8 +254,7 @@ uint32_t link_control::work() { ASSERT(!m_opengoal); rv = work_v2(); } else { - printf("UNHANDLED OBJECT FILE VERSION %d IN WORK!\n", m_version); - ASSERT(false); + ASSERT_MSG(false, fmt::format("UNHANDLED OBJECT FILE VERSION {} IN WORK!", m_version)); return 0; } @@ -502,8 +501,7 @@ uint32_t link_control::work_v3() { lp = lp + ptr_link_v3(lp, ofh, m_segment_process); break; default: - printf("unknown link table thing %d\n", *lp); - ASSERT(false); + ASSERT_MSG(false, fmt::format("unknown link table thing {}", *lp)); break; } } diff --git a/game/kernel/kscheme.cpp b/game/kernel/kscheme.cpp index 5280e60ffd..c643220427 100644 --- a/game/kernel/kscheme.cpp +++ b/game/kernel/kscheme.cpp @@ -1213,8 +1213,7 @@ u64 call_method_of_type_arg2(u32 arg, Ptr type, u32 method_id, u32 a1, u32 (*type_tag).offset); } } - printf("[ERROR] call_method_of_type_arg2 failed!\n"); - ASSERT(false); + ASSERT_MSG(false, "[ERROR] call_method_of_type_arg2 failed!"); return arg; } diff --git a/game/mips2c/functions/generic_merc.cpp b/game/mips2c/functions/generic_merc.cpp index 4174d4cce8..5131f0c501 100644 --- a/game/mips2c/functions/generic_merc.cpp +++ b/game/mips2c/functions/generic_merc.cpp @@ -1921,8 +1921,7 @@ void vcallms_311(ExecutionContext* c, u16* vis) { vcallms_311_case_427(c, vis); break; default: - fmt::print("BAD JUMP {}\n", vis[vi01]); - ASSERT(false); + ASSERT_MSG(false, fmt::format("BAD JUMP {}", vis[vi01])); } } @@ -1955,8 +1954,7 @@ void vcallms_311_reference(ExecutionContext* c, u16* vis) { case 427: goto JUMP_427; default: - fmt::print("BAD JUMP {}\n", vis[vi01]); - ASSERT(false); + ASSERT_MSG(false, fmt::format("BAD JUMP {}", vis[vi01])); } JUMP_314: diff --git a/game/overlord/srpc.cpp b/game/overlord/srpc.cpp index 2e594d28fb..b028b162ef 100644 --- a/game/overlord/srpc.cpp +++ b/game/overlord/srpc.cpp @@ -10,6 +10,7 @@ #include "sbank.h" #include "iso_api.h" #include "common/util/Assert.h" +#include "third-party/fmt/core.h" using namespace iop; @@ -322,8 +323,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) { // TODO ShutdownFilingSystem(); } break; default: { - printf("Unhandled RPC Player command %d\n", (int)cmd->command); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Unhandled RPC Player command {}", (int)cmd->command)); } break; } n_messages--; @@ -410,8 +410,7 @@ void* RPC_Loader(unsigned int /*fno*/, void* data, int size) { // SignalSema(gSema); } break; default: - printf("Unhandled RPC Loader command %d\n", (int)cmd->command); - ASSERT(false); + ASSERT_MSG(false, fmt::format("Unhandled RPC Loader command {}", (int)cmd->command)); } n_messages--; cmd++; diff --git a/goalc/debugger/Debugger.cpp b/goalc/debugger/Debugger.cpp index 897d93de81..4d462f0766 100644 --- a/goalc/debugger/Debugger.cpp +++ b/goalc/debugger/Debugger.cpp @@ -763,8 +763,8 @@ void Debugger::watcher() { break; #endif default: - printf("[Debugger] unhandled signal in watcher: %d\n", int(signal_info.kind)); - ASSERT(false); + ASSERT_MSG(false, fmt::format("[Debugger] unhandled signal in watcher: {}", + int(signal_info.kind))); } { diff --git a/goalc/emitter/CodeTester.cpp b/goalc/emitter/CodeTester.cpp index 225a289ca0..542df8945a 100644 --- a/goalc/emitter/CodeTester.cpp +++ b/goalc/emitter/CodeTester.cpp @@ -15,6 +15,7 @@ #include #include "CodeTester.h" #include "IGen.h" +#include "third-party/fmt/core.h" namespace emitter { @@ -133,8 +134,7 @@ void CodeTester::init_code_buffer(int capacity) { code_buffer = (u8*)mmap(nullptr, capacity, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); if (code_buffer == (u8*)(-1)) { - printf("[CodeTester] Failed to map memory!\n"); - ASSERT(false); + ASSERT_MSG(false, "[CodeTester] Failed to map memory!"); } code_buffer_capacity = capacity; diff --git a/goalc/regalloc/Allocator.cpp b/goalc/regalloc/Allocator.cpp index 986247d1a2..5c85be8bba 100644 --- a/goalc/regalloc/Allocator.cpp +++ b/goalc/regalloc/Allocator.cpp @@ -569,8 +569,7 @@ bool try_spill_coloring(int var, RegAllocCache* cache, const AllocationInput& in } if (spill_assignment.reg == -1) { - printf("SPILLING FAILED BECAUSE WE COULDN'T FIND A TEMP REGISTER!\n"); - ASSERT(false); + ASSERT_MSG(false, "SPILLING FAILED BECAUSE WE COULDN'T FIND A TEMP REGISTER!"); return false; } @@ -844,4 +843,4 @@ AllocationResult allocate_registers(const AllocationInput& input) { result.num_spills = cache.stats.num_spill_ops; return result; -} \ No newline at end of file +} From cb2905212861e7f15c2259fcb8fb8c846a93d1bf Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Tue, 12 Apr 2022 19:55:29 -0400 Subject: [PATCH 021/172] fix bug with relative path in extractor (#1299) --- decompiler/extractor/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decompiler/extractor/main.cpp b/decompiler/extractor/main.cpp index 110f9a78d9..a06ede7e32 100644 --- a/decompiler/extractor/main.cpp +++ b/decompiler/extractor/main.cpp @@ -118,7 +118,7 @@ int main(int argc, char** argv) { // Compile! Compiler compiler; - compiler.make_system().set_constant("*iso-data*", jak1_input_files.string()); + compiler.make_system().set_constant("*iso-data*", absolute(jak1_input_files).string()); compiler.make_system().set_constant("*use-iso-data-path*", true); compiler.make_system().load_project_file( From 60a490d5c3576ccc79c2a3bb820acf718818f243 Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Tue, 12 Apr 2022 20:15:30 -0400 Subject: [PATCH 022/172] support unpacking iso files in the extractor (#1300) --- common/CMakeLists.txt | 1 + common/util/read_iso_file.cpp | 114 ++++++++++++++++++++++++++++++++++ common/util/read_iso_file.h | 30 +++++++++ decompiler/extractor/main.cpp | 12 +++- 4 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 common/util/read_iso_file.cpp create mode 100644 common/util/read_iso_file.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index eb9bb73ceb..05f6127624 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -34,6 +34,7 @@ add_library(common util/diff.cpp util/FileUtil.cpp util/json_util.cpp + util/read_iso_file.cpp util/Timer.cpp util/os.cpp util/print_float.cpp diff --git a/common/util/read_iso_file.cpp b/common/util/read_iso_file.cpp new file mode 100644 index 0000000000..837ee5f82a --- /dev/null +++ b/common/util/read_iso_file.cpp @@ -0,0 +1,114 @@ +#include "read_iso_file.h" +#include "third-party/fmt/core.h" +#include "common/common_types.h" +#include "common/util/Assert.h" +#include "common/util/FileUtil.h" + +IsoFile::IsoFile() { + root.is_dir = true; +} + +std::string IsoFile::print() const { + std::string result; + root.print(&result, ""); + return result; +} + +void IsoFile::Entry::print(std::string* result, const std::string& prefix) const { + if (is_dir) { + std::string child_prefix = prefix + "/" + name; + for (const auto& child : children) { + child.print(result, child_prefix); + } + } else { + result->append(prefix); + result->push_back('/'); + result->append(name); + result->push_back('\n'); + } +} + +namespace { +constexpr int SECTOR_SIZE = 0x800; + +template +T read_file(FILE* fp, u32 sector, u32 offset_in_sector) { + T result; + if (fseek(fp, sector * SECTOR_SIZE + offset_in_sector, SEEK_SET)) { + ASSERT_MSG(false, "Failed to fseek iso"); + } + if (fread(&result, sizeof(T), 1, fp) != 1) { + ASSERT_MSG(false, "Failed to fread iso"); + } + return result; +} + +void add_from_dir(FILE* fp, u32 sector, u32 size, IsoFile::Entry* parent) { + u32 offset = 0; + while (offset < size) { + if (!read_file(fp, sector, offset)) { + offset = (offset & ~(SECTOR_SIZE - 1)) + SECTOR_SIZE; + continue; + } + u8 record_size = read_file(fp, sector, offset); + u8 kind = read_file(fp, sector, offset + 0x21); + if ((kind != 0) && (kind != 1)) { + auto& entry = parent->children.emplace_back(); + u32 extent = read_file(fp, sector, offset + 2); + u32 dir_or_file_size = read_file(fp, sector, offset + 10); + u32 name_len = read_file(fp, sector, offset + 32); + u8 c0 = read_file(fp, sector, offset + name_len + 0x1f); + u8 c1 = read_file(fp, sector, offset + name_len + 0x20); + for (u32 i = 0; i < name_len; i++) { + entry.name.push_back(read_file(fp, sector, offset + 0x21 + i)); + } + entry.is_dir = (c0 != ';' || c1 != '1'); + if (entry.is_dir) { + add_from_dir(fp, extent, dir_or_file_size, &entry); + } else { + entry.name.pop_back(); + entry.name.pop_back(); + entry.offset_in_file = SECTOR_SIZE * extent; + entry.size = dir_or_file_size; + } + } + offset += record_size; + } +} + +void unpack_entry(FILE* fp, const IsoFile::Entry& entry, const std::filesystem::path& dest) { + std::filesystem::path path_to_entry = dest / entry.name; + if (entry.is_dir) { + std::filesystem::create_directory(path_to_entry); + for (const auto& child : entry.children) { + unpack_entry(fp, child, path_to_entry); + } + } else { + std::vector buffer(entry.size); + if (fseek(fp, entry.offset_in_file, SEEK_SET)) { + ASSERT_MSG(false, "Failed to fseek iso when unpacking"); + } + if (fread(buffer.data(), buffer.size(), 1, fp) != 1) { + ASSERT_MSG(false, "Failed to fread iso when unpacking"); + } + file_util::write_binary_file(path_to_entry.string(), buffer.data(), buffer.size()); + } +} +} // namespace + +IsoFile find_files_in_iso(FILE* fp) { + IsoFile result; + u32 path_table_sector = read_file(fp, 0x10, 0x8c); + u32 path_table_extent = read_file(fp, path_table_sector, 2); + u32 dir_size = read_file(fp, path_table_extent, 10); + add_from_dir(fp, path_table_extent, dir_size, &result.root); + return result; +} + +void unpack_iso_files(FILE* fp, const IsoFile& layout, const std::filesystem::path& dest) { + unpack_entry(fp, layout.root, dest); +} + +void unpack_iso_files(FILE* fp, const std::filesystem::path& dest) { + unpack_iso_files(fp, find_files_in_iso(fp), dest); +} diff --git a/common/util/read_iso_file.h b/common/util/read_iso_file.h new file mode 100644 index 0000000000..af771db8f9 --- /dev/null +++ b/common/util/read_iso_file.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include + +struct IsoFile { + struct Entry { + bool is_dir = false; + std::string name; + + // if file + size_t offset_in_file = 0; + size_t size = 0; + + // if dir + std::vector children; + void print(std::string* result, const std::string& prefix) const; + }; + + std::string print() const; + + Entry root; + + IsoFile(); +}; + +IsoFile find_files_in_iso(FILE* fp); +void unpack_iso_files(FILE* fp, const IsoFile& layout, const std::filesystem::path& dest); +void unpack_iso_files(FILE* fp, const std::filesystem::path& dest); \ No newline at end of file diff --git a/decompiler/extractor/main.cpp b/decompiler/extractor/main.cpp index a06ede7e32..43bd52e80e 100644 --- a/decompiler/extractor/main.cpp +++ b/decompiler/extractor/main.cpp @@ -5,6 +5,7 @@ #include "decompiler/level_extractor/extract_level.h" #include "decompiler/config.h" #include "goalc/compiler/Compiler.h" +#include "common/util/read_iso_file.h" void setup_global_decompiler_stuff() { file_util::init_crc(); @@ -31,8 +32,15 @@ int main(int argc, char** argv) { } if (!std::filesystem::is_directory(jak1_input_files)) { - fmt::print("Error: input folder {} is not a folder.\n", jak1_input_files.string()); - return 1; + fmt::print("Note: input isn't a folder, assuming it's an ISO file...\n"); + auto path_to_iso_files = file_util::get_jak_project_dir() / "extracted_iso"; + std::filesystem::create_directories(path_to_iso_files); + + auto fp = fopen(jak1_input_files.string().c_str(), "rb"); + ASSERT_MSG(fp, "failed to open input ISO file\n"); + unpack_iso_files(fp, path_to_iso_files); + fclose(fp); + jak1_input_files = path_to_iso_files; } if (!std::filesystem::exists(jak1_input_files / "DGO")) { From 9168e20e1811ff4dd7e8c48e378b865d60634947 Mon Sep 17 00:00:00 2001 From: Ziemas Date: Thu, 14 Apr 2022 00:50:35 +0200 Subject: [PATCH 023/172] Overlord fixes (#1301) * srpc: Implement part of VBlank_Handler And call it on RPC message for lack of better ways * ssound: Fix distance calculation avoids negative array index * srpc: fix sound id assignment * srpc: bail out on missing sound id * ssound: Fixes for angle and volume calculation * srpc: Fix VAG filename stuff * ssound: Fix CalculateAngle * ssound: UpdateAutoVol fixes * srpc: Fix up SET_PARAM command --- game/graphics/sceGraphicsInterface.cpp | 2 ++ game/overlord/srpc.cpp | 43 +++++++++++++++++++------- game/overlord/ssound.cpp | 12 +++---- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/game/graphics/sceGraphicsInterface.cpp b/game/graphics/sceGraphicsInterface.cpp index d291f90b1e..6aac5303d2 100644 --- a/game/graphics/sceGraphicsInterface.cpp +++ b/game/graphics/sceGraphicsInterface.cpp @@ -2,6 +2,7 @@ #include "game/graphics/gfx.h" #include #include "common/util/Assert.h" +#include "game/overlord/srpc.h" /*! * Wait for rendering to complete. @@ -28,5 +29,6 @@ u32 sceGsSyncPath(u32 mode, u32 timeout) { */ u32 sceGsSyncV(u32 mode) { ASSERT(mode == 0); + VBlank_Handler(); return Gfx::vsync(); } diff --git a/game/overlord/srpc.cpp b/game/overlord/srpc.cpp index b028b162ef..355c2502a3 100644 --- a/game/overlord/srpc.cpp +++ b/game/overlord/srpc.cpp @@ -104,19 +104,21 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) { while (n_messages > 0) { switch (cmd->command) { case SoundCommand::PLAY: { - // spool- soundsn are vag sounds? + if (cmd->play.sound_id == 0) { + break; + } if (!memcmp(cmd->play.name, "spool-", 6)) { - char namebuf[8]; - char langbuf[8]; - auto name = cmd->play.name; + char namebuf[16]; + const char* name = &cmd->play.name[6]; size_t len = strlen(name); if (len < 9) { - memset(namebuf, 32, sizeof(namebuf)); + memset(namebuf, ' ', 8); memcpy(namebuf, name, len); } else { - memcpy(namebuf, name, sizeof(namebuf)); + memcpy(namebuf, name, 8); } + // ASCII toupper for (int i = 0; i < 8; i++) { if (namebuf[i] >= 0x61 && namebuf[i] < 0x7b) { namebuf[i] -= 0x20; @@ -126,8 +128,8 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) { // TODO vagfile = FindVAGFile(namebuf); void* vagfile = nullptr; - memcpy(namebuf, "VAGWAD ", sizeof(namebuf)); - strcpy(langbuf, gLanguage); + memcpy(namebuf, "VAGWAD ", 8); + strcpy(&namebuf[8], gLanguage); FileRecord* rec = isofs->find_in(namebuf); if (vagfile != nullptr) { @@ -191,7 +193,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) { sound->params.pitch_mod, sound->params.bend); sound->sound_handle = handle; if (sound->sound_handle) { - sound->id = index; + sound->id = cmd->play.sound_id; } } break; case SoundCommand::PAUSE_SOUND: { @@ -223,7 +225,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) { u32 mask = cmd->param.parms.mask; if (sound != nullptr) { if (mask & 1) { - if (mask & 0x20) { + if (mask & 0x10) { sound->auto_time = cmd->param.auto_time; sound->new_volume = cmd->param.parms.volume; } else { @@ -240,7 +242,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) { sound->params.pitch_mod = cmd->param.parms.pitch_mod; if (mask & 0x10) { snd_AutoPitch(sound->sound_handle, sound->params.pitch_mod, cmd->param.auto_time, - cmd->param.auto_time); + cmd->param.auto_from); } else { snd_SetSoundPitchModifier(sound->sound_handle, cmd->param.parms.pitch_mod); } @@ -249,7 +251,7 @@ void* RPC_Player(unsigned int /*fno*/, void* data, int size) { sound->params.bend = cmd->param.parms.bend; if (mask & 0x10) { snd_AutoPitchBend(sound->sound_handle, sound->params.bend, cmd->param.auto_time, - cmd->param.auto_time); + cmd->param.auto_from); } else { snd_SetSoundPitchBend(sound->sound_handle, cmd->param.parms.bend); } @@ -420,5 +422,22 @@ void* RPC_Loader(unsigned int /*fno*/, void* data, int size) { } s32 VBlank_Handler() { + if (!gSoundEnable) + return 1; + + if (gMusicFadeDir > 0) { + gMusicFade += 1024; + if (gMusicFade > 0x10000) { + gMusicFade = 0x10000; + gMusicFadeDir = 0; + } + } else if (gMusicFadeDir < 0) { + gMusicFade -= 512; + if (gMusicFade < 0) { + gMusicFade = 0; + gMusicFadeDir = 0; + } + } + return 1; } diff --git a/game/overlord/ssound.cpp b/game/overlord/ssound.cpp index 51e368beab..9c2f7e3da4 100644 --- a/game/overlord/ssound.cpp +++ b/game/overlord/ssound.cpp @@ -249,7 +249,7 @@ s32 CalculateFallofVolume(Vec3w* pos, s32 volume, s32 fo_curve, s32 fo_min, s32 zdiff >>= 1; } - s32 distance = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff; + u32 distance = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff; if (distance != 0) { s32 steps = 0; while ((distance & 0xc0000000) == 0) { @@ -284,7 +284,7 @@ s32 CalculateFallofVolume(Vec3w* pos, s32 volume, s32 fo_curve, s32 fo_min, s32 } s32 factor = ((gCurve[fo_curve].unk4 << 16) + gCurve[fo_curve].unk3 * v13 + - gCurve[fo_curve].unk2 * ((v13 * 13) >> 16) + + gCurve[fo_curve].unk2 * ((v13 * v13) >> 16) + gCurve[fo_curve].unk1 * (((((v13 * v13) >> 16) * v13) >> 16) >> 16)) >> 12; @@ -310,7 +310,7 @@ s32 CalculateAngle(Vec3w* trans) { lookupZ = trans->z - gCamTrans.z; } - if (diffX == 0 && diffZ == 0) { + if (lookupX == 0 && lookupZ == 0) { return 0; } @@ -339,7 +339,7 @@ s32 CalculateAngle(Vec3w* trans) { } else if (diffZ >= 0) { angle = angle + 270; } else { - angle = 270 - 90; + angle = 270 - angle; } } @@ -413,10 +413,10 @@ static void UpdateAutoVol(Sound* sound, s32 ticks) { if (sound->new_volume == -4) { snd_StopSound(sound->sound_handle); sound->id = 0; - return; + } else { + sound->params.volume = sound->new_volume; } - sound->params.volume = sound->new_volume; sound->auto_time = 0; } From ab063bf7b043320f96de40cda082d26919039d31 Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Fri, 15 Apr 2022 18:01:47 -0400 Subject: [PATCH 024/172] extractor: split up extraction process and allow overriding `data` dir path (#1302) * extractor: split up extraction process and allow overriding `data` dir path * lint: formatting * deps: add CLI11 dependency * extractor: refactor CLI arg handling --- .vs/launch.vs.json | 7 + CMakePresets.json | 20 + common/util/FileUtil.cpp | 9 +- common/util/FileUtil.h | 2 +- decompiler/extractor/main.cpp | 135 +- decompiler/main.cpp | 2 +- game/main.cpp | 7 +- goalc/main.cpp | 2 +- test/offline/offline_test_main.cpp | 2 +- test/test_main.cpp | 2 +- third-party/CLI11.hpp | 9190 ++++++++++++++++++++++++++++ 11 files changed, 9338 insertions(+), 40 deletions(-) create mode 100644 third-party/CLI11.hpp diff --git a/.vs/launch.vs.json b/.vs/launch.vs.json index 3b6301e167..b38cc28223 100644 --- a/.vs/launch.vs.json +++ b/.vs/launch.vs.json @@ -125,6 +125,13 @@ "projectTarget" : "dgo_unpacker.exe (bin\\dgo_unpacker.exe)", "name" : "Run - DGO Unpacker (test)", "args" : [ "C:\\GameData\\Jak1\\Backup\\DGO-PAL\\GAME", "C:\\GameData\\Jak1\\Backup\\DISC-PAL\\CGO\\GAME.CGO"] + }, + { + "type" : "default", + "project" : "CMakeLists.txt", + "projectTarget" : "extractor.exe (bin\\extractor.exe)", + "name" : "Run - Extractor - Extract", + "args" : [ "\"E:\\ISOs\\Jak\\Jak 1.iso\"", "--extract", "-proj-path", "C:\\Users\\xtvas\\Repositories\\opengoal\\launcher\\bundle-test\\data"] } ] } diff --git a/CMakePresets.json b/CMakePresets.json index c82ad4fd9e..e92107cdad 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -54,6 +54,26 @@ }, "vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Windows" ] } } }, + { + "name": "Release-clang-static", + "displayName": "Windows Release - Static (clang-cl)", + "description": "Target Windows with the Visual Studio development environment.", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/Release", + "architecture": { + "value": "x64", + "strategy": "external" + }, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", + "INSTALL_GTEST": "True", + "CMAKE_C_COMPILER": "clang-cl", + "CMAKE_CXX_COMPILER": "clang-cl", + "BUILD_FOR_RELEASE": "true" + }, + "vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Windows" ] } } + }, { "name": "Debug-msvc", "displayName": "Windows Debug (msvc)", diff --git a/common/util/FileUtil.cpp b/common/util/FileUtil.cpp index 1de428a36b..9345c4b9f0 100644 --- a/common/util/FileUtil.cpp +++ b/common/util/FileUtil.cpp @@ -106,11 +106,18 @@ std::optional try_get_data_dir() { } } -bool setup_project_path() { +bool setup_project_path(std::optional project_path_override) { if (gFilePathInfo.initialized) { return true; } + if (project_path_override) { + gFilePathInfo.path_to_data = *project_path_override; + gFilePathInfo.initialized = true; + fmt::print("Using explicitly set project path: {}\n", project_path_override->string()); + return true; + } + auto data_path = try_get_data_dir(); if (data_path) { gFilePathInfo.path_to_data = *data_path; diff --git a/common/util/FileUtil.h b/common/util/FileUtil.h index b829ef5be9..f672b57992 100644 --- a/common/util/FileUtil.h +++ b/common/util/FileUtil.h @@ -22,7 +22,7 @@ std::filesystem::path get_jak_project_dir(); bool create_dir_if_needed(const std::string& path); bool create_dir_if_needed_for_file(const std::string& path); -bool setup_project_path(); +bool setup_project_path(std::optional project_path_override); std::string get_file_path(const std::vector& path); void write_binary_file(const std::string& name, const void* data, size_t size); void write_rgba_png(const std::string& name, void* data, int w, int h); diff --git a/decompiler/extractor/main.cpp b/decompiler/extractor/main.cpp index 43bd52e80e..83d92c1984 100644 --- a/decompiler/extractor/main.cpp +++ b/decompiler/extractor/main.cpp @@ -1,3 +1,4 @@ +#include "third-party/CLI11.hpp" #include "third-party/fmt/core.h" #include "common/util/FileUtil.h" #include "decompiler/Disasm/OpcodeInfo.h" @@ -7,47 +8,33 @@ #include "goalc/compiler/Compiler.h" #include "common/util/read_iso_file.h" -void setup_global_decompiler_stuff() { +void setup_global_decompiler_stuff(std::optional project_path_override) { file_util::init_crc(); decompiler::init_opcode_info(); - file_util::setup_project_path(); + file_util::setup_project_path(project_path_override); } -int main(int argc, char** argv) { - using namespace decompiler; - fmt::print("OpenGOAL Level Extraction Tool\n"); - if (argc != 2) { - fmt::print(" usage: extractor \n"); - return 1; - } +void extract_files(std::filesystem::path data_dir_path, std::filesystem::path extracted_iso_path) { + fmt::print("Note: input isn't a folder, assuming it's an ISO file...\n"); - // todo: print revision here. - setup_global_decompiler_stuff(); + std::filesystem::create_directories(extracted_iso_path); - std::filesystem::path jak1_input_files(argv[1]); - // make sure the input looks right - if (!std::filesystem::exists(jak1_input_files)) { - fmt::print("Error: input folder {} does not exist\n", jak1_input_files.string()); - return 1; - } + auto fp = fopen(data_dir_path.string().c_str(), "rb"); + ASSERT_MSG(fp, "failed to open input ISO file\n"); + unpack_iso_files(fp, extracted_iso_path); + fclose(fp); +} - if (!std::filesystem::is_directory(jak1_input_files)) { - fmt::print("Note: input isn't a folder, assuming it's an ISO file...\n"); - auto path_to_iso_files = file_util::get_jak_project_dir() / "extracted_iso"; - std::filesystem::create_directories(path_to_iso_files); - - auto fp = fopen(jak1_input_files.string().c_str(), "rb"); - ASSERT_MSG(fp, "failed to open input ISO file\n"); - unpack_iso_files(fp, path_to_iso_files); - fclose(fp); - jak1_input_files = path_to_iso_files; - } - - if (!std::filesystem::exists(jak1_input_files / "DGO")) { +int validate(std::filesystem::path path_to_iso_files) { + if (!std::filesystem::exists(path_to_iso_files / "DGO")) { fmt::print("Error: input folder doesn't have a DGO folder. Is this the right input?\n"); return 1; } + return 0; +} +void decompile(std::filesystem::path jak1_input_files) { + using namespace decompiler; Config config = read_config_file( (file_util::get_jak_project_dir() / "decompiler" / "config" / "jak1_ntsc_black_label.jsonc") .string(), @@ -123,15 +110,97 @@ int main(int argc, char** argv) { extract_from_level(db, tex_db, lev, config.hacks, config.rip_levels); } } +} - // Compile! +void compile(std::filesystem::path extracted_iso_path) { Compiler compiler; - compiler.make_system().set_constant("*iso-data*", absolute(jak1_input_files).string()); + compiler.make_system().set_constant("*iso-data*", absolute(extracted_iso_path).string()); compiler.make_system().set_constant("*use-iso-data-path*", true); compiler.make_system().load_project_file( (file_util::get_jak_project_dir() / "goal_src" / "game.gp").string()); compiler.run_front_end_on_string("(mi)"); +} +void launch_game() { system((file_util::get_jak_project_dir() / "../gk").string().c_str()); -} \ No newline at end of file +} + +int main(int argc, char** argv) { + std::filesystem::path data_dir_path; + std::filesystem::path project_path_override; + bool flag_runall = false; + bool flag_extract = false; + bool flag_validate = false; + bool flag_decompile = false; + bool flag_compile = false; + bool flag_play = false; + + CLI::App app{"OpenGOAL Level Extraction Tool"}; + app.add_option("game-files-path", data_dir_path, + "The path to the folder with the ISO extracted or the ISO itself") + ->check(CLI::ExistingPath) + ->required(); + app.add_option("--proj-path", project_path_override, + "Explicitly set the location of the 'data/' folder") + ->check(CLI::ExistingPath); + app.add_flag("-a,--all", flag_runall, "Run all steps, from extraction to playing the game"); + app.add_flag("-e,--extract", flag_extract, "Extract the ISO"); + app.add_flag("-v,--validate", flag_validate, "Validate the ISO / game files"); + app.add_flag("-d,--decompile", flag_decompile, "Decompile the game data"); + app.add_flag("-c,--compile", flag_compile, "Compile the game"); + app.add_flag("-p,--play", flag_play, "Play the game"); + app.validate_positionals(); + + CLI11_PARSE(app, argc, argv); + + fmt::print("Working Directory - {}\n", std::filesystem::current_path().string()); + + // If no flag is set, we default to running everything + if (!flag_extract && !flag_validate && !flag_decompile && !flag_compile && !flag_play) { + fmt::print("Running all steps, no flags provided!\n"); + flag_runall = true; + } + + // todo: print revision here. + if (!project_path_override.empty()) { + setup_global_decompiler_stuff(std::make_optional(project_path_override)); + } else { + setup_global_decompiler_stuff(std::nullopt); + } + + auto path_to_iso_files = file_util::get_jak_project_dir() / "extracted_iso"; + + // make sure the input looks right + if (!std::filesystem::exists(data_dir_path)) { + fmt::print("Error: input folder {} does not exist\n", data_dir_path.string()); + return 1; + } + + if (flag_runall || flag_extract) { + if (!std::filesystem::is_directory(path_to_iso_files)) { + extract_files(data_dir_path, path_to_iso_files); + } + } + + if (flag_runall || flag_validate) { + auto ok = validate(path_to_iso_files); + if (ok != 0) { + return ok; + } + } + + if (flag_runall || flag_decompile) { + decompile(path_to_iso_files); + } + + if (flag_runall || flag_compile) { + compile(path_to_iso_files); + } + + if (flag_runall || flag_play) { + launch_game(); + } + + return 0; +} diff --git a/decompiler/main.cpp b/decompiler/main.cpp index 67d1c144be..574eac0b8b 100644 --- a/decompiler/main.cpp +++ b/decompiler/main.cpp @@ -15,7 +15,7 @@ int main(int argc, char** argv) { fmt::print("[Mem] Top of main: {} MB\n", get_peak_rss() / (1024 * 1024)); using namespace decompiler; - if (!file_util::setup_project_path()) { + if (!file_util::setup_project_path(std::nullopt)) { return 1; } lg::set_file(file_util::get_file_path({"log/decompiler.txt"})); diff --git a/game/main.cpp b/game/main.cpp index c875dad4ec..d46027fcc0 100644 --- a/game/main.cpp +++ b/game/main.cpp @@ -39,6 +39,7 @@ int main(int argc, char** argv) { bool verbose = false; bool disable_avx2 = false; + std::optional project_path_override = std::nullopt; for (int i = 1; i < argc; i++) { if (std::string("-v") == argv[i]) { verbose = true; @@ -48,9 +49,13 @@ int main(int argc, char** argv) { if (std::string("-no-avx2") == argv[i]) { disable_avx2 = true; } + + if (std::string("-proj-path") == argv[i] && i + 1 < argc) { + project_path_override = std::make_optional(std::filesystem::path(argv[i + 1])); + } } - if (!file_util::setup_project_path()) { + if (!file_util::setup_project_path(project_path_override)) { return 1; } diff --git a/goalc/main.cpp b/goalc/main.cpp index 395e434674..ff395afb24 100644 --- a/goalc/main.cpp +++ b/goalc/main.cpp @@ -26,7 +26,7 @@ void setup_logging(bool verbose) { int main(int argc, char** argv) { (void)argc; (void)argv; - if (!file_util::setup_project_path()) { + if (!file_util::setup_project_path(std::nullopt)) { return 1; } std::string argument; diff --git a/test/offline/offline_test_main.cpp b/test/offline/offline_test_main.cpp index 27bb5e5e61..72e8757089 100644 --- a/test/offline/offline_test_main.cpp +++ b/test/offline/offline_test_main.cpp @@ -347,7 +347,7 @@ bool compile(Decompiler& dc, int main(int argc, char* argv[]) { fmt::print("Offline Decompiler Test 2\n"); lg::initialize(); - if (!file_util::setup_project_path()) { + if (!file_util::setup_project_path(std::nullopt)) { return 1; } diff --git a/test/test_main.cpp b/test/test_main.cpp index 9a3ba4a4bd..f08fdcbd33 100644 --- a/test/test_main.cpp +++ b/test/test_main.cpp @@ -20,7 +20,7 @@ int main(int argc, char** argv) { // hopefully get a debug print on github actions setup_cpu_info(); - file_util::setup_project_path(); + file_util::setup_project_path(std::nullopt); lg::initialize(); ::testing::InitGoogleTest(&argc, argv); diff --git a/third-party/CLI11.hpp b/third-party/CLI11.hpp new file mode 100644 index 0000000000..f29a5c4e1e --- /dev/null +++ b/third-party/CLI11.hpp @@ -0,0 +1,9190 @@ +// CLI11: Version 2.2.0 +// Originally designed by Henry Schreiner +// https://github.com/CLIUtils/CLI11 +// +// This is a standalone header file generated by MakeSingleHeader.py in CLI11/scripts +// from: v2.2.0 +// +// CLI11 2.2.0 Copyright (c) 2017-2022 University of Cincinnati, developed by Henry +// Schreiner under NSF AWARD 1414736. All rights reserved. +// +// Redistribution and use in source and binary forms of CLI11, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holder nor the names of its contributors +// may be used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +// Standard combined includes: +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define CLI11_VERSION_MAJOR 2 +#define CLI11_VERSION_MINOR 2 +#define CLI11_VERSION_PATCH 0 +#define CLI11_VERSION "2.2.0" + + + + +// The following version macro is very similar to the one in pybind11 +#if !(defined(_MSC_VER) && __cplusplus == 199711L) && !defined(__INTEL_COMPILER) +#if __cplusplus >= 201402L +#define CLI11_CPP14 +#if __cplusplus >= 201703L +#define CLI11_CPP17 +#if __cplusplus > 201703L +#define CLI11_CPP20 +#endif +#endif +#endif +#elif defined(_MSC_VER) && __cplusplus == 199711L +// MSVC sets _MSVC_LANG rather than __cplusplus (supposedly until the standard is fully implemented) +// Unless you use the /Zc:__cplusplus flag on Visual Studio 2017 15.7 Preview 3 or newer +#if _MSVC_LANG >= 201402L +#define CLI11_CPP14 +#if _MSVC_LANG > 201402L && _MSC_VER >= 1910 +#define CLI11_CPP17 +#if _MSVC_LANG > 201703L && _MSC_VER >= 1910 +#define CLI11_CPP20 +#endif +#endif +#endif +#endif + +#if defined(CLI11_CPP14) +#define CLI11_DEPRECATED(reason) [[deprecated(reason)]] +#elif defined(_MSC_VER) +#define CLI11_DEPRECATED(reason) __declspec(deprecated(reason)) +#else +#define CLI11_DEPRECATED(reason) __attribute__((deprecated(reason))) +#endif + +/** detection of rtti */ +#ifndef CLI11_USE_STATIC_RTTI +#if(defined(_HAS_STATIC_RTTI) && _HAS_STATIC_RTTI) +#define CLI11_USE_STATIC_RTTI 1 +#elif defined(__cpp_rtti) +#if(defined(_CPPRTTI) && _CPPRTTI == 0) +#define CLI11_USE_STATIC_RTTI 1 +#else +#define CLI11_USE_STATIC_RTTI 0 +#endif +#elif(defined(__GCC_RTTI) && __GXX_RTTI) +#define CLI11_USE_STATIC_RTTI 0 +#else +#define CLI11_USE_STATIC_RTTI 1 +#endif +#endif + + + +// C standard library +// Only needed for existence checking +#if defined CLI11_CPP17 && defined __has_include && !defined CLI11_HAS_FILESYSTEM +#if __has_include() +// Filesystem cannot be used if targeting macOS < 10.15 +#if defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 +#define CLI11_HAS_FILESYSTEM 0 +#elif defined(__wasi__) +// As of wasi-sdk-14, filesystem is not implemented +#define CLI11_HAS_FILESYSTEM 0 +#else +#include +#if defined __cpp_lib_filesystem && __cpp_lib_filesystem >= 201703 +#if defined _GLIBCXX_RELEASE && _GLIBCXX_RELEASE >= 9 +#define CLI11_HAS_FILESYSTEM 1 +#elif defined(__GLIBCXX__) +// if we are using gcc and Version <9 default to no filesystem +#define CLI11_HAS_FILESYSTEM 0 +#else +#define CLI11_HAS_FILESYSTEM 1 +#endif +#else +#define CLI11_HAS_FILESYSTEM 0 +#endif +#endif +#endif +#endif + +#if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0 +#include // NOLINT(build/include) +#else +#include +#include +#endif + + + +namespace CLI { + + +/// Include the items in this namespace to get free conversion of enums to/from streams. +/// (This is available inside CLI as well, so CLI11 will use this without a using statement). +namespace enums { + +/// output streaming for enumerations +template ::value>::type> +std::ostream &operator<<(std::ostream &in, const T &item) { + // make sure this is out of the detail namespace otherwise it won't be found when needed + return in << static_cast::type>(item); +} + +} // namespace enums + +/// Export to CLI namespace +using enums::operator<<; + +namespace detail { +/// a constant defining an expected max vector size defined to be a big number that could be multiplied by 4 and not +/// produce overflow for some expected uses +constexpr int expected_max_vector_size{1 << 29}; +// Based on http://stackoverflow.com/questions/236129/split-a-string-in-c +/// Split a string by a delim +inline std::vector split(const std::string &s, char delim) { + std::vector elems; + // Check to see if empty string, give consistent result + if(s.empty()) { + elems.emplace_back(); + } else { + std::stringstream ss; + ss.str(s); + std::string item; + while(std::getline(ss, item, delim)) { + elems.push_back(item); + } + } + return elems; +} + +/// Simple function to join a string +template std::string join(const T &v, std::string delim = ",") { + std::ostringstream s; + auto beg = std::begin(v); + auto end = std::end(v); + if(beg != end) + s << *beg++; + while(beg != end) { + s << delim << *beg++; + } + return s.str(); +} + +/// Simple function to join a string from processed elements +template ::value>::type> +std::string join(const T &v, Callable func, std::string delim = ",") { + std::ostringstream s; + auto beg = std::begin(v); + auto end = std::end(v); + auto loc = s.tellp(); + while(beg != end) { + auto nloc = s.tellp(); + if(nloc > loc) { + s << delim; + loc = nloc; + } + s << func(*beg++); + } + return s.str(); +} + +/// Join a string in reverse order +template std::string rjoin(const T &v, std::string delim = ",") { + std::ostringstream s; + for(std::size_t start = 0; start < v.size(); start++) { + if(start > 0) + s << delim; + s << v[v.size() - start - 1]; + } + return s.str(); +} + +// Based roughly on http://stackoverflow.com/questions/25829143/c-trim-whitespace-from-a-string + +/// Trim whitespace from left of string +inline std::string <rim(std::string &str) { + auto it = std::find_if(str.begin(), str.end(), [](char ch) { return !std::isspace(ch, std::locale()); }); + str.erase(str.begin(), it); + return str; +} + +/// Trim anything from left of string +inline std::string <rim(std::string &str, const std::string &filter) { + auto it = std::find_if(str.begin(), str.end(), [&filter](char ch) { return filter.find(ch) == std::string::npos; }); + str.erase(str.begin(), it); + return str; +} + +/// Trim whitespace from right of string +inline std::string &rtrim(std::string &str) { + auto it = std::find_if(str.rbegin(), str.rend(), [](char ch) { return !std::isspace(ch, std::locale()); }); + str.erase(it.base(), str.end()); + return str; +} + +/// Trim anything from right of string +inline std::string &rtrim(std::string &str, const std::string &filter) { + auto it = + std::find_if(str.rbegin(), str.rend(), [&filter](char ch) { return filter.find(ch) == std::string::npos; }); + str.erase(it.base(), str.end()); + return str; +} + +/// Trim whitespace from string +inline std::string &trim(std::string &str) { return ltrim(rtrim(str)); } + +/// Trim anything from string +inline std::string &trim(std::string &str, const std::string filter) { return ltrim(rtrim(str, filter), filter); } + +/// Make a copy of the string and then trim it +inline std::string trim_copy(const std::string &str) { + std::string s = str; + return trim(s); +} + +/// remove quotes at the front and back of a string either '"' or '\'' +inline std::string &remove_quotes(std::string &str) { + if(str.length() > 1 && (str.front() == '"' || str.front() == '\'')) { + if(str.front() == str.back()) { + str.pop_back(); + str.erase(str.begin(), str.begin() + 1); + } + } + return str; +} + +/// Add a leader to the beginning of all new lines (nothing is added +/// at the start of the first line). `"; "` would be for ini files +/// +/// Can't use Regex, or this would be a subs. +inline std::string fix_newlines(const std::string &leader, std::string input) { + std::string::size_type n = 0; + while(n != std::string::npos && n < input.size()) { + n = input.find('\n', n); + if(n != std::string::npos) { + input = input.substr(0, n + 1) + leader + input.substr(n + 1); + n += leader.size(); + } + } + return input; +} + +/// Make a copy of the string and then trim it, any filter string can be used (any char in string is filtered) +inline std::string trim_copy(const std::string &str, const std::string &filter) { + std::string s = str; + return trim(s, filter); +} +/// Print a two part "help" string +inline std::ostream &format_help(std::ostream &out, std::string name, const std::string &description, std::size_t wid) { + name = " " + name; + out << std::setw(static_cast(wid)) << std::left << name; + if(!description.empty()) { + if(name.length() >= wid) + out << "\n" << std::setw(static_cast(wid)) << ""; + for(const char c : description) { + out.put(c); + if(c == '\n') { + out << std::setw(static_cast(wid)) << ""; + } + } + } + out << "\n"; + return out; +} + +/// Print subcommand aliases +inline std::ostream &format_aliases(std::ostream &out, const std::vector &aliases, std::size_t wid) { + if(!aliases.empty()) { + out << std::setw(static_cast(wid)) << " aliases: "; + bool front = true; + for(const auto &alias : aliases) { + if(!front) { + out << ", "; + } else { + front = false; + } + out << detail::fix_newlines(" ", alias); + } + out << "\n"; + } + return out; +} + +/// Verify the first character of an option +/// - is a trigger character, ! has special meaning and new lines would just be annoying to deal with +template bool valid_first_char(T c) { return ((c != '-') && (c != '!') && (c != ' ') && c != '\n'); } + +/// Verify following characters of an option +template bool valid_later_char(T c) { + // = and : are value separators, { has special meaning for option defaults, + // and \n would just be annoying to deal with in many places allowing space here has too much potential for + // inadvertent entry errors and bugs + return ((c != '=') && (c != ':') && (c != '{') && (c != ' ') && c != '\n'); +} + +/// Verify an option/subcommand name +inline bool valid_name_string(const std::string &str) { + if(str.empty() || !valid_first_char(str[0])) { + return false; + } + auto e = str.end(); + for(auto c = str.begin() + 1; c != e; ++c) + if(!valid_later_char(*c)) + return false; + return true; +} + +/// Verify an app name +inline bool valid_alias_name_string(const std::string &str) { + static const std::string badChars(std::string("\n") + '\0'); + return (str.find_first_of(badChars) == std::string::npos); +} + +/// check if a string is a container segment separator (empty or "%%") +inline bool is_separator(const std::string &str) { + static const std::string sep("%%"); + return (str.empty() || str == sep); +} + +/// Verify that str consists of letters only +inline bool isalpha(const std::string &str) { + return std::all_of(str.begin(), str.end(), [](char c) { return std::isalpha(c, std::locale()); }); +} + +/// Return a lower case version of a string +inline std::string to_lower(std::string str) { + std::transform(std::begin(str), std::end(str), std::begin(str), [](const std::string::value_type &x) { + return std::tolower(x, std::locale()); + }); + return str; +} + +/// remove underscores from a string +inline std::string remove_underscore(std::string str) { + str.erase(std::remove(std::begin(str), std::end(str), '_'), std::end(str)); + return str; +} + +/// Find and replace a substring with another substring +inline std::string find_and_replace(std::string str, std::string from, std::string to) { + + std::size_t start_pos = 0; + + while((start_pos = str.find(from, start_pos)) != std::string::npos) { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); + } + + return str; +} + +/// check if the flag definitions has possible false flags +inline bool has_default_flag_values(const std::string &flags) { + return (flags.find_first_of("{!") != std::string::npos); +} + +inline void remove_default_flag_values(std::string &flags) { + auto loc = flags.find_first_of('{', 2); + while(loc != std::string::npos) { + auto finish = flags.find_first_of("},", loc + 1); + if((finish != std::string::npos) && (flags[finish] == '}')) { + flags.erase(flags.begin() + static_cast(loc), + flags.begin() + static_cast(finish) + 1); + } + loc = flags.find_first_of('{', loc + 1); + } + flags.erase(std::remove(flags.begin(), flags.end(), '!'), flags.end()); +} + +/// Check if a string is a member of a list of strings and optionally ignore case or ignore underscores +inline std::ptrdiff_t find_member(std::string name, + const std::vector names, + bool ignore_case = false, + bool ignore_underscore = false) { + auto it = std::end(names); + if(ignore_case) { + if(ignore_underscore) { + name = detail::to_lower(detail::remove_underscore(name)); + it = std::find_if(std::begin(names), std::end(names), [&name](std::string local_name) { + return detail::to_lower(detail::remove_underscore(local_name)) == name; + }); + } else { + name = detail::to_lower(name); + it = std::find_if(std::begin(names), std::end(names), [&name](std::string local_name) { + return detail::to_lower(local_name) == name; + }); + } + + } else if(ignore_underscore) { + name = detail::remove_underscore(name); + it = std::find_if(std::begin(names), std::end(names), [&name](std::string local_name) { + return detail::remove_underscore(local_name) == name; + }); + } else { + it = std::find(std::begin(names), std::end(names), name); + } + + return (it != std::end(names)) ? (it - std::begin(names)) : (-1); +} + +/// Find a trigger string and call a modify callable function that takes the current string and starting position of the +/// trigger and returns the position in the string to search for the next trigger string +template inline std::string find_and_modify(std::string str, std::string trigger, Callable modify) { + std::size_t start_pos = 0; + while((start_pos = str.find(trigger, start_pos)) != std::string::npos) { + start_pos = modify(str, start_pos); + } + return str; +} + +/// Split a string '"one two" "three"' into 'one two', 'three' +/// Quote characters can be ` ' or " +inline std::vector split_up(std::string str, char delimiter = '\0') { + + const std::string delims("\'\"`"); + auto find_ws = [delimiter](char ch) { + return (delimiter == '\0') ? (std::isspace(ch, std::locale()) != 0) : (ch == delimiter); + }; + trim(str); + + std::vector output; + bool embeddedQuote = false; + char keyChar = ' '; + while(!str.empty()) { + if(delims.find_first_of(str[0]) != std::string::npos) { + keyChar = str[0]; + auto end = str.find_first_of(keyChar, 1); + while((end != std::string::npos) && (str[end - 1] == '\\')) { // deal with escaped quotes + end = str.find_first_of(keyChar, end + 1); + embeddedQuote = true; + } + if(end != std::string::npos) { + output.push_back(str.substr(1, end - 1)); + if(end + 2 < str.size()) { + str = str.substr(end + 2); + } else { + str.clear(); + } + + } else { + output.push_back(str.substr(1)); + str = ""; + } + } else { + auto it = std::find_if(std::begin(str), std::end(str), find_ws); + if(it != std::end(str)) { + std::string value = std::string(str.begin(), it); + output.push_back(value); + str = std::string(it + 1, str.end()); + } else { + output.push_back(str); + str = ""; + } + } + // transform any embedded quotes into the regular character + if(embeddedQuote) { + output.back() = find_and_replace(output.back(), std::string("\\") + keyChar, std::string(1, keyChar)); + embeddedQuote = false; + } + trim(str); + } + return output; +} + +/// This function detects an equal or colon followed by an escaped quote after an argument +/// then modifies the string to replace the equality with a space. This is needed +/// to allow the split up function to work properly and is intended to be used with the find_and_modify function +/// the return value is the offset+1 which is required by the find_and_modify function. +inline std::size_t escape_detect(std::string &str, std::size_t offset) { + auto next = str[offset + 1]; + if((next == '\"') || (next == '\'') || (next == '`')) { + auto astart = str.find_last_of("-/ \"\'`", offset - 1); + if(astart != std::string::npos) { + if(str[astart] == ((str[offset] == '=') ? '-' : '/')) + str[offset] = ' '; // interpret this as a space so the split_up works properly + } + } + return offset + 1; +} + +/// Add quotes if the string contains spaces +inline std::string &add_quotes_if_needed(std::string &str) { + if((str.front() != '"' && str.front() != '\'') || str.front() != str.back()) { + char quote = str.find('"') < str.find('\'') ? '\'' : '"'; + if(str.find(' ') != std::string::npos) { + str.insert(0, 1, quote); + str.append(1, quote); + } + } + return str; +} + +} // namespace detail + + + + +// Use one of these on all error classes. +// These are temporary and are undef'd at the end of this file. +#define CLI11_ERROR_DEF(parent, name) \ + protected: \ + name(std::string ename, std::string msg, int exit_code) : parent(std::move(ename), std::move(msg), exit_code) {} \ + name(std::string ename, std::string msg, ExitCodes exit_code) \ + : parent(std::move(ename), std::move(msg), exit_code) {} \ + \ + public: \ + name(std::string msg, ExitCodes exit_code) : parent(#name, std::move(msg), exit_code) {} \ + name(std::string msg, int exit_code) : parent(#name, std::move(msg), exit_code) {} + +// This is added after the one above if a class is used directly and builds its own message +#define CLI11_ERROR_SIMPLE(name) \ + explicit name(std::string msg) : name(#name, msg, ExitCodes::name) {} + +/// These codes are part of every error in CLI. They can be obtained from e using e.exit_code or as a quick shortcut, +/// int values from e.get_error_code(). +enum class ExitCodes { + Success = 0, + IncorrectConstruction = 100, + BadNameString, + OptionAlreadyAdded, + FileError, + ConversionError, + ValidationError, + RequiredError, + RequiresError, + ExcludesError, + ExtrasError, + ConfigError, + InvalidError, + HorribleError, + OptionNotFound, + ArgumentMismatch, + BaseClass = 127 +}; + +// Error definitions + +/// @defgroup error_group Errors +/// @brief Errors thrown by CLI11 +/// +/// These are the errors that can be thrown. Some of them, like CLI::Success, are not really errors. +/// @{ + +/// All errors derive from this one +class Error : public std::runtime_error { + int actual_exit_code; + std::string error_name{"Error"}; + + public: + int get_exit_code() const { return actual_exit_code; } + + std::string get_name() const { return error_name; } + + Error(std::string name, std::string msg, int exit_code = static_cast(ExitCodes::BaseClass)) + : runtime_error(msg), actual_exit_code(exit_code), error_name(std::move(name)) {} + + Error(std::string name, std::string msg, ExitCodes exit_code) : Error(name, msg, static_cast(exit_code)) {} +}; + +// Note: Using Error::Error constructors does not work on GCC 4.7 + +/// Construction errors (not in parsing) +class ConstructionError : public Error { + CLI11_ERROR_DEF(Error, ConstructionError) +}; + +/// Thrown when an option is set to conflicting values (non-vector and multi args, for example) +class IncorrectConstruction : public ConstructionError { + CLI11_ERROR_DEF(ConstructionError, IncorrectConstruction) + CLI11_ERROR_SIMPLE(IncorrectConstruction) + static IncorrectConstruction PositionalFlag(std::string name) { + return IncorrectConstruction(name + ": Flags cannot be positional"); + } + static IncorrectConstruction Set0Opt(std::string name) { + return IncorrectConstruction(name + ": Cannot set 0 expected, use a flag instead"); + } + static IncorrectConstruction SetFlag(std::string name) { + return IncorrectConstruction(name + ": Cannot set an expected number for flags"); + } + static IncorrectConstruction ChangeNotVector(std::string name) { + return IncorrectConstruction(name + ": You can only change the expected arguments for vectors"); + } + static IncorrectConstruction AfterMultiOpt(std::string name) { + return IncorrectConstruction( + name + ": You can't change expected arguments after you've changed the multi option policy!"); + } + static IncorrectConstruction MissingOption(std::string name) { + return IncorrectConstruction("Option " + name + " is not defined"); + } + static IncorrectConstruction MultiOptionPolicy(std::string name) { + return IncorrectConstruction(name + ": multi_option_policy only works for flags and exact value options"); + } +}; + +/// Thrown on construction of a bad name +class BadNameString : public ConstructionError { + CLI11_ERROR_DEF(ConstructionError, BadNameString) + CLI11_ERROR_SIMPLE(BadNameString) + static BadNameString OneCharName(std::string name) { return BadNameString("Invalid one char name: " + name); } + static BadNameString BadLongName(std::string name) { return BadNameString("Bad long name: " + name); } + static BadNameString DashesOnly(std::string name) { + return BadNameString("Must have a name, not just dashes: " + name); + } + static BadNameString MultiPositionalNames(std::string name) { + return BadNameString("Only one positional name allowed, remove: " + name); + } +}; + +/// Thrown when an option already exists +class OptionAlreadyAdded : public ConstructionError { + CLI11_ERROR_DEF(ConstructionError, OptionAlreadyAdded) + explicit OptionAlreadyAdded(std::string name) + : OptionAlreadyAdded(name + " is already added", ExitCodes::OptionAlreadyAdded) {} + static OptionAlreadyAdded Requires(std::string name, std::string other) { + return OptionAlreadyAdded(name + " requires " + other, ExitCodes::OptionAlreadyAdded); + } + static OptionAlreadyAdded Excludes(std::string name, std::string other) { + return OptionAlreadyAdded(name + " excludes " + other, ExitCodes::OptionAlreadyAdded); + } +}; + +// Parsing errors + +/// Anything that can error in Parse +class ParseError : public Error { + CLI11_ERROR_DEF(Error, ParseError) +}; + +// Not really "errors" + +/// This is a successful completion on parsing, supposed to exit +class Success : public ParseError { + CLI11_ERROR_DEF(ParseError, Success) + Success() : Success("Successfully completed, should be caught and quit", ExitCodes::Success) {} +}; + +/// -h or --help on command line +class CallForHelp : public Success { + CLI11_ERROR_DEF(Success, CallForHelp) + CallForHelp() : CallForHelp("This should be caught in your main function, see examples", ExitCodes::Success) {} +}; + +/// Usually something like --help-all on command line +class CallForAllHelp : public Success { + CLI11_ERROR_DEF(Success, CallForAllHelp) + CallForAllHelp() + : CallForAllHelp("This should be caught in your main function, see examples", ExitCodes::Success) {} +}; + +/// -v or --version on command line +class CallForVersion : public Success { + CLI11_ERROR_DEF(Success, CallForVersion) + CallForVersion() + : CallForVersion("This should be caught in your main function, see examples", ExitCodes::Success) {} +}; + +/// Does not output a diagnostic in CLI11_PARSE, but allows main() to return with a specific error code. +class RuntimeError : public ParseError { + CLI11_ERROR_DEF(ParseError, RuntimeError) + explicit RuntimeError(int exit_code = 1) : RuntimeError("Runtime error", exit_code) {} +}; + +/// Thrown when parsing an INI file and it is missing +class FileError : public ParseError { + CLI11_ERROR_DEF(ParseError, FileError) + CLI11_ERROR_SIMPLE(FileError) + static FileError Missing(std::string name) { return FileError(name + " was not readable (missing?)"); } +}; + +/// Thrown when conversion call back fails, such as when an int fails to coerce to a string +class ConversionError : public ParseError { + CLI11_ERROR_DEF(ParseError, ConversionError) + CLI11_ERROR_SIMPLE(ConversionError) + ConversionError(std::string member, std::string name) + : ConversionError("The value " + member + " is not an allowed value for " + name) {} + ConversionError(std::string name, std::vector results) + : ConversionError("Could not convert: " + name + " = " + detail::join(results)) {} + static ConversionError TooManyInputsFlag(std::string name) { + return ConversionError(name + ": too many inputs for a flag"); + } + static ConversionError TrueFalse(std::string name) { + return ConversionError(name + ": Should be true/false or a number"); + } +}; + +/// Thrown when validation of results fails +class ValidationError : public ParseError { + CLI11_ERROR_DEF(ParseError, ValidationError) + CLI11_ERROR_SIMPLE(ValidationError) + explicit ValidationError(std::string name, std::string msg) : ValidationError(name + ": " + msg) {} +}; + +/// Thrown when a required option is missing +class RequiredError : public ParseError { + CLI11_ERROR_DEF(ParseError, RequiredError) + explicit RequiredError(std::string name) : RequiredError(name + " is required", ExitCodes::RequiredError) {} + static RequiredError Subcommand(std::size_t min_subcom) { + if(min_subcom == 1) { + return RequiredError("A subcommand"); + } + return RequiredError("Requires at least " + std::to_string(min_subcom) + " subcommands", + ExitCodes::RequiredError); + } + static RequiredError + Option(std::size_t min_option, std::size_t max_option, std::size_t used, const std::string &option_list) { + if((min_option == 1) && (max_option == 1) && (used == 0)) + return RequiredError("Exactly 1 option from [" + option_list + "]"); + if((min_option == 1) && (max_option == 1) && (used > 1)) { + return RequiredError("Exactly 1 option from [" + option_list + "] is required and " + std::to_string(used) + + " were given", + ExitCodes::RequiredError); + } + if((min_option == 1) && (used == 0)) + return RequiredError("At least 1 option from [" + option_list + "]"); + if(used < min_option) { + return RequiredError("Requires at least " + std::to_string(min_option) + " options used and only " + + std::to_string(used) + "were given from [" + option_list + "]", + ExitCodes::RequiredError); + } + if(max_option == 1) + return RequiredError("Requires at most 1 options be given from [" + option_list + "]", + ExitCodes::RequiredError); + + return RequiredError("Requires at most " + std::to_string(max_option) + " options be used and " + + std::to_string(used) + "were given from [" + option_list + "]", + ExitCodes::RequiredError); + } +}; + +/// Thrown when the wrong number of arguments has been received +class ArgumentMismatch : public ParseError { + CLI11_ERROR_DEF(ParseError, ArgumentMismatch) + CLI11_ERROR_SIMPLE(ArgumentMismatch) + ArgumentMismatch(std::string name, int expected, std::size_t received) + : ArgumentMismatch(expected > 0 ? ("Expected exactly " + std::to_string(expected) + " arguments to " + name + + ", got " + std::to_string(received)) + : ("Expected at least " + std::to_string(-expected) + " arguments to " + name + + ", got " + std::to_string(received)), + ExitCodes::ArgumentMismatch) {} + + static ArgumentMismatch AtLeast(std::string name, int num, std::size_t received) { + return ArgumentMismatch(name + ": At least " + std::to_string(num) + " required but received " + + std::to_string(received)); + } + static ArgumentMismatch AtMost(std::string name, int num, std::size_t received) { + return ArgumentMismatch(name + ": At Most " + std::to_string(num) + " required but received " + + std::to_string(received)); + } + static ArgumentMismatch TypedAtLeast(std::string name, int num, std::string type) { + return ArgumentMismatch(name + ": " + std::to_string(num) + " required " + type + " missing"); + } + static ArgumentMismatch FlagOverride(std::string name) { + return ArgumentMismatch(name + " was given a disallowed flag override"); + } + static ArgumentMismatch PartialType(std::string name, int num, std::string type) { + return ArgumentMismatch(name + ": " + type + " only partially specified: " + std::to_string(num) + + " required for each element"); + } +}; + +/// Thrown when a requires option is missing +class RequiresError : public ParseError { + CLI11_ERROR_DEF(ParseError, RequiresError) + RequiresError(std::string curname, std::string subname) + : RequiresError(curname + " requires " + subname, ExitCodes::RequiresError) {} +}; + +/// Thrown when an excludes option is present +class ExcludesError : public ParseError { + CLI11_ERROR_DEF(ParseError, ExcludesError) + ExcludesError(std::string curname, std::string subname) + : ExcludesError(curname + " excludes " + subname, ExitCodes::ExcludesError) {} +}; + +/// Thrown when too many positionals or options are found +class ExtrasError : public ParseError { + CLI11_ERROR_DEF(ParseError, ExtrasError) + explicit ExtrasError(std::vector args) + : ExtrasError((args.size() > 1 ? "The following arguments were not expected: " + : "The following argument was not expected: ") + + detail::rjoin(args, " "), + ExitCodes::ExtrasError) {} + ExtrasError(const std::string &name, std::vector args) + : ExtrasError(name, + (args.size() > 1 ? "The following arguments were not expected: " + : "The following argument was not expected: ") + + detail::rjoin(args, " "), + ExitCodes::ExtrasError) {} +}; + +/// Thrown when extra values are found in an INI file +class ConfigError : public ParseError { + CLI11_ERROR_DEF(ParseError, ConfigError) + CLI11_ERROR_SIMPLE(ConfigError) + static ConfigError Extras(std::string item) { return ConfigError("INI was not able to parse " + item); } + static ConfigError NotConfigurable(std::string item) { + return ConfigError(item + ": This option is not allowed in a configuration file"); + } +}; + +/// Thrown when validation fails before parsing +class InvalidError : public ParseError { + CLI11_ERROR_DEF(ParseError, InvalidError) + explicit InvalidError(std::string name) + : InvalidError(name + ": Too many positional arguments with unlimited expected args", ExitCodes::InvalidError) { + } +}; + +/// This is just a safety check to verify selection and parsing match - you should not ever see it +/// Strings are directly added to this error, but again, it should never be seen. +class HorribleError : public ParseError { + CLI11_ERROR_DEF(ParseError, HorribleError) + CLI11_ERROR_SIMPLE(HorribleError) +}; + +// After parsing + +/// Thrown when counting a non-existent option +class OptionNotFound : public Error { + CLI11_ERROR_DEF(Error, OptionNotFound) + explicit OptionNotFound(std::string name) : OptionNotFound(name + " not found", ExitCodes::OptionNotFound) {} +}; + +#undef CLI11_ERROR_DEF +#undef CLI11_ERROR_SIMPLE + +/// @} + + + + +// Type tools + +// Utilities for type enabling +namespace detail { +// Based generally on https://rmf.io/cxx11/almost-static-if +/// Simple empty scoped class +enum class enabler {}; + +/// An instance to use in EnableIf +constexpr enabler dummy = {}; +} // namespace detail + +/// A copy of enable_if_t from C++14, compatible with C++11. +/// +/// We could check to see if C++14 is being used, but it does not hurt to redefine this +/// (even Google does this: https://github.com/google/skia/blob/main/include/private/SkTLogic.h) +/// It is not in the std namespace anyway, so no harm done. +template using enable_if_t = typename std::enable_if::type; + +/// A copy of std::void_t from C++17 (helper for C++11 and C++14) +template struct make_void { using type = void; }; + +/// A copy of std::void_t from C++17 - same reasoning as enable_if_t, it does not hurt to redefine +template using void_t = typename make_void::type; + +/// A copy of std::conditional_t from C++14 - same reasoning as enable_if_t, it does not hurt to redefine +template using conditional_t = typename std::conditional::type; + +/// Check to see if something is bool (fail check by default) +template struct is_bool : std::false_type {}; + +/// Check to see if something is bool (true if actually a bool) +template <> struct is_bool : std::true_type {}; + +/// Check to see if something is a shared pointer +template struct is_shared_ptr : std::false_type {}; + +/// Check to see if something is a shared pointer (True if really a shared pointer) +template struct is_shared_ptr> : std::true_type {}; + +/// Check to see if something is a shared pointer (True if really a shared pointer) +template struct is_shared_ptr> : std::true_type {}; + +/// Check to see if something is copyable pointer +template struct is_copyable_ptr { + static bool const value = is_shared_ptr::value || std::is_pointer::value; +}; + +/// This can be specialized to override the type deduction for IsMember. +template struct IsMemberType { using type = T; }; + +/// The main custom type needed here is const char * should be a string. +template <> struct IsMemberType { using type = std::string; }; + +namespace detail { + +// These are utilities for IsMember and other transforming objects + +/// Handy helper to access the element_type generically. This is not part of is_copyable_ptr because it requires that +/// pointer_traits be valid. + +/// not a pointer +template struct element_type { using type = T; }; + +template struct element_type::value>::type> { + using type = typename std::pointer_traits::element_type; +}; + +/// Combination of the element type and value type - remove pointer (including smart pointers) and get the value_type of +/// the container +template struct element_value_type { using type = typename element_type::type::value_type; }; + +/// Adaptor for set-like structure: This just wraps a normal container in a few utilities that do almost nothing. +template struct pair_adaptor : std::false_type { + using value_type = typename T::value_type; + using first_type = typename std::remove_const::type; + using second_type = typename std::remove_const::type; + + /// Get the first value (really just the underlying value) + template static auto first(Q &&pair_value) -> decltype(std::forward(pair_value)) { + return std::forward(pair_value); + } + /// Get the second value (really just the underlying value) + template static auto second(Q &&pair_value) -> decltype(std::forward(pair_value)) { + return std::forward(pair_value); + } +}; + +/// Adaptor for map-like structure (true version, must have key_type and mapped_type). +/// This wraps a mapped container in a few utilities access it in a general way. +template +struct pair_adaptor< + T, + conditional_t, void>> + : std::true_type { + using value_type = typename T::value_type; + using first_type = typename std::remove_const::type; + using second_type = typename std::remove_const::type; + + /// Get the first value (really just the underlying value) + template static auto first(Q &&pair_value) -> decltype(std::get<0>(std::forward(pair_value))) { + return std::get<0>(std::forward(pair_value)); + } + /// Get the second value (really just the underlying value) + template static auto second(Q &&pair_value) -> decltype(std::get<1>(std::forward(pair_value))) { + return std::get<1>(std::forward(pair_value)); + } +}; + +// Warning is suppressed due to "bug" in gcc<5.0 and gcc 7.0 with c++17 enabled that generates a Wnarrowing warning +// in the unevaluated context even if the function that was using this wasn't used. The standard says narrowing in +// brace initialization shouldn't be allowed but for backwards compatibility gcc allows it in some contexts. It is a +// little fuzzy what happens in template constructs and I think that was something GCC took a little while to work out. +// But regardless some versions of gcc generate a warning when they shouldn't from the following code so that should be +// suppressed +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnarrowing" +#endif +// check for constructibility from a specific type and copy assignable used in the parse detection +template class is_direct_constructible { + template + static auto test(int, std::true_type) -> decltype( +// NVCC warns about narrowing conversions here +#ifdef __CUDACC__ +#pragma diag_suppress 2361 +#endif + TT { std::declval() } +#ifdef __CUDACC__ +#pragma diag_default 2361 +#endif + , + std::is_move_assignable()); + + template static auto test(int, std::false_type) -> std::false_type; + + template static auto test(...) -> std::false_type; + + public: + static constexpr bool value = decltype(test(0, typename std::is_constructible::type()))::value; +}; +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +// Check for output streamability +// Based on https://stackoverflow.com/questions/22758291/how-can-i-detect-if-a-type-can-be-streamed-to-an-stdostream + +template class is_ostreamable { + template + static auto test(int) -> decltype(std::declval() << std::declval(), std::true_type()); + + template static auto test(...) -> std::false_type; + + public: + static constexpr bool value = decltype(test(0))::value; +}; + +/// Check for input streamability +template class is_istreamable { + template + static auto test(int) -> decltype(std::declval() >> std::declval(), std::true_type()); + + template static auto test(...) -> std::false_type; + + public: + static constexpr bool value = decltype(test(0))::value; +}; + +/// Check for complex +template class is_complex { + template + static auto test(int) -> decltype(std::declval().real(), std::declval().imag(), std::true_type()); + + template static auto test(...) -> std::false_type; + + public: + static constexpr bool value = decltype(test(0))::value; +}; + +/// Templated operation to get a value from a stream +template ::value, detail::enabler> = detail::dummy> +bool from_stream(const std::string &istring, T &obj) { + std::istringstream is; + is.str(istring); + is >> obj; + return !is.fail() && !is.rdbuf()->in_avail(); +} + +template ::value, detail::enabler> = detail::dummy> +bool from_stream(const std::string & /*istring*/, T & /*obj*/) { + return false; +} + +// check to see if an object is a mutable container (fail by default) +template struct is_mutable_container : std::false_type {}; + +/// type trait to test if a type is a mutable container meaning it has a value_type, it has an iterator, a clear, and +/// end methods and an insert function. And for our purposes we exclude std::string and types that can be constructed +/// from a std::string +template +struct is_mutable_container< + T, + conditional_t().end()), + decltype(std::declval().clear()), + decltype(std::declval().insert(std::declval().end())>(), + std::declval()))>, + void>> + : public conditional_t::value, std::false_type, std::true_type> {}; + +// check to see if an object is a mutable container (fail by default) +template struct is_readable_container : std::false_type {}; + +/// type trait to test if a type is a container meaning it has a value_type, it has an iterator, a clear, and an end +/// methods and an insert function. And for our purposes we exclude std::string and types that can be constructed from +/// a std::string +template +struct is_readable_container< + T, + conditional_t().end()), decltype(std::declval().begin())>, void>> + : public std::true_type {}; + +// check to see if an object is a wrapper (fail by default) +template struct is_wrapper : std::false_type {}; + +// check if an object is a wrapper (it has a value_type defined) +template +struct is_wrapper, void>> : public std::true_type {}; + +// Check for tuple like types, as in classes with a tuple_size type trait +template class is_tuple_like { + template + // static auto test(int) + // -> decltype(std::conditional<(std::tuple_size::value > 0), std::true_type, std::false_type>::type()); + static auto test(int) -> decltype(std::tuple_size::type>::value, std::true_type{}); + template static auto test(...) -> std::false_type; + + public: + static constexpr bool value = decltype(test(0))::value; +}; + +/// Convert an object to a string (directly forward if this can become a string) +template ::value, detail::enabler> = detail::dummy> +auto to_string(T &&value) -> decltype(std::forward(value)) { + return std::forward(value); +} + +/// Construct a string from the object +template ::value && !std::is_convertible::value, + detail::enabler> = detail::dummy> +std::string to_string(const T &value) { + return std::string(value); +} + +/// Convert an object to a string (streaming must be supported for that type) +template ::value && !std::is_constructible::value && + is_ostreamable::value, + detail::enabler> = detail::dummy> +std::string to_string(T &&value) { + std::stringstream stream; + stream << value; + return stream.str(); +} + +/// If conversion is not supported, return an empty string (streaming is not supported for that type) +template ::value && !is_ostreamable::value && + !is_readable_container::type>::value, + detail::enabler> = detail::dummy> +std::string to_string(T &&) { + return std::string{}; +} + +/// convert a readable container to a string +template ::value && !is_ostreamable::value && + is_readable_container::value, + detail::enabler> = detail::dummy> +std::string to_string(T &&variable) { + auto cval = variable.begin(); + auto end = variable.end(); + if(cval == end) { + return std::string("{}"); + } + std::vector defaults; + while(cval != end) { + defaults.emplace_back(CLI::detail::to_string(*cval)); + ++cval; + } + return std::string("[" + detail::join(defaults) + "]"); +} + +/// special template overload +template ::value, detail::enabler> = detail::dummy> +auto checked_to_string(T &&value) -> decltype(to_string(std::forward(value))) { + return to_string(std::forward(value)); +} + +/// special template overload +template ::value, detail::enabler> = detail::dummy> +std::string checked_to_string(T &&) { + return std::string{}; +} +/// get a string as a convertible value for arithmetic types +template ::value, detail::enabler> = detail::dummy> +std::string value_string(const T &value) { + return std::to_string(value); +} +/// get a string as a convertible value for enumerations +template ::value, detail::enabler> = detail::dummy> +std::string value_string(const T &value) { + return std::to_string(static_cast::type>(value)); +} +/// for other types just use the regular to_string function +template ::value && !std::is_arithmetic::value, detail::enabler> = detail::dummy> +auto value_string(const T &value) -> decltype(to_string(value)) { + return to_string(value); +} + +/// template to get the underlying value type if it exists or use a default +template struct wrapped_type { using type = def; }; + +/// Type size for regular object types that do not look like a tuple +template struct wrapped_type::value>::type> { + using type = typename T::value_type; +}; + +/// This will only trigger for actual void type +template struct type_count_base { static const int value{0}; }; + +/// Type size for regular object types that do not look like a tuple +template +struct type_count_base::value && !is_mutable_container::value && + !std::is_void::value>::type> { + static constexpr int value{1}; +}; + +/// the base tuple size +template +struct type_count_base::value && !is_mutable_container::value>::type> { + static constexpr int value{std::tuple_size::value}; +}; + +/// Type count base for containers is the type_count_base of the individual element +template struct type_count_base::value>::type> { + static constexpr int value{type_count_base::value}; +}; + +/// Set of overloads to get the type size of an object + +/// forward declare the subtype_count structure +template struct subtype_count; + +/// forward declare the subtype_count_min structure +template struct subtype_count_min; + +/// This will only trigger for actual void type +template struct type_count { static const int value{0}; }; + +/// Type size for regular object types that do not look like a tuple +template +struct type_count::value && !is_tuple_like::value && !is_complex::value && + !std::is_void::value>::type> { + static constexpr int value{1}; +}; + +/// Type size for complex since it sometimes looks like a wrapper +template struct type_count::value>::type> { + static constexpr int value{2}; +}; + +/// Type size of types that are wrappers,except complex and tuples(which can also be wrappers sometimes) +template struct type_count::value>::type> { + static constexpr int value{subtype_count::value}; +}; + +/// Type size of types that are wrappers,except containers complex and tuples(which can also be wrappers sometimes) +template +struct type_count::value && !is_complex::value && !is_tuple_like::value && + !is_mutable_container::value>::type> { + static constexpr int value{type_count::value}; +}; + +/// 0 if the index > tuple size +template +constexpr typename std::enable_if::value, int>::type tuple_type_size() { + return 0; +} + +/// Recursively generate the tuple type name +template + constexpr typename std::enable_if < I::value, int>::type tuple_type_size() { + return subtype_count::type>::value + tuple_type_size(); +} + +/// Get the type size of the sum of type sizes for all the individual tuple types +template struct type_count::value>::type> { + static constexpr int value{tuple_type_size()}; +}; + +/// definition of subtype count +template struct subtype_count { + static constexpr int value{is_mutable_container::value ? expected_max_vector_size : type_count::value}; +}; + +/// This will only trigger for actual void type +template struct type_count_min { static const int value{0}; }; + +/// Type size for regular object types that do not look like a tuple +template +struct type_count_min< + T, + typename std::enable_if::value && !is_tuple_like::value && !is_wrapper::value && + !is_complex::value && !std::is_void::value>::type> { + static constexpr int value{type_count::value}; +}; + +/// Type size for complex since it sometimes looks like a wrapper +template struct type_count_min::value>::type> { + static constexpr int value{1}; +}; + +/// Type size min of types that are wrappers,except complex and tuples(which can also be wrappers sometimes) +template +struct type_count_min< + T, + typename std::enable_if::value && !is_complex::value && !is_tuple_like::value>::type> { + static constexpr int value{subtype_count_min::value}; +}; + +/// 0 if the index > tuple size +template +constexpr typename std::enable_if::value, int>::type tuple_type_size_min() { + return 0; +} + +/// Recursively generate the tuple type name +template + constexpr typename std::enable_if < I::value, int>::type tuple_type_size_min() { + return subtype_count_min::type>::value + tuple_type_size_min(); +} + +/// Get the type size of the sum of type sizes for all the individual tuple types +template struct type_count_min::value>::type> { + static constexpr int value{tuple_type_size_min()}; +}; + +/// definition of subtype count +template struct subtype_count_min { + static constexpr int value{is_mutable_container::value + ? ((type_count::value < expected_max_vector_size) ? type_count::value : 0) + : type_count_min::value}; +}; + +/// This will only trigger for actual void type +template struct expected_count { static const int value{0}; }; + +/// For most types the number of expected items is 1 +template +struct expected_count::value && !is_wrapper::value && + !std::is_void::value>::type> { + static constexpr int value{1}; +}; +/// number of expected items in a vector +template struct expected_count::value>::type> { + static constexpr int value{expected_max_vector_size}; +}; + +/// number of expected items in a vector +template +struct expected_count::value && is_wrapper::value>::type> { + static constexpr int value{expected_count::value}; +}; + +// Enumeration of the different supported categorizations of objects +enum class object_category : int { + char_value = 1, + integral_value = 2, + unsigned_integral = 4, + enumeration = 6, + boolean_value = 8, + floating_point = 10, + number_constructible = 12, + double_constructible = 14, + integer_constructible = 16, + // string like types + string_assignable = 23, + string_constructible = 24, + other = 45, + // special wrapper or container types + wrapper_value = 50, + complex_number = 60, + tuple_value = 70, + container_value = 80, + +}; + +/// Set of overloads to classify an object according to type + +/// some type that is not otherwise recognized +template struct classify_object { + static constexpr object_category value{object_category::other}; +}; + +/// Signed integers +template +struct classify_object< + T, + typename std::enable_if::value && !std::is_same::value && std::is_signed::value && + !is_bool::value && !std::is_enum::value>::type> { + static constexpr object_category value{object_category::integral_value}; +}; + +/// Unsigned integers +template +struct classify_object::value && std::is_unsigned::value && + !std::is_same::value && !is_bool::value>::type> { + static constexpr object_category value{object_category::unsigned_integral}; +}; + +/// single character values +template +struct classify_object::value && !std::is_enum::value>::type> { + static constexpr object_category value{object_category::char_value}; +}; + +/// Boolean values +template struct classify_object::value>::type> { + static constexpr object_category value{object_category::boolean_value}; +}; + +/// Floats +template struct classify_object::value>::type> { + static constexpr object_category value{object_category::floating_point}; +}; + +/// String and similar direct assignment +template +struct classify_object::value && !std::is_integral::value && + std::is_assignable::value>::type> { + static constexpr object_category value{object_category::string_assignable}; +}; + +/// String and similar constructible and copy assignment +template +struct classify_object< + T, + typename std::enable_if::value && !std::is_integral::value && + !std::is_assignable::value && (type_count::value == 1) && + std::is_constructible::value>::type> { + static constexpr object_category value{object_category::string_constructible}; +}; + +/// Enumerations +template struct classify_object::value>::type> { + static constexpr object_category value{object_category::enumeration}; +}; + +template struct classify_object::value>::type> { + static constexpr object_category value{object_category::complex_number}; +}; + +/// Handy helper to contain a bunch of checks that rule out many common types (integers, string like, floating point, +/// vectors, and enumerations +template struct uncommon_type { + using type = typename std::conditional::value && !std::is_integral::value && + !std::is_assignable::value && + !std::is_constructible::value && !is_complex::value && + !is_mutable_container::value && !std::is_enum::value, + std::true_type, + std::false_type>::type; + static constexpr bool value = type::value; +}; + +/// wrapper type +template +struct classify_object::value && is_wrapper::value && + !is_tuple_like::value && uncommon_type::value)>::type> { + static constexpr object_category value{object_category::wrapper_value}; +}; + +/// Assignable from double or int +template +struct classify_object::value && type_count::value == 1 && + !is_wrapper::value && is_direct_constructible::value && + is_direct_constructible::value>::type> { + static constexpr object_category value{object_category::number_constructible}; +}; + +/// Assignable from int +template +struct classify_object::value && type_count::value == 1 && + !is_wrapper::value && !is_direct_constructible::value && + is_direct_constructible::value>::type> { + static constexpr object_category value{object_category::integer_constructible}; +}; + +/// Assignable from double +template +struct classify_object::value && type_count::value == 1 && + !is_wrapper::value && is_direct_constructible::value && + !is_direct_constructible::value>::type> { + static constexpr object_category value{object_category::double_constructible}; +}; + +/// Tuple type +template +struct classify_object< + T, + typename std::enable_if::value && + ((type_count::value >= 2 && !is_wrapper::value) || + (uncommon_type::value && !is_direct_constructible::value && + !is_direct_constructible::value))>::type> { + static constexpr object_category value{object_category::tuple_value}; + // the condition on this class requires it be like a tuple, but on some compilers (like Xcode) tuples can be + // constructed from just the first element so tuples of can be constructed from a string, which + // could lead to issues so there are two variants of the condition, the first isolates things with a type size >=2 + // mainly to get tuples on Xcode with the exception of wrappers, the second is the main one and just separating out + // those cases that are caught by other object classifications +}; + +/// container type +template struct classify_object::value>::type> { + static constexpr object_category value{object_category::container_value}; +}; + +// Type name print + +/// Was going to be based on +/// http://stackoverflow.com/questions/1055452/c-get-name-of-type-in-template +/// But this is cleaner and works better in this case + +template ::value == object_category::char_value, detail::enabler> = detail::dummy> +constexpr const char *type_name() { + return "CHAR"; +} + +template ::value == object_category::integral_value || + classify_object::value == object_category::integer_constructible, + detail::enabler> = detail::dummy> +constexpr const char *type_name() { + return "INT"; +} + +template ::value == object_category::unsigned_integral, detail::enabler> = detail::dummy> +constexpr const char *type_name() { + return "UINT"; +} + +template ::value == object_category::floating_point || + classify_object::value == object_category::number_constructible || + classify_object::value == object_category::double_constructible, + detail::enabler> = detail::dummy> +constexpr const char *type_name() { + return "FLOAT"; +} + +/// Print name for enumeration types +template ::value == object_category::enumeration, detail::enabler> = detail::dummy> +constexpr const char *type_name() { + return "ENUM"; +} + +/// Print name for enumeration types +template ::value == object_category::boolean_value, detail::enabler> = detail::dummy> +constexpr const char *type_name() { + return "BOOLEAN"; +} + +/// Print name for enumeration types +template ::value == object_category::complex_number, detail::enabler> = detail::dummy> +constexpr const char *type_name() { + return "COMPLEX"; +} + +/// Print for all other types +template ::value >= object_category::string_assignable && + classify_object::value <= object_category::other, + detail::enabler> = detail::dummy> +constexpr const char *type_name() { + return "TEXT"; +} +/// typename for tuple value +template ::value == object_category::tuple_value && type_count_base::value >= 2, + detail::enabler> = detail::dummy> +std::string type_name(); // forward declaration + +/// Generate type name for a wrapper or container value +template ::value == object_category::container_value || + classify_object::value == object_category::wrapper_value, + detail::enabler> = detail::dummy> +std::string type_name(); // forward declaration + +/// Print name for single element tuple types +template ::value == object_category::tuple_value && type_count_base::value == 1, + detail::enabler> = detail::dummy> +inline std::string type_name() { + return type_name::type>::type>(); +} + +/// Empty string if the index > tuple size +template +inline typename std::enable_if::value, std::string>::type tuple_name() { + return std::string{}; +} + +/// Recursively generate the tuple type name +template +inline typename std::enable_if<(I < type_count_base::value), std::string>::type tuple_name() { + std::string str = std::string(type_name::type>::type>()) + + ',' + tuple_name(); + if(str.back() == ',') + str.pop_back(); + return str; +} + +/// Print type name for tuples with 2 or more elements +template ::value == object_category::tuple_value && type_count_base::value >= 2, + detail::enabler>> +inline std::string type_name() { + auto tname = std::string(1, '[') + tuple_name(); + tname.push_back(']'); + return tname; +} + +/// get the type name for a type that has a value_type member +template ::value == object_category::container_value || + classify_object::value == object_category::wrapper_value, + detail::enabler>> +inline std::string type_name() { + return type_name(); +} + +// Lexical cast + +/// Convert to an unsigned integral +template ::value, detail::enabler> = detail::dummy> +bool integral_conversion(const std::string &input, T &output) noexcept { + if(input.empty()) { + return false; + } + char *val = nullptr; + std::uint64_t output_ll = std::strtoull(input.c_str(), &val, 0); + output = static_cast(output_ll); + if(val == (input.c_str() + input.size()) && static_cast(output) == output_ll) { + return true; + } + val = nullptr; + std::int64_t output_sll = std::strtoll(input.c_str(), &val, 0); + if(val == (input.c_str() + input.size())) { + output = (output_sll < 0) ? static_cast(0) : static_cast(output_sll); + return (static_cast(output) == output_sll); + } + return false; +} + +/// Convert to a signed integral +template ::value, detail::enabler> = detail::dummy> +bool integral_conversion(const std::string &input, T &output) noexcept { + if(input.empty()) { + return false; + } + char *val = nullptr; + std::int64_t output_ll = std::strtoll(input.c_str(), &val, 0); + output = static_cast(output_ll); + if(val == (input.c_str() + input.size()) && static_cast(output) == output_ll) { + return true; + } + if(input == "true") { + // this is to deal with a few oddities with flags and wrapper int types + output = static_cast(1); + return true; + } + return false; +} + +/// Convert a flag into an integer value typically binary flags +inline std::int64_t to_flag_value(std::string val) { + static const std::string trueString("true"); + static const std::string falseString("false"); + if(val == trueString) { + return 1; + } + if(val == falseString) { + return -1; + } + val = detail::to_lower(val); + std::int64_t ret; + if(val.size() == 1) { + if(val[0] >= '1' && val[0] <= '9') { + return (static_cast(val[0]) - '0'); + } + switch(val[0]) { + case '0': + case 'f': + case 'n': + case '-': + ret = -1; + break; + case 't': + case 'y': + case '+': + ret = 1; + break; + default: + throw std::invalid_argument("unrecognized character"); + } + return ret; + } + if(val == trueString || val == "on" || val == "yes" || val == "enable") { + ret = 1; + } else if(val == falseString || val == "off" || val == "no" || val == "disable") { + ret = -1; + } else { + ret = std::stoll(val); + } + return ret; +} + +/// Integer conversion +template ::value == object_category::integral_value || + classify_object::value == object_category::unsigned_integral, + detail::enabler> = detail::dummy> +bool lexical_cast(const std::string &input, T &output) { + return integral_conversion(input, output); +} + +/// char values +template ::value == object_category::char_value, detail::enabler> = detail::dummy> +bool lexical_cast(const std::string &input, T &output) { + if(input.size() == 1) { + output = static_cast(input[0]); + return true; + } + return integral_conversion(input, output); +} + +/// Boolean values +template ::value == object_category::boolean_value, detail::enabler> = detail::dummy> +bool lexical_cast(const std::string &input, T &output) { + try { + auto out = to_flag_value(input); + output = (out > 0); + return true; + } catch(const std::invalid_argument &) { + return false; + } catch(const std::out_of_range &) { + // if the number is out of the range of a 64 bit value then it is still a number and for this purpose is still + // valid all we care about the sign + output = (input[0] != '-'); + return true; + } +} + +/// Floats +template ::value == object_category::floating_point, detail::enabler> = detail::dummy> +bool lexical_cast(const std::string &input, T &output) { + if(input.empty()) { + return false; + } + char *val = nullptr; + auto output_ld = std::strtold(input.c_str(), &val); + output = static_cast(output_ld); + return val == (input.c_str() + input.size()); +} + +/// complex +template ::value == object_category::complex_number, detail::enabler> = detail::dummy> +bool lexical_cast(const std::string &input, T &output) { + using XC = typename wrapped_type::type; + XC x{0.0}, y{0.0}; + auto str1 = input; + bool worked = false; + auto nloc = str1.find_last_of("+-"); + if(nloc != std::string::npos && nloc > 0) { + worked = detail::lexical_cast(str1.substr(0, nloc), x); + str1 = str1.substr(nloc); + if(str1.back() == 'i' || str1.back() == 'j') + str1.pop_back(); + worked = worked && detail::lexical_cast(str1, y); + } else { + if(str1.back() == 'i' || str1.back() == 'j') { + str1.pop_back(); + worked = detail::lexical_cast(str1, y); + x = XC{0}; + } else { + worked = detail::lexical_cast(str1, x); + y = XC{0}; + } + } + if(worked) { + output = T{x, y}; + return worked; + } + return from_stream(input, output); +} + +/// String and similar direct assignment +template ::value == object_category::string_assignable, detail::enabler> = detail::dummy> +bool lexical_cast(const std::string &input, T &output) { + output = input; + return true; +} + +/// String and similar constructible and copy assignment +template < + typename T, + enable_if_t::value == object_category::string_constructible, detail::enabler> = detail::dummy> +bool lexical_cast(const std::string &input, T &output) { + output = T(input); + return true; +} + +/// Enumerations +template ::value == object_category::enumeration, detail::enabler> = detail::dummy> +bool lexical_cast(const std::string &input, T &output) { + typename std::underlying_type::type val; + if(!integral_conversion(input, val)) { + return false; + } + output = static_cast(val); + return true; +} + +/// wrapper types +template ::value == object_category::wrapper_value && + std::is_assignable::value, + detail::enabler> = detail::dummy> +bool lexical_cast(const std::string &input, T &output) { + typename T::value_type val; + if(lexical_cast(input, val)) { + output = val; + return true; + } + return from_stream(input, output); +} + +template ::value == object_category::wrapper_value && + !std::is_assignable::value && std::is_assignable::value, + detail::enabler> = detail::dummy> +bool lexical_cast(const std::string &input, T &output) { + typename T::value_type val; + if(lexical_cast(input, val)) { + output = T{val}; + return true; + } + return from_stream(input, output); +} + +/// Assignable from double or int +template < + typename T, + enable_if_t::value == object_category::number_constructible, detail::enabler> = detail::dummy> +bool lexical_cast(const std::string &input, T &output) { + int val; + if(integral_conversion(input, val)) { + output = T(val); + return true; + } else { + double dval; + if(lexical_cast(input, dval)) { + output = T{dval}; + return true; + } + } + return from_stream(input, output); +} + +/// Assignable from int +template < + typename T, + enable_if_t::value == object_category::integer_constructible, detail::enabler> = detail::dummy> +bool lexical_cast(const std::string &input, T &output) { + int val; + if(integral_conversion(input, val)) { + output = T(val); + return true; + } + return from_stream(input, output); +} + +/// Assignable from double +template < + typename T, + enable_if_t::value == object_category::double_constructible, detail::enabler> = detail::dummy> +bool lexical_cast(const std::string &input, T &output) { + double val; + if(lexical_cast(input, val)) { + output = T{val}; + return true; + } + return from_stream(input, output); +} + +/// Non-string convertible from an int +template ::value == object_category::other && std::is_assignable::value, + detail::enabler> = detail::dummy> +bool lexical_cast(const std::string &input, T &output) { + int val; + if(integral_conversion(input, val)) { +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4800) +#endif + // with Atomic this could produce a warning due to the conversion but if atomic gets here it is an old style + // so will most likely still work + output = val; +#ifdef _MSC_VER +#pragma warning(pop) +#endif + return true; + } + // LCOV_EXCL_START + // This version of cast is only used for odd cases in an older compilers the fail over + // from_stream is tested elsewhere an not relevant for coverage here + return from_stream(input, output); + // LCOV_EXCL_STOP +} + +/// Non-string parsable by a stream +template ::value == object_category::other && !std::is_assignable::value, + detail::enabler> = detail::dummy> +bool lexical_cast(const std::string &input, T &output) { + static_assert(is_istreamable::value, + "option object type must have a lexical cast overload or streaming input operator(>>) defined, if it " + "is convertible from another type use the add_option(...) with XC being the known type"); + return from_stream(input, output); +} + +/// Assign a value through lexical cast operations +/// Strings can be empty so we need to do a little different +template ::value && + (classify_object::value == object_category::string_assignable || + classify_object::value == object_category::string_constructible), + detail::enabler> = detail::dummy> +bool lexical_assign(const std::string &input, AssignTo &output) { + return lexical_cast(input, output); +} + +/// Assign a value through lexical cast operations +template ::value && std::is_assignable::value && + classify_object::value != object_category::string_assignable && + classify_object::value != object_category::string_constructible, + detail::enabler> = detail::dummy> +bool lexical_assign(const std::string &input, AssignTo &output) { + if(input.empty()) { + output = AssignTo{}; + return true; + } + + return lexical_cast(input, output); +} + +/// Assign a value through lexical cast operations +template ::value && !std::is_assignable::value && + classify_object::value == object_category::wrapper_value, + detail::enabler> = detail::dummy> +bool lexical_assign(const std::string &input, AssignTo &output) { + if(input.empty()) { + typename AssignTo::value_type emptyVal{}; + output = emptyVal; + return true; + } + return lexical_cast(input, output); +} + +/// Assign a value through lexical cast operations for int compatible values +/// mainly for atomic operations on some compilers +template ::value && !std::is_assignable::value && + classify_object::value != object_category::wrapper_value && + std::is_assignable::value, + detail::enabler> = detail::dummy> +bool lexical_assign(const std::string &input, AssignTo &output) { + if(input.empty()) { + output = 0; + return true; + } + int val; + if(lexical_cast(input, val)) { + output = val; + return true; + } + return false; +} + +/// Assign a value converted from a string in lexical cast to the output value directly +template ::value && std::is_assignable::value, + detail::enabler> = detail::dummy> +bool lexical_assign(const std::string &input, AssignTo &output) { + ConvertTo val{}; + bool parse_result = (!input.empty()) ? lexical_cast(input, val) : true; + if(parse_result) { + output = val; + } + return parse_result; +} + +/// Assign a value from a lexical cast through constructing a value and move assigning it +template < + typename AssignTo, + typename ConvertTo, + enable_if_t::value && !std::is_assignable::value && + std::is_move_assignable::value, + detail::enabler> = detail::dummy> +bool lexical_assign(const std::string &input, AssignTo &output) { + ConvertTo val{}; + bool parse_result = input.empty() ? true : lexical_cast(input, val); + if(parse_result) { + output = AssignTo(val); // use () form of constructor to allow some implicit conversions + } + return parse_result; +} + +/// primary lexical conversion operation, 1 string to 1 type of some kind +template ::value <= object_category::other && + classify_object::value <= object_category::wrapper_value, + detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, AssignTo &output) { + return lexical_assign(strings[0], output); +} + +/// Lexical conversion if there is only one element but the conversion type is for two, then call a two element +/// constructor +template ::value <= 2) && expected_count::value == 1 && + is_tuple_like::value && type_count_base::value == 2, + detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, AssignTo &output) { + // the remove const is to handle pair types coming from a container + typename std::remove_const::type>::type v1; + typename std::tuple_element<1, ConvertTo>::type v2; + bool retval = lexical_assign(strings[0], v1); + if(strings.size() > 1) { + retval = retval && lexical_assign(strings[1], v2); + } + if(retval) { + output = AssignTo{v1, v2}; + } + return retval; +} + +/// Lexical conversion of a container types of single elements +template ::value && is_mutable_container::value && + type_count::value == 1, + detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, AssignTo &output) { + output.erase(output.begin(), output.end()); + if(strings.size() == 1 && strings[0] == "{}") { + return true; + } + bool skip_remaining = false; + if(strings.size() == 2 && strings[0] == "{}" && is_separator(strings[1])) { + skip_remaining = true; + } + for(const auto &elem : strings) { + typename AssignTo::value_type out; + bool retval = lexical_assign(elem, out); + if(!retval) { + return false; + } + output.insert(output.end(), std::move(out)); + if(skip_remaining) { + break; + } + } + return (!output.empty()); +} + +/// Lexical conversion for complex types +template ::value, detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, AssignTo &output) { + + if(strings.size() >= 2 && !strings[1].empty()) { + using XC2 = typename wrapped_type::type; + XC2 x{0.0}, y{0.0}; + auto str1 = strings[1]; + if(str1.back() == 'i' || str1.back() == 'j') { + str1.pop_back(); + } + auto worked = detail::lexical_cast(strings[0], x) && detail::lexical_cast(str1, y); + if(worked) { + output = ConvertTo{x, y}; + } + return worked; + } else { + return lexical_assign(strings[0], output); + } +} + +/// Conversion to a vector type using a particular single type as the conversion type +template ::value && (expected_count::value == 1) && + (type_count::value == 1), + detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, AssignTo &output) { + bool retval = true; + output.clear(); + output.reserve(strings.size()); + for(const auto &elem : strings) { + + output.emplace_back(); + retval = retval && lexical_assign(elem, output.back()); + } + return (!output.empty()) && retval; +} + +// forward declaration + +/// Lexical conversion of a container types with conversion type of two elements +template ::value && is_mutable_container::value && + type_count_base::value == 2, + detail::enabler> = detail::dummy> +bool lexical_conversion(std::vector strings, AssignTo &output); + +/// Lexical conversion of a vector types with type_size >2 forward declaration +template ::value && is_mutable_container::value && + type_count_base::value != 2 && + ((type_count::value > 2) || + (type_count::value > type_count_base::value)), + detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, AssignTo &output); + +/// Conversion for tuples +template ::value && is_tuple_like::value && + (type_count_base::value != type_count::value || + type_count::value > 2), + detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, AssignTo &output); // forward declaration + +/// Conversion for operations where the assigned type is some class but the conversion is a mutable container or large +/// tuple +template ::value && !is_mutable_container::value && + classify_object::value != object_category::wrapper_value && + (is_mutable_container::value || type_count::value > 2), + detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, AssignTo &output) { + + if(strings.size() > 1 || (!strings.empty() && !(strings.front().empty()))) { + ConvertTo val; + auto retval = lexical_conversion(strings, val); + output = AssignTo{val}; + return retval; + } + output = AssignTo{}; + return true; +} + +/// function template for converting tuples if the static Index is greater than the tuple size +template +inline typename std::enable_if<(I >= type_count_base::value), bool>::type +tuple_conversion(const std::vector &, AssignTo &) { + return true; +} + +/// Conversion of a tuple element where the type size ==1 and not a mutable container +template +inline typename std::enable_if::value && type_count::value == 1, bool>::type +tuple_type_conversion(std::vector &strings, AssignTo &output) { + auto retval = lexical_assign(strings[0], output); + strings.erase(strings.begin()); + return retval; +} + +/// Conversion of a tuple element where the type size !=1 but the size is fixed and not a mutable container +template +inline typename std::enable_if::value && (type_count::value > 1) && + type_count::value == type_count_min::value, + bool>::type +tuple_type_conversion(std::vector &strings, AssignTo &output) { + auto retval = lexical_conversion(strings, output); + strings.erase(strings.begin(), strings.begin() + type_count::value); + return retval; +} + +/// Conversion of a tuple element where the type is a mutable container or a type with different min and max type sizes +template +inline typename std::enable_if::value || + type_count::value != type_count_min::value, + bool>::type +tuple_type_conversion(std::vector &strings, AssignTo &output) { + + std::size_t index{subtype_count_min::value}; + const std::size_t mx_count{subtype_count::value}; + const std::size_t mx{(std::max)(mx_count, strings.size())}; + + while(index < mx) { + if(is_separator(strings[index])) { + break; + } + ++index; + } + bool retval = lexical_conversion( + std::vector(strings.begin(), strings.begin() + static_cast(index)), output); + strings.erase(strings.begin(), strings.begin() + static_cast(index) + 1); + return retval; +} + +/// Tuple conversion operation +template +inline typename std::enable_if<(I < type_count_base::value), bool>::type +tuple_conversion(std::vector strings, AssignTo &output) { + bool retval = true; + using ConvertToElement = typename std:: + conditional::value, typename std::tuple_element::type, ConvertTo>::type; + if(!strings.empty()) { + retval = retval && tuple_type_conversion::type, ConvertToElement>( + strings, std::get(output)); + } + retval = retval && tuple_conversion(std::move(strings), output); + return retval; +} + +/// Lexical conversion of a container types with tuple elements of size 2 +template ::value && is_mutable_container::value && + type_count_base::value == 2, + detail::enabler>> +bool lexical_conversion(std::vector strings, AssignTo &output) { + output.clear(); + while(!strings.empty()) { + + typename std::remove_const::type>::type v1; + typename std::tuple_element<1, typename ConvertTo::value_type>::type v2; + bool retval = tuple_type_conversion(strings, v1); + if(!strings.empty()) { + retval = retval && tuple_type_conversion(strings, v2); + } + if(retval) { + output.insert(output.end(), typename AssignTo::value_type{v1, v2}); + } else { + return false; + } + } + return (!output.empty()); +} + +/// lexical conversion of tuples with type count>2 or tuples of types of some element with a type size>=2 +template ::value && is_tuple_like::value && + (type_count_base::value != type_count::value || + type_count::value > 2), + detail::enabler>> +bool lexical_conversion(const std::vector &strings, AssignTo &output) { + static_assert( + !is_tuple_like::value || type_count_base::value == type_count_base::value, + "if the conversion type is defined as a tuple it must be the same size as the type you are converting to"); + return tuple_conversion(strings, output); +} + +/// Lexical conversion of a vector types for everything but tuples of two elements and types of size 1 +template ::value && is_mutable_container::value && + type_count_base::value != 2 && + ((type_count::value > 2) || + (type_count::value > type_count_base::value)), + detail::enabler>> +bool lexical_conversion(const std::vector &strings, AssignTo &output) { + bool retval = true; + output.clear(); + std::vector temp; + std::size_t ii{0}; + std::size_t icount{0}; + std::size_t xcm{type_count::value}; + auto ii_max = strings.size(); + while(ii < ii_max) { + temp.push_back(strings[ii]); + ++ii; + ++icount; + if(icount == xcm || is_separator(temp.back()) || ii == ii_max) { + if(static_cast(xcm) > type_count_min::value && is_separator(temp.back())) { + temp.pop_back(); + } + typename AssignTo::value_type temp_out; + retval = retval && + lexical_conversion(temp, temp_out); + temp.clear(); + if(!retval) { + return false; + } + output.insert(output.end(), std::move(temp_out)); + icount = 0; + } + } + return retval; +} + +/// conversion for wrapper types +template ::value == object_category::wrapper_value && + std::is_assignable::value, + detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, AssignTo &output) { + if(strings.empty() || strings.front().empty()) { + output = ConvertTo{}; + return true; + } + typename ConvertTo::value_type val; + if(lexical_conversion(strings, val)) { + output = ConvertTo{val}; + return true; + } + return false; +} + +/// conversion for wrapper types +template ::value == object_category::wrapper_value && + !std::is_assignable::value, + detail::enabler> = detail::dummy> +bool lexical_conversion(const std::vector &strings, AssignTo &output) { + using ConvertType = typename ConvertTo::value_type; + if(strings.empty() || strings.front().empty()) { + output = ConvertType{}; + return true; + } + ConvertType val; + if(lexical_conversion(strings, val)) { + output = val; + return true; + } + return false; +} + +/// Sum a vector of strings +inline std::string sum_string_vector(const std::vector &values) { + double val{0.0}; + bool fail{false}; + std::string output; + for(const auto &arg : values) { + double tv{0.0}; + auto comp = detail::lexical_cast(arg, tv); + if(!comp) { + try { + tv = static_cast(detail::to_flag_value(arg)); + } catch(const std::exception &) { + fail = true; + break; + } + } + val += tv; + } + if(fail) { + for(const auto &arg : values) { + output.append(arg); + } + } else { + if(val <= static_cast(std::numeric_limits::min()) || + val >= static_cast(std::numeric_limits::max()) || + val == static_cast(val)) { + output = detail::value_string(static_cast(val)); + } else { + output = detail::value_string(val); + } + } + return output; +} + +} // namespace detail + + + +namespace detail { + +// Returns false if not a short option. Otherwise, sets opt name and rest and returns true +inline bool split_short(const std::string ¤t, std::string &name, std::string &rest) { + if(current.size() > 1 && current[0] == '-' && valid_first_char(current[1])) { + name = current.substr(1, 1); + rest = current.substr(2); + return true; + } + return false; +} + +// Returns false if not a long option. Otherwise, sets opt name and other side of = and returns true +inline bool split_long(const std::string ¤t, std::string &name, std::string &value) { + if(current.size() > 2 && current.substr(0, 2) == "--" && valid_first_char(current[2])) { + auto loc = current.find_first_of('='); + if(loc != std::string::npos) { + name = current.substr(2, loc - 2); + value = current.substr(loc + 1); + } else { + name = current.substr(2); + value = ""; + } + return true; + } + return false; +} + +// Returns false if not a windows style option. Otherwise, sets opt name and value and returns true +inline bool split_windows_style(const std::string ¤t, std::string &name, std::string &value) { + if(current.size() > 1 && current[0] == '/' && valid_first_char(current[1])) { + auto loc = current.find_first_of(':'); + if(loc != std::string::npos) { + name = current.substr(1, loc - 1); + value = current.substr(loc + 1); + } else { + name = current.substr(1); + value = ""; + } + return true; + } + return false; +} + +// Splits a string into multiple long and short names +inline std::vector split_names(std::string current) { + std::vector output; + std::size_t val; + while((val = current.find(",")) != std::string::npos) { + output.push_back(trim_copy(current.substr(0, val))); + current = current.substr(val + 1); + } + output.push_back(trim_copy(current)); + return output; +} + +/// extract default flag values either {def} or starting with a ! +inline std::vector> get_default_flag_values(const std::string &str) { + std::vector flags = split_names(str); + flags.erase(std::remove_if(flags.begin(), + flags.end(), + [](const std::string &name) { + return ((name.empty()) || (!(((name.find_first_of('{') != std::string::npos) && + (name.back() == '}')) || + (name[0] == '!')))); + }), + flags.end()); + std::vector> output; + output.reserve(flags.size()); + for(auto &flag : flags) { + auto def_start = flag.find_first_of('{'); + std::string defval = "false"; + if((def_start != std::string::npos) && (flag.back() == '}')) { + defval = flag.substr(def_start + 1); + defval.pop_back(); + flag.erase(def_start, std::string::npos); + } + flag.erase(0, flag.find_first_not_of("-!")); + output.emplace_back(flag, defval); + } + return output; +} + +/// Get a vector of short names, one of long names, and a single name +inline std::tuple, std::vector, std::string> +get_names(const std::vector &input) { + + std::vector short_names; + std::vector long_names; + std::string pos_name; + + for(std::string name : input) { + if(name.length() == 0) { + continue; + } + if(name.length() > 1 && name[0] == '-' && name[1] != '-') { + if(name.length() == 2 && valid_first_char(name[1])) + short_names.emplace_back(1, name[1]); + else + throw BadNameString::OneCharName(name); + } else if(name.length() > 2 && name.substr(0, 2) == "--") { + name = name.substr(2); + if(valid_name_string(name)) + long_names.push_back(name); + else + throw BadNameString::BadLongName(name); + } else if(name == "-" || name == "--") { + throw BadNameString::DashesOnly(name); + } else { + if(pos_name.length() > 0) + throw BadNameString::MultiPositionalNames(name); + pos_name = name; + } + } + + return std::tuple, std::vector, std::string>( + short_names, long_names, pos_name); +} + +} // namespace detail + + + +class App; + +/// Holds values to load into Options +struct ConfigItem { + /// This is the list of parents + std::vector parents{}; + + /// This is the name + std::string name{}; + + /// Listing of inputs + std::vector inputs{}; + + /// The list of parents and name joined by "." + std::string fullname() const { + std::vector tmp = parents; + tmp.emplace_back(name); + return detail::join(tmp, "."); + } +}; + +/// This class provides a converter for configuration files. +class Config { + protected: + std::vector items{}; + + public: + /// Convert an app into a configuration + virtual std::string to_config(const App *, bool, bool, std::string) const = 0; + + /// Convert a configuration into an app + virtual std::vector from_config(std::istream &) const = 0; + + /// Get a flag value + virtual std::string to_flag(const ConfigItem &item) const { + if(item.inputs.size() == 1) { + return item.inputs.at(0); + } + if(item.inputs.empty()) { + return "{}"; + } + throw ConversionError::TooManyInputsFlag(item.fullname()); + } + + /// Parse a config file, throw an error (ParseError:ConfigParseError or FileError) on failure + std::vector from_file(const std::string &name) { + std::ifstream input{name}; + if(!input.good()) + throw FileError::Missing(name); + + return from_config(input); + } + + /// Virtual destructor + virtual ~Config() = default; +}; + +/// This converter works with INI/TOML files; to write INI files use ConfigINI +class ConfigBase : public Config { + protected: + /// the character used for comments + char commentChar = '#'; + /// the character used to start an array '\0' is a default to not use + char arrayStart = '['; + /// the character used to end an array '\0' is a default to not use + char arrayEnd = ']'; + /// the character used to separate elements in an array + char arraySeparator = ','; + /// the character used separate the name from the value + char valueDelimiter = '='; + /// the character to use around strings + char stringQuote = '"'; + /// the character to use around single characters + char characterQuote = '\''; + /// the maximum number of layers to allow + uint8_t maximumLayers{255}; + /// the separator used to separator parent layers + char parentSeparatorChar{'.'}; + /// Specify the configuration index to use for arrayed sections + int16_t configIndex{-1}; + /// Specify the configuration section that should be used + std::string configSection{}; + + public: + std::string + to_config(const App * /*app*/, bool default_also, bool write_description, std::string prefix) const override; + + std::vector from_config(std::istream &input) const override; + /// Specify the configuration for comment characters + ConfigBase *comment(char cchar) { + commentChar = cchar; + return this; + } + /// Specify the start and end characters for an array + ConfigBase *arrayBounds(char aStart, char aEnd) { + arrayStart = aStart; + arrayEnd = aEnd; + return this; + } + /// Specify the delimiter character for an array + ConfigBase *arrayDelimiter(char aSep) { + arraySeparator = aSep; + return this; + } + /// Specify the delimiter between a name and value + ConfigBase *valueSeparator(char vSep) { + valueDelimiter = vSep; + return this; + } + /// Specify the quote characters used around strings and characters + ConfigBase *quoteCharacter(char qString, char qChar) { + stringQuote = qString; + characterQuote = qChar; + return this; + } + /// Specify the maximum number of parents + ConfigBase *maxLayers(uint8_t layers) { + maximumLayers = layers; + return this; + } + /// Specify the separator to use for parent layers + ConfigBase *parentSeparator(char sep) { + parentSeparatorChar = sep; + return this; + } + /// get a reference to the configuration section + std::string §ionRef() { return configSection; } + /// get the section + const std::string §ion() const { return configSection; } + /// specify a particular section of the configuration file to use + ConfigBase *section(const std::string §ionName) { + configSection = sectionName; + return this; + } + + /// get a reference to the configuration index + int16_t &indexRef() { return configIndex; } + /// get the section index + int16_t index() const { return configIndex; } + /// specify a particular index in the section to use (-1) for all sections to use + ConfigBase *index(int16_t sectionIndex) { + configIndex = sectionIndex; + return this; + } +}; + +/// the default Config is the TOML file format +using ConfigTOML = ConfigBase; + +/// ConfigINI generates a "standard" INI compliant output +class ConfigINI : public ConfigTOML { + + public: + ConfigINI() { + commentChar = ';'; + arrayStart = '\0'; + arrayEnd = '\0'; + arraySeparator = ' '; + valueDelimiter = '='; + } +}; + + + +class Option; + +/// @defgroup validator_group Validators + +/// @brief Some validators that are provided +/// +/// These are simple `std::string(const std::string&)` validators that are useful. They return +/// a string if the validation fails. A custom struct is provided, as well, with the same user +/// semantics, but with the ability to provide a new type name. +/// @{ + +/// +class Validator { + protected: + /// This is the description function, if empty the description_ will be used + std::function desc_function_{[]() { return std::string{}; }}; + + /// This is the base function that is to be called. + /// Returns a string error message if validation fails. + std::function func_{[](std::string &) { return std::string{}; }}; + /// The name for search purposes of the Validator + std::string name_{}; + /// A Validator will only apply to an indexed value (-1 is all elements) + int application_index_ = -1; + /// Enable for Validator to allow it to be disabled if need be + bool active_{true}; + /// specify that a validator should not modify the input + bool non_modifying_{false}; + + public: + Validator() = default; + /// Construct a Validator with just the description string + explicit Validator(std::string validator_desc) : desc_function_([validator_desc]() { return validator_desc; }) {} + /// Construct Validator from basic information + Validator(std::function op, std::string validator_desc, std::string validator_name = "") + : desc_function_([validator_desc]() { return validator_desc; }), func_(std::move(op)), + name_(std::move(validator_name)) {} + /// Set the Validator operation function + Validator &operation(std::function op) { + func_ = std::move(op); + return *this; + } + /// This is the required operator for a Validator - provided to help + /// users (CLI11 uses the member `func` directly) + std::string operator()(std::string &str) const { + std::string retstring; + if(active_) { + if(non_modifying_) { + std::string value = str; + retstring = func_(value); + } else { + retstring = func_(str); + } + } + return retstring; + } + + /// This is the required operator for a Validator - provided to help + /// users (CLI11 uses the member `func` directly) + std::string operator()(const std::string &str) const { + std::string value = str; + return (active_) ? func_(value) : std::string{}; + } + + /// Specify the type string + Validator &description(std::string validator_desc) { + desc_function_ = [validator_desc]() { return validator_desc; }; + return *this; + } + /// Specify the type string + Validator description(std::string validator_desc) const { + Validator newval(*this); + newval.desc_function_ = [validator_desc]() { return validator_desc; }; + return newval; + } + /// Generate type description information for the Validator + std::string get_description() const { + if(active_) { + return desc_function_(); + } + return std::string{}; + } + /// Specify the type string + Validator &name(std::string validator_name) { + name_ = std::move(validator_name); + return *this; + } + /// Specify the type string + Validator name(std::string validator_name) const { + Validator newval(*this); + newval.name_ = std::move(validator_name); + return newval; + } + /// Get the name of the Validator + const std::string &get_name() const { return name_; } + /// Specify whether the Validator is active or not + Validator &active(bool active_val = true) { + active_ = active_val; + return *this; + } + /// Specify whether the Validator is active or not + Validator active(bool active_val = true) const { + Validator newval(*this); + newval.active_ = active_val; + return newval; + } + + /// Specify whether the Validator can be modifying or not + Validator &non_modifying(bool no_modify = true) { + non_modifying_ = no_modify; + return *this; + } + /// Specify the application index of a validator + Validator &application_index(int app_index) { + application_index_ = app_index; + return *this; + } + /// Specify the application index of a validator + Validator application_index(int app_index) const { + Validator newval(*this); + newval.application_index_ = app_index; + return newval; + } + /// Get the current value of the application index + int get_application_index() const { return application_index_; } + /// Get a boolean if the validator is active + bool get_active() const { return active_; } + + /// Get a boolean if the validator is allowed to modify the input returns true if it can modify the input + bool get_modifying() const { return !non_modifying_; } + + /// Combining validators is a new validator. Type comes from left validator if function, otherwise only set if the + /// same. + Validator operator&(const Validator &other) const { + Validator newval; + + newval._merge_description(*this, other, " AND "); + + // Give references (will make a copy in lambda function) + const std::function &f1 = func_; + const std::function &f2 = other.func_; + + newval.func_ = [f1, f2](std::string &input) { + std::string s1 = f1(input); + std::string s2 = f2(input); + if(!s1.empty() && !s2.empty()) + return std::string("(") + s1 + ") AND (" + s2 + ")"; + else + return s1 + s2; + }; + + newval.active_ = (active_ & other.active_); + newval.application_index_ = application_index_; + return newval; + } + + /// Combining validators is a new validator. Type comes from left validator if function, otherwise only set if the + /// same. + Validator operator|(const Validator &other) const { + Validator newval; + + newval._merge_description(*this, other, " OR "); + + // Give references (will make a copy in lambda function) + const std::function &f1 = func_; + const std::function &f2 = other.func_; + + newval.func_ = [f1, f2](std::string &input) { + std::string s1 = f1(input); + std::string s2 = f2(input); + if(s1.empty() || s2.empty()) + return std::string(); + + return std::string("(") + s1 + ") OR (" + s2 + ")"; + }; + newval.active_ = (active_ & other.active_); + newval.application_index_ = application_index_; + return newval; + } + + /// Create a validator that fails when a given validator succeeds + Validator operator!() const { + Validator newval; + const std::function &dfunc1 = desc_function_; + newval.desc_function_ = [dfunc1]() { + auto str = dfunc1(); + return (!str.empty()) ? std::string("NOT ") + str : std::string{}; + }; + // Give references (will make a copy in lambda function) + const std::function &f1 = func_; + + newval.func_ = [f1, dfunc1](std::string &test) -> std::string { + std::string s1 = f1(test); + if(s1.empty()) { + return std::string("check ") + dfunc1() + " succeeded improperly"; + } + return std::string{}; + }; + newval.active_ = active_; + newval.application_index_ = application_index_; + return newval; + } + + private: + void _merge_description(const Validator &val1, const Validator &val2, const std::string &merger) { + + const std::function &dfunc1 = val1.desc_function_; + const std::function &dfunc2 = val2.desc_function_; + + desc_function_ = [=]() { + std::string f1 = dfunc1(); + std::string f2 = dfunc2(); + if((f1.empty()) || (f2.empty())) { + return f1 + f2; + } + return std::string(1, '(') + f1 + ')' + merger + '(' + f2 + ')'; + }; + } +}; // namespace CLI + +/// Class wrapping some of the accessors of Validator +class CustomValidator : public Validator { + public: +}; +// The implementation of the built in validators is using the Validator class; +// the user is only expected to use the const (static) versions (since there's no setup). +// Therefore, this is in detail. +namespace detail { + +/// CLI enumeration of different file types +enum class path_type { nonexistent, file, directory }; + +#if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0 +/// get the type of the path from a file name +inline path_type check_path(const char *file) noexcept { + std::error_code ec; + auto stat = std::filesystem::status(file, ec); + if(ec) { + return path_type::nonexistent; + } + switch(stat.type()) { + case std::filesystem::file_type::none: + case std::filesystem::file_type::not_found: + return path_type::nonexistent; + case std::filesystem::file_type::directory: + return path_type::directory; + case std::filesystem::file_type::symlink: + case std::filesystem::file_type::block: + case std::filesystem::file_type::character: + case std::filesystem::file_type::fifo: + case std::filesystem::file_type::socket: + case std::filesystem::file_type::regular: + case std::filesystem::file_type::unknown: + default: + return path_type::file; + } +} +#else +/// get the type of the path from a file name +inline path_type check_path(const char *file) noexcept { +#if defined(_MSC_VER) + struct __stat64 buffer; + if(_stat64(file, &buffer) == 0) { + return ((buffer.st_mode & S_IFDIR) != 0) ? path_type::directory : path_type::file; + } +#else + struct stat buffer; + if(stat(file, &buffer) == 0) { + return ((buffer.st_mode & S_IFDIR) != 0) ? path_type::directory : path_type::file; + } +#endif + return path_type::nonexistent; +} +#endif +/// Check for an existing file (returns error message if check fails) +class ExistingFileValidator : public Validator { + public: + ExistingFileValidator() : Validator("FILE") { + func_ = [](std::string &filename) { + auto path_result = check_path(filename.c_str()); + if(path_result == path_type::nonexistent) { + return "File does not exist: " + filename; + } + if(path_result == path_type::directory) { + return "File is actually a directory: " + filename; + } + return std::string(); + }; + } +}; + +/// Check for an existing directory (returns error message if check fails) +class ExistingDirectoryValidator : public Validator { + public: + ExistingDirectoryValidator() : Validator("DIR") { + func_ = [](std::string &filename) { + auto path_result = check_path(filename.c_str()); + if(path_result == path_type::nonexistent) { + return "Directory does not exist: " + filename; + } + if(path_result == path_type::file) { + return "Directory is actually a file: " + filename; + } + return std::string(); + }; + } +}; + +/// Check for an existing path +class ExistingPathValidator : public Validator { + public: + ExistingPathValidator() : Validator("PATH(existing)") { + func_ = [](std::string &filename) { + auto path_result = check_path(filename.c_str()); + if(path_result == path_type::nonexistent) { + return "Path does not exist: " + filename; + } + return std::string(); + }; + } +}; + +/// Check for an non-existing path +class NonexistentPathValidator : public Validator { + public: + NonexistentPathValidator() : Validator("PATH(non-existing)") { + func_ = [](std::string &filename) { + auto path_result = check_path(filename.c_str()); + if(path_result != path_type::nonexistent) { + return "Path already exists: " + filename; + } + return std::string(); + }; + } +}; + +/// Validate the given string is a legal ipv4 address +class IPV4Validator : public Validator { + public: + IPV4Validator() : Validator("IPV4") { + func_ = [](std::string &ip_addr) { + auto result = CLI::detail::split(ip_addr, '.'); + if(result.size() != 4) { + return std::string("Invalid IPV4 address must have four parts (") + ip_addr + ')'; + } + int num; + for(const auto &var : result) { + bool retval = detail::lexical_cast(var, num); + if(!retval) { + return std::string("Failed parsing number (") + var + ')'; + } + if(num < 0 || num > 255) { + return std::string("Each IP number must be between 0 and 255 ") + var; + } + } + return std::string(); + }; + } +}; + +} // namespace detail + +// Static is not needed here, because global const implies static. + +/// Check for existing file (returns error message if check fails) +const detail::ExistingFileValidator ExistingFile; + +/// Check for an existing directory (returns error message if check fails) +const detail::ExistingDirectoryValidator ExistingDirectory; + +/// Check for an existing path +const detail::ExistingPathValidator ExistingPath; + +/// Check for an non-existing path +const detail::NonexistentPathValidator NonexistentPath; + +/// Check for an IP4 address +const detail::IPV4Validator ValidIPV4; + +/// Validate the input as a particular type +template class TypeValidator : public Validator { + public: + explicit TypeValidator(const std::string &validator_name) : Validator(validator_name) { + func_ = [](std::string &input_string) { + auto val = DesiredType(); + if(!detail::lexical_cast(input_string, val)) { + return std::string("Failed parsing ") + input_string + " as a " + detail::type_name(); + } + return std::string(); + }; + } + TypeValidator() : TypeValidator(detail::type_name()) {} +}; + +/// Check for a number +const TypeValidator Number("NUMBER"); + +/// Modify a path if the file is a particular default location, can be used as Check or transform +/// with the error return optionally disabled +class FileOnDefaultPath : public Validator { + public: + explicit FileOnDefaultPath(std::string default_path, bool enableErrorReturn = true) : Validator("FILE") { + func_ = [default_path, enableErrorReturn](std::string &filename) { + auto path_result = detail::check_path(filename.c_str()); + if(path_result == detail::path_type::nonexistent) { + std::string test_file_path = default_path; + if(default_path.back() != '/' && default_path.back() != '\\') { + // Add folder separator + test_file_path += '/'; + } + test_file_path.append(filename); + path_result = detail::check_path(test_file_path.c_str()); + if(path_result == detail::path_type::file) { + filename = test_file_path; + } else { + if(enableErrorReturn) { + return "File does not exist: " + filename; + } + } + } + return std::string{}; + }; + } +}; + +/// Produce a range (factory). Min and max are inclusive. +class Range : public Validator { + public: + /// This produces a range with min and max inclusive. + /// + /// Note that the constructor is templated, but the struct is not, so C++17 is not + /// needed to provide nice syntax for Range(a,b). + template + Range(T min_val, T max_val, const std::string &validator_name = std::string{}) : Validator(validator_name) { + if(validator_name.empty()) { + std::stringstream out; + out << detail::type_name() << " in [" << min_val << " - " << max_val << "]"; + description(out.str()); + } + + func_ = [min_val, max_val](std::string &input) { + T val; + bool converted = detail::lexical_cast(input, val); + if((!converted) || (val < min_val || val > max_val)) { + std::stringstream out; + out << "Value " << input << " not in range ["; + out << min_val << " - " << max_val << "]"; + return out.str(); + } + return std::string{}; + }; + } + + /// Range of one value is 0 to value + template + explicit Range(T max_val, const std::string &validator_name = std::string{}) + : Range(static_cast(0), max_val, validator_name) {} +}; + +/// Check for a non negative number +const Range NonNegativeNumber((std::numeric_limits::max)(), "NONNEGATIVE"); + +/// Check for a positive valued number (val>0.0), min() her is the smallest positive number +const Range PositiveNumber((std::numeric_limits::min)(), (std::numeric_limits::max)(), "POSITIVE"); + +/// Produce a bounded range (factory). Min and max are inclusive. +class Bound : public Validator { + public: + /// This bounds a value with min and max inclusive. + /// + /// Note that the constructor is templated, but the struct is not, so C++17 is not + /// needed to provide nice syntax for Range(a,b). + template Bound(T min_val, T max_val) { + std::stringstream out; + out << detail::type_name() << " bounded to [" << min_val << " - " << max_val << "]"; + description(out.str()); + + func_ = [min_val, max_val](std::string &input) { + T val; + bool converted = detail::lexical_cast(input, val); + if(!converted) { + return std::string("Value ") + input + " could not be converted"; + } + if(val < min_val) + input = detail::to_string(min_val); + else if(val > max_val) + input = detail::to_string(max_val); + + return std::string{}; + }; + } + + /// Range of one value is 0 to value + template explicit Bound(T max_val) : Bound(static_cast(0), max_val) {} +}; + +namespace detail { +template ::type>::value, detail::enabler> = detail::dummy> +auto smart_deref(T value) -> decltype(*value) { + return *value; +} + +template < + typename T, + enable_if_t::type>::value, detail::enabler> = detail::dummy> +typename std::remove_reference::type &smart_deref(T &value) { + return value; +} +/// Generate a string representation of a set +template std::string generate_set(const T &set) { + using element_t = typename detail::element_type::type; + using iteration_type_t = typename detail::pair_adaptor::value_type; // the type of the object pair + std::string out(1, '{'); + out.append(detail::join( + detail::smart_deref(set), + [](const iteration_type_t &v) { return detail::pair_adaptor::first(v); }, + ",")); + out.push_back('}'); + return out; +} + +/// Generate a string representation of a map +template std::string generate_map(const T &map, bool key_only = false) { + using element_t = typename detail::element_type::type; + using iteration_type_t = typename detail::pair_adaptor::value_type; // the type of the object pair + std::string out(1, '{'); + out.append(detail::join( + detail::smart_deref(map), + [key_only](const iteration_type_t &v) { + std::string res{detail::to_string(detail::pair_adaptor::first(v))}; + + if(!key_only) { + res.append("->"); + res += detail::to_string(detail::pair_adaptor::second(v)); + } + return res; + }, + ",")); + out.push_back('}'); + return out; +} + +template struct has_find { + template + static auto test(int) -> decltype(std::declval().find(std::declval()), std::true_type()); + template static auto test(...) -> decltype(std::false_type()); + + static const auto value = decltype(test(0))::value; + using type = std::integral_constant; +}; + +/// A search function +template ::value, detail::enabler> = detail::dummy> +auto search(const T &set, const V &val) -> std::pair { + using element_t = typename detail::element_type::type; + auto &setref = detail::smart_deref(set); + auto it = std::find_if(std::begin(setref), std::end(setref), [&val](decltype(*std::begin(setref)) v) { + return (detail::pair_adaptor::first(v) == val); + }); + return {(it != std::end(setref)), it}; +} + +/// A search function that uses the built in find function +template ::value, detail::enabler> = detail::dummy> +auto search(const T &set, const V &val) -> std::pair { + auto &setref = detail::smart_deref(set); + auto it = setref.find(val); + return {(it != std::end(setref)), it}; +} + +/// A search function with a filter function +template +auto search(const T &set, const V &val, const std::function &filter_function) + -> std::pair { + using element_t = typename detail::element_type::type; + // do the potentially faster first search + auto res = search(set, val); + if((res.first) || (!(filter_function))) { + return res; + } + // if we haven't found it do the longer linear search with all the element translations + auto &setref = detail::smart_deref(set); + auto it = std::find_if(std::begin(setref), std::end(setref), [&](decltype(*std::begin(setref)) v) { + V a{detail::pair_adaptor::first(v)}; + a = filter_function(a); + return (a == val); + }); + return {(it != std::end(setref)), it}; +} + +// the following suggestion was made by Nikita Ofitserov(@himikof) +// done in templates to prevent compiler warnings on negation of unsigned numbers + +/// Do a check for overflow on signed numbers +template +inline typename std::enable_if::value, T>::type overflowCheck(const T &a, const T &b) { + if((a > 0) == (b > 0)) { + return ((std::numeric_limits::max)() / (std::abs)(a) < (std::abs)(b)); + } else { + return ((std::numeric_limits::min)() / (std::abs)(a) > -(std::abs)(b)); + } +} +/// Do a check for overflow on unsigned numbers +template +inline typename std::enable_if::value, T>::type overflowCheck(const T &a, const T &b) { + return ((std::numeric_limits::max)() / a < b); +} + +/// Performs a *= b; if it doesn't cause integer overflow. Returns false otherwise. +template typename std::enable_if::value, bool>::type checked_multiply(T &a, T b) { + if(a == 0 || b == 0 || a == 1 || b == 1) { + a *= b; + return true; + } + if(a == (std::numeric_limits::min)() || b == (std::numeric_limits::min)()) { + return false; + } + if(overflowCheck(a, b)) { + return false; + } + a *= b; + return true; +} + +/// Performs a *= b; if it doesn't equal infinity. Returns false otherwise. +template +typename std::enable_if::value, bool>::type checked_multiply(T &a, T b) { + T c = a * b; + if(std::isinf(c) && !std::isinf(a) && !std::isinf(b)) { + return false; + } + a = c; + return true; +} + +} // namespace detail +/// Verify items are in a set +class IsMember : public Validator { + public: + using filter_fn_t = std::function; + + /// This allows in-place construction using an initializer list + template + IsMember(std::initializer_list values, Args &&...args) + : IsMember(std::vector(values), std::forward(args)...) {} + + /// This checks to see if an item is in a set (empty function) + template explicit IsMember(T &&set) : IsMember(std::forward(set), nullptr) {} + + /// This checks to see if an item is in a set: pointer or copy version. You can pass in a function that will filter + /// both sides of the comparison before computing the comparison. + template explicit IsMember(T set, F filter_function) { + + // Get the type of the contained item - requires a container have ::value_type + // if the type does not have first_type and second_type, these are both value_type + using element_t = typename detail::element_type::type; // Removes (smart) pointers if needed + using item_t = typename detail::pair_adaptor::first_type; // Is value_type if not a map + + using local_item_t = typename IsMemberType::type; // This will convert bad types to good ones + // (const char * to std::string) + + // Make a local copy of the filter function, using a std::function if not one already + std::function filter_fn = filter_function; + + // This is the type name for help, it will take the current version of the set contents + desc_function_ = [set]() { return detail::generate_set(detail::smart_deref(set)); }; + + // This is the function that validates + // It stores a copy of the set pointer-like, so shared_ptr will stay alive + func_ = [set, filter_fn](std::string &input) { + local_item_t b; + if(!detail::lexical_cast(input, b)) { + throw ValidationError(input); // name is added later + } + if(filter_fn) { + b = filter_fn(b); + } + auto res = detail::search(set, b, filter_fn); + if(res.first) { + // Make sure the version in the input string is identical to the one in the set + if(filter_fn) { + input = detail::value_string(detail::pair_adaptor::first(*(res.second))); + } + + // Return empty error string (success) + return std::string{}; + } + + // If you reach this point, the result was not found + return input + " not in " + detail::generate_set(detail::smart_deref(set)); + }; + } + + /// You can pass in as many filter functions as you like, they nest (string only currently) + template + IsMember(T &&set, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&...other) + : IsMember( + std::forward(set), + [filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); }, + other...) {} +}; + +/// definition of the default transformation object +template using TransformPairs = std::vector>; + +/// Translate named items to other or a value set +class Transformer : public Validator { + public: + using filter_fn_t = std::function; + + /// This allows in-place construction + template + Transformer(std::initializer_list> values, Args &&...args) + : Transformer(TransformPairs(values), std::forward(args)...) {} + + /// direct map of std::string to std::string + template explicit Transformer(T &&mapping) : Transformer(std::forward(mapping), nullptr) {} + + /// This checks to see if an item is in a set: pointer or copy version. You can pass in a function that will filter + /// both sides of the comparison before computing the comparison. + template explicit Transformer(T mapping, F filter_function) { + + static_assert(detail::pair_adaptor::type>::value, + "mapping must produce value pairs"); + // Get the type of the contained item - requires a container have ::value_type + // if the type does not have first_type and second_type, these are both value_type + using element_t = typename detail::element_type::type; // Removes (smart) pointers if needed + using item_t = typename detail::pair_adaptor::first_type; // Is value_type if not a map + using local_item_t = typename IsMemberType::type; // Will convert bad types to good ones + // (const char * to std::string) + + // Make a local copy of the filter function, using a std::function if not one already + std::function filter_fn = filter_function; + + // This is the type name for help, it will take the current version of the set contents + desc_function_ = [mapping]() { return detail::generate_map(detail::smart_deref(mapping)); }; + + func_ = [mapping, filter_fn](std::string &input) { + local_item_t b; + if(!detail::lexical_cast(input, b)) { + return std::string(); + // there is no possible way we can match anything in the mapping if we can't convert so just return + } + if(filter_fn) { + b = filter_fn(b); + } + auto res = detail::search(mapping, b, filter_fn); + if(res.first) { + input = detail::value_string(detail::pair_adaptor::second(*res.second)); + } + return std::string{}; + }; + } + + /// You can pass in as many filter functions as you like, they nest + template + Transformer(T &&mapping, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&...other) + : Transformer( + std::forward(mapping), + [filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); }, + other...) {} +}; + +/// translate named items to other or a value set +class CheckedTransformer : public Validator { + public: + using filter_fn_t = std::function; + + /// This allows in-place construction + template + CheckedTransformer(std::initializer_list> values, Args &&...args) + : CheckedTransformer(TransformPairs(values), std::forward(args)...) {} + + /// direct map of std::string to std::string + template explicit CheckedTransformer(T mapping) : CheckedTransformer(std::move(mapping), nullptr) {} + + /// This checks to see if an item is in a set: pointer or copy version. You can pass in a function that will filter + /// both sides of the comparison before computing the comparison. + template explicit CheckedTransformer(T mapping, F filter_function) { + + static_assert(detail::pair_adaptor::type>::value, + "mapping must produce value pairs"); + // Get the type of the contained item - requires a container have ::value_type + // if the type does not have first_type and second_type, these are both value_type + using element_t = typename detail::element_type::type; // Removes (smart) pointers if needed + using item_t = typename detail::pair_adaptor::first_type; // Is value_type if not a map + using local_item_t = typename IsMemberType::type; // Will convert bad types to good ones + // (const char * to std::string) + using iteration_type_t = typename detail::pair_adaptor::value_type; // the type of the object pair + + // Make a local copy of the filter function, using a std::function if not one already + std::function filter_fn = filter_function; + + auto tfunc = [mapping]() { + std::string out("value in "); + out += detail::generate_map(detail::smart_deref(mapping)) + " OR {"; + out += detail::join( + detail::smart_deref(mapping), + [](const iteration_type_t &v) { return detail::to_string(detail::pair_adaptor::second(v)); }, + ","); + out.push_back('}'); + return out; + }; + + desc_function_ = tfunc; + + func_ = [mapping, tfunc, filter_fn](std::string &input) { + local_item_t b; + bool converted = detail::lexical_cast(input, b); + if(converted) { + if(filter_fn) { + b = filter_fn(b); + } + auto res = detail::search(mapping, b, filter_fn); + if(res.first) { + input = detail::value_string(detail::pair_adaptor::second(*res.second)); + return std::string{}; + } + } + for(const auto &v : detail::smart_deref(mapping)) { + auto output_string = detail::value_string(detail::pair_adaptor::second(v)); + if(output_string == input) { + return std::string(); + } + } + + return "Check " + input + " " + tfunc() + " FAILED"; + }; + } + + /// You can pass in as many filter functions as you like, they nest + template + CheckedTransformer(T &&mapping, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&...other) + : CheckedTransformer( + std::forward(mapping), + [filter_fn_1, filter_fn_2](std::string a) { return filter_fn_2(filter_fn_1(a)); }, + other...) {} +}; + +/// Helper function to allow ignore_case to be passed to IsMember or Transform +inline std::string ignore_case(std::string item) { return detail::to_lower(item); } + +/// Helper function to allow ignore_underscore to be passed to IsMember or Transform +inline std::string ignore_underscore(std::string item) { return detail::remove_underscore(item); } + +/// Helper function to allow checks to ignore spaces to be passed to IsMember or Transform +inline std::string ignore_space(std::string item) { + item.erase(std::remove(std::begin(item), std::end(item), ' '), std::end(item)); + item.erase(std::remove(std::begin(item), std::end(item), '\t'), std::end(item)); + return item; +} + +/// Multiply a number by a factor using given mapping. +/// Can be used to write transforms for SIZE or DURATION inputs. +/// +/// Example: +/// With mapping = `{"b"->1, "kb"->1024, "mb"->1024*1024}` +/// one can recognize inputs like "100", "12kb", "100 MB", +/// that will be automatically transformed to 100, 14448, 104857600. +/// +/// Output number type matches the type in the provided mapping. +/// Therefore, if it is required to interpret real inputs like "0.42 s", +/// the mapping should be of a type or . +class AsNumberWithUnit : public Validator { + public: + /// Adjust AsNumberWithUnit behavior. + /// CASE_SENSITIVE/CASE_INSENSITIVE controls how units are matched. + /// UNIT_OPTIONAL/UNIT_REQUIRED throws ValidationError + /// if UNIT_REQUIRED is set and unit literal is not found. + enum Options { + CASE_SENSITIVE = 0, + CASE_INSENSITIVE = 1, + UNIT_OPTIONAL = 0, + UNIT_REQUIRED = 2, + DEFAULT = CASE_INSENSITIVE | UNIT_OPTIONAL + }; + + template + explicit AsNumberWithUnit(std::map mapping, + Options opts = DEFAULT, + const std::string &unit_name = "UNIT") { + description(generate_description(unit_name, opts)); + validate_mapping(mapping, opts); + + // transform function + func_ = [mapping, opts](std::string &input) -> std::string { + Number num; + + detail::rtrim(input); + if(input.empty()) { + throw ValidationError("Input is empty"); + } + + // Find split position between number and prefix + auto unit_begin = input.end(); + while(unit_begin > input.begin() && std::isalpha(*(unit_begin - 1), std::locale())) { + --unit_begin; + } + + std::string unit{unit_begin, input.end()}; + input.resize(static_cast(std::distance(input.begin(), unit_begin))); + detail::trim(input); + + if(opts & UNIT_REQUIRED && unit.empty()) { + throw ValidationError("Missing mandatory unit"); + } + if(opts & CASE_INSENSITIVE) { + unit = detail::to_lower(unit); + } + if(unit.empty()) { + if(!detail::lexical_cast(input, num)) { + throw ValidationError(std::string("Value ") + input + " could not be converted to " + + detail::type_name()); + } + // No need to modify input if no unit passed + return {}; + } + + // find corresponding factor + auto it = mapping.find(unit); + if(it == mapping.end()) { + throw ValidationError(unit + + " unit not recognized. " + "Allowed values: " + + detail::generate_map(mapping, true)); + } + + if(!input.empty()) { + bool converted = detail::lexical_cast(input, num); + if(!converted) { + throw ValidationError(std::string("Value ") + input + " could not be converted to " + + detail::type_name()); + } + // perform safe multiplication + bool ok = detail::checked_multiply(num, it->second); + if(!ok) { + throw ValidationError(detail::to_string(num) + " multiplied by " + unit + + " factor would cause number overflow. Use smaller value."); + } + } else { + num = static_cast(it->second); + } + + input = detail::to_string(num); + + return {}; + }; + } + + private: + /// Check that mapping contains valid units. + /// Update mapping for CASE_INSENSITIVE mode. + template static void validate_mapping(std::map &mapping, Options opts) { + for(auto &kv : mapping) { + if(kv.first.empty()) { + throw ValidationError("Unit must not be empty."); + } + if(!detail::isalpha(kv.first)) { + throw ValidationError("Unit must contain only letters."); + } + } + + // make all units lowercase if CASE_INSENSITIVE + if(opts & CASE_INSENSITIVE) { + std::map lower_mapping; + for(auto &kv : mapping) { + auto s = detail::to_lower(kv.first); + if(lower_mapping.count(s)) { + throw ValidationError(std::string("Several matching lowercase unit representations are found: ") + + s); + } + lower_mapping[detail::to_lower(kv.first)] = kv.second; + } + mapping = std::move(lower_mapping); + } + } + + /// Generate description like this: NUMBER [UNIT] + template static std::string generate_description(const std::string &name, Options opts) { + std::stringstream out; + out << detail::type_name() << ' '; + if(opts & UNIT_REQUIRED) { + out << name; + } else { + out << '[' << name << ']'; + } + return out.str(); + } +}; + +/// Converts a human-readable size string (with unit literal) to uin64_t size. +/// Example: +/// "100" => 100 +/// "1 b" => 100 +/// "10Kb" => 10240 // you can configure this to be interpreted as kilobyte (*1000) or kibibyte (*1024) +/// "10 KB" => 10240 +/// "10 kb" => 10240 +/// "10 kib" => 10240 // *i, *ib are always interpreted as *bibyte (*1024) +/// "10kb" => 10240 +/// "2 MB" => 2097152 +/// "2 EiB" => 2^61 // Units up to exibyte are supported +class AsSizeValue : public AsNumberWithUnit { + public: + using result_t = std::uint64_t; + + /// If kb_is_1000 is true, + /// interpret 'kb', 'k' as 1000 and 'kib', 'ki' as 1024 + /// (same applies to higher order units as well). + /// Otherwise, interpret all literals as factors of 1024. + /// The first option is formally correct, but + /// the second interpretation is more wide-spread + /// (see https://en.wikipedia.org/wiki/Binary_prefix). + explicit AsSizeValue(bool kb_is_1000) : AsNumberWithUnit(get_mapping(kb_is_1000)) { + if(kb_is_1000) { + description("SIZE [b, kb(=1000b), kib(=1024b), ...]"); + } else { + description("SIZE [b, kb(=1024b), ...]"); + } + } + + private: + /// Get mapping + static std::map init_mapping(bool kb_is_1000) { + std::map m; + result_t k_factor = kb_is_1000 ? 1000 : 1024; + result_t ki_factor = 1024; + result_t k = 1; + result_t ki = 1; + m["b"] = 1; + for(std::string p : {"k", "m", "g", "t", "p", "e"}) { + k *= k_factor; + ki *= ki_factor; + m[p] = k; + m[p + "b"] = k; + m[p + "i"] = ki; + m[p + "ib"] = ki; + } + return m; + } + + /// Cache calculated mapping + static std::map get_mapping(bool kb_is_1000) { + if(kb_is_1000) { + static auto m = init_mapping(true); + return m; + } else { + static auto m = init_mapping(false); + return m; + } + } +}; + +namespace detail { +/// Split a string into a program name and command line arguments +/// the string is assumed to contain a file name followed by other arguments +/// the return value contains is a pair with the first argument containing the program name and the second +/// everything else. +inline std::pair split_program_name(std::string commandline) { + // try to determine the programName + std::pair vals; + trim(commandline); + auto esp = commandline.find_first_of(' ', 1); + while(detail::check_path(commandline.substr(0, esp).c_str()) != path_type::file) { + esp = commandline.find_first_of(' ', esp + 1); + if(esp == std::string::npos) { + // if we have reached the end and haven't found a valid file just assume the first argument is the + // program name + if(commandline[0] == '"' || commandline[0] == '\'' || commandline[0] == '`') { + bool embeddedQuote = false; + auto keyChar = commandline[0]; + auto end = commandline.find_first_of(keyChar, 1); + while((end != std::string::npos) && (commandline[end - 1] == '\\')) { // deal with escaped quotes + end = commandline.find_first_of(keyChar, end + 1); + embeddedQuote = true; + } + if(end != std::string::npos) { + vals.first = commandline.substr(1, end - 1); + esp = end + 1; + if(embeddedQuote) { + vals.first = find_and_replace(vals.first, std::string("\\") + keyChar, std::string(1, keyChar)); + } + } else { + esp = commandline.find_first_of(' ', 1); + } + } else { + esp = commandline.find_first_of(' ', 1); + } + + break; + } + } + if(vals.first.empty()) { + vals.first = commandline.substr(0, esp); + rtrim(vals.first); + } + + // strip the program name + vals.second = (esp != std::string::npos) ? commandline.substr(esp + 1) : std::string{}; + ltrim(vals.second); + return vals; +} + +} // namespace detail +/// @} + + + + +class Option; +class App; + +/// This enum signifies the type of help requested +/// +/// This is passed in by App; all user classes must accept this as +/// the second argument. + +enum class AppFormatMode { + Normal, ///< The normal, detailed help + All, ///< A fully expanded help + Sub, ///< Used when printed as part of expanded subcommand +}; + +/// This is the minimum requirements to run a formatter. +/// +/// A user can subclass this is if they do not care at all +/// about the structure in CLI::Formatter. +class FormatterBase { + protected: + /// @name Options + ///@{ + + /// The width of the first column + std::size_t column_width_{30}; + + /// @brief The required help printout labels (user changeable) + /// Values are Needs, Excludes, etc. + std::map labels_{}; + + ///@} + /// @name Basic + ///@{ + + public: + FormatterBase() = default; + FormatterBase(const FormatterBase &) = default; + FormatterBase(FormatterBase &&) = default; + + /// Adding a destructor in this form to work around bug in GCC 4.7 + virtual ~FormatterBase() noexcept {} // NOLINT(modernize-use-equals-default) + + /// This is the key method that puts together help + virtual std::string make_help(const App *, std::string, AppFormatMode) const = 0; + + ///@} + /// @name Setters + ///@{ + + /// Set the "REQUIRED" label + void label(std::string key, std::string val) { labels_[key] = val; } + + /// Set the column width + void column_width(std::size_t val) { column_width_ = val; } + + ///@} + /// @name Getters + ///@{ + + /// Get the current value of a name (REQUIRED, etc.) + std::string get_label(std::string key) const { + if(labels_.find(key) == labels_.end()) + return key; + else + return labels_.at(key); + } + + /// Get the current column width + std::size_t get_column_width() const { return column_width_; } + + ///@} +}; + +/// This is a specialty override for lambda functions +class FormatterLambda final : public FormatterBase { + using funct_t = std::function; + + /// The lambda to hold and run + funct_t lambda_; + + public: + /// Create a FormatterLambda with a lambda function + explicit FormatterLambda(funct_t funct) : lambda_(std::move(funct)) {} + + /// Adding a destructor (mostly to make GCC 4.7 happy) + ~FormatterLambda() noexcept override {} // NOLINT(modernize-use-equals-default) + + /// This will simply call the lambda function + std::string make_help(const App *app, std::string name, AppFormatMode mode) const override { + return lambda_(app, name, mode); + } +}; + +/// This is the default Formatter for CLI11. It pretty prints help output, and is broken into quite a few +/// overridable methods, to be highly customizable with minimal effort. +class Formatter : public FormatterBase { + public: + Formatter() = default; + Formatter(const Formatter &) = default; + Formatter(Formatter &&) = default; + + /// @name Overridables + ///@{ + + /// This prints out a group of options with title + /// + virtual std::string make_group(std::string group, bool is_positional, std::vector opts) const; + + /// This prints out just the positionals "group" + virtual std::string make_positionals(const App *app) const; + + /// This prints out all the groups of options + std::string make_groups(const App *app, AppFormatMode mode) const; + + /// This prints out all the subcommands + virtual std::string make_subcommands(const App *app, AppFormatMode mode) const; + + /// This prints out a subcommand + virtual std::string make_subcommand(const App *sub) const; + + /// This prints out a subcommand in help-all + virtual std::string make_expanded(const App *sub) const; + + /// This prints out all the groups of options + virtual std::string make_footer(const App *app) const; + + /// This displays the description line + virtual std::string make_description(const App *app) const; + + /// This displays the usage line + virtual std::string make_usage(const App *app, std::string name) const; + + /// This puts everything together + std::string make_help(const App * /*app*/, std::string, AppFormatMode) const override; + + ///@} + /// @name Options + ///@{ + + /// This prints out an option help line, either positional or optional form + virtual std::string make_option(const Option *opt, bool is_positional) const { + std::stringstream out; + detail::format_help( + out, make_option_name(opt, is_positional) + make_option_opts(opt), make_option_desc(opt), column_width_); + return out.str(); + } + + /// @brief This is the name part of an option, Default: left column + virtual std::string make_option_name(const Option *, bool) const; + + /// @brief This is the options part of the name, Default: combined into left column + virtual std::string make_option_opts(const Option *) const; + + /// @brief This is the description. Default: Right column, on new line if left column too large + virtual std::string make_option_desc(const Option *) const; + + /// @brief This is used to print the name on the USAGE line + virtual std::string make_option_usage(const Option *opt) const; + + ///@} +}; + + + + +using results_t = std::vector; +/// callback function definition +using callback_t = std::function; + +class Option; +class App; + +using Option_p = std::unique_ptr