From a81aef889a4e2d4ae63352fcbec110cf1ac0c138 Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Wed, 30 Jun 2021 19:20:31 -0400 Subject: [PATCH] Level load test (#656) * tweaks for loading VI1 * temp * clean up --- common/goos/Interpreter.cpp | 20 ++++++++ common/goos/Interpreter.h | 3 ++ decompiler/ObjectFile/ObjectFileDB.cpp | 3 ++ game/fake_iso.txt | 3 +- game/kernel/klink.cpp | 10 ++-- game/sce/stubs.cpp | 4 +- goal_src/engine/game/main.gc | 5 ++ goal_src/engine/gfx/texture.gc | 8 +++ goal_src/engine/level/level-h.gc | 2 +- goal_src/engine/level/level.gc | 67 +++++++++++++++++++++++--- goal_src/engine/load/file-io.gc | 4 +- goal_src/engine/util/types-h.gc | 14 ++++++ goal_src/goal-lib.gc | 4 +- goalc/compiler/compilation/Debug.cpp | 1 + goalc/debugger/Debugger.cpp | 20 ++++++++ goalc/debugger/Debugger.h | 1 + 16 files changed, 150 insertions(+), 19 deletions(-) diff --git a/common/goos/Interpreter.cpp b/common/goos/Interpreter.cpp index 1df0e5883..990ff4fba 100644 --- a/common/goos/Interpreter.cpp +++ b/common/goos/Interpreter.cpp @@ -71,6 +71,7 @@ Interpreter::Interpreter() { {"error", &Interpreter::eval_error}, {"string-ref", &Interpreter::eval_string_ref}, {"string-length", &Interpreter::eval_string_length}, + {"string-append", &Interpreter::eval_string_append}, {"ash", &Interpreter::eval_ash}}; string_to_type = {{"empty-list", ObjectType::EMPTY_LIST}, @@ -1556,6 +1557,25 @@ Object Interpreter::eval_string_length(const Object& form, return Object::make_integer(str->data.length()); } +Object Interpreter::eval_string_append(const Object& form, + Arguments& args, + const std::shared_ptr& env) { + (void)env; + if (!args.named.empty()) { + throw_eval_error(form, "string-append does not accept named arguments"); + } + + std::string result; + for (auto& arg : args.unnamed) { + if (!arg.is_string()) { + throw_eval_error(form, "string-append can only operate on strings"); + } + result += arg.as_string()->data; + } + + return StringObject::make_new(result); +} + Object Interpreter::eval_ash(const Object& form, Arguments& args, const std::shared_ptr& env) { diff --git a/common/goos/Interpreter.h b/common/goos/Interpreter.h index 16a4f50e6..db8225801 100644 --- a/common/goos/Interpreter.h +++ b/common/goos/Interpreter.h @@ -192,6 +192,9 @@ class Interpreter { Object eval_string_length(const Object& form, Arguments& args, const std::shared_ptr& env); + Object eval_string_append(const Object& form, + Arguments& args, + const std::shared_ptr& env); Object eval_ash(const Object& form, Arguments& args, const std::shared_ptr& env); diff --git a/decompiler/ObjectFile/ObjectFileDB.cpp b/decompiler/ObjectFile/ObjectFileDB.cpp index 9b38f0513..ce434f950 100644 --- a/decompiler/ObjectFile/ObjectFileDB.cpp +++ b/decompiler/ObjectFile/ObjectFileDB.cpp @@ -763,6 +763,9 @@ void ObjectFileDB::analyze_functions_ir1(const Config& config) { void ObjectFileDB::dump_raw_objects(const std::string& output_dir) { for_each_obj([&](ObjectFileData& data) { auto dest = output_dir + "/" + data.to_unique_name(); + if (data.obj_version != 3) { + dest += ".go"; + } file_util::write_binary_file(dest, data.data.data(), data.data.size()); }); } diff --git a/game/fake_iso.txt b/game/fake_iso.txt index db267221d..7316dfcb8 100644 --- a/game/fake_iso.txt +++ b/game/fake_iso.txt @@ -10,4 +10,5 @@ TWEAKVAL.MUS resources/TWEAKVAL.MUS VAGDIR.AYB resources/VAGDIR.AYB SCREEN1.USA resources/SCREEN1.USA 0COMMON.TXT out/iso/0COMMON.TXT -0TEST.TXT out/iso/0TEST.TXT \ No newline at end of file +0TEST.TXT out/iso/0TEST.TXT +VI1.DGO out/iso/VI1.DGO \ No newline at end of file diff --git a/game/kernel/klink.cpp b/game/kernel/klink.cpp index 543815bb6..ae18304d8 100644 --- a/game/kernel/klink.cpp +++ b/game/kernel/klink.cpp @@ -887,10 +887,12 @@ void* ultimate_memcpy(void* dst, void* src, uint32_t size) { } gfunc_774.offset = sym->value; } - printf("calling goal ultimate-memcpy!\n"); - return Ptr(call_goal(gfunc_774, make_u8_ptr(dst).offset, make_u8_ptr(src).offset, size, - s7.offset, g_ee_main_mem)) - .c(); + printf("Replacing goal ultimate-memcpy! with memmove\n"); + return memmove(dst, src, size); + // return Ptr(call_goal(gfunc_774, make_u8_ptr(dst).offset, make_u8_ptr(src).offset, + // size, + // s7.offset, g_ee_main_mem)) + // .c(); } else { return memmove(dst, src, size); } diff --git a/game/sce/stubs.cpp b/game/sce/stubs.cpp index 105ef5e60..efd82b25b 100644 --- a/game/sce/stubs.cpp +++ b/game/sce/stubs.cpp @@ -28,9 +28,7 @@ void sceGsExecStoreImage() { assert(false); } -void FlushCache() { - assert(false); -} +void FlushCache() {} } // namespace ee diff --git a/goal_src/engine/game/main.gc b/goal_src/engine/game/main.gc index 000ac8bfe..f118e1d06 100644 --- a/goal_src/engine/game/main.gc +++ b/goal_src/engine/game/main.gc @@ -23,6 +23,11 @@ (defun display-loop () ;; this function doesnt decompile right now + (while #t + (suspend) + ;;(format #t "hello from the display loop~%") + ) + 0 ) diff --git a/goal_src/engine/gfx/texture.gc b/goal_src/engine/gfx/texture.gc index 50043c6fe..59b4afbf4 100644 --- a/goal_src/engine/gfx/texture.gc +++ b/goal_src/engine/gfx/texture.gc @@ -1658,3 +1658,11 @@ (none) ) + +(define *texture-pool* (new 'global 'texture-pool)) + +;; temp hack for loading: +(defmethod relocate texture-page ((obj texture-page) (offset int)) + (format #t "HACK! removing texture page ~A from level heap~%" (-> obj name)) + (remove-from-heap obj loading-level) + ) diff --git a/goal_src/engine/level/level-h.gc b/goal_src/engine/level/level-h.gc index c2f0f632d..e7b083283 100644 --- a/goal_src/engine/level/level-h.gc +++ b/goal_src/engine/level/level-h.gc @@ -174,7 +174,7 @@ (deftype level-group (basic) ((length int32 :offset-assert 4) (unknown-level-1 level :offset-assert 8) - (unknown-level-2 level :offset-assert 12) + (unknown-level-2 level :offset-assert 12) ;; currently loading (entity-link entity-links :offset-assert 16) ;; not sure what's going on here (border? basic :offset-assert 20) (vis? basic :offset-assert 24) diff --git a/goal_src/engine/level/level.gc b/goal_src/engine/level/level.gc index f6722723a..143ac1138 100644 --- a/goal_src/engine/level/level.gc +++ b/goal_src/engine/level/level.gc @@ -93,6 +93,44 @@ ) ;; relocate bsp-header +(defmethod relocate bsp-header ((obj bsp-header) (arg0 int)) + (let ((s5-0 (-> *level* unknown-level-2))) + (if s5-0 + (cond + (obj + (cond + ((not (type-type? (-> obj type) bsp-header)) + (format 0 "ERROR: level ~A is not a bsp-header.~%" (-> s5-0 name)) + (the-as bsp-header #f) + ) + ((not (file-info-correct-version? (-> obj info) (file-kind level-bt) 0)) + (the-as bsp-header #f) + ) + ((< 2048 (-> obj visible-list-length)) + (format 0 "ERROR: level ~A visible-list-length ~d is greater than 2048 (16384 drawables).~%" + (-> s5-0 name) + (-> obj visible-list-length) + ) + (the-as bsp-header #f) + ) + (else + (load-dbg "bsp login: ~A~%" obj) + (set! (-> s5-0 bsp) obj) + (set! (-> obj level) s5-0) + obj + ) + ) + ) + (else + (format 0 "ERROR: level ~A is not a valid file.~%" + (-> s5-0 name) + ) + (the-as bsp-header #f) + ) + ) + ) + ) + ) (defmethod dummy-24 level ((obj level)) (unless (or (not (-> obj bsp)) (= *kernel-boot-mode* 'debug-boot)) @@ -448,7 +486,8 @@ (cond ((-> obj bsp) (set! (-> *level* unknown-level-1) (the-as level (-> obj bsp))) - (login-level-textures *texture-pool* obj (-> obj bsp unk-data-1-len) (the-as (pointer texture-id) (-> obj bsp unk-data-1))) + ;; TODO + ;;(login-level-textures *texture-pool* obj (-> obj bsp unk-data-1-len) (the-as (pointer texture-id) (-> obj bsp unk-data-1))) (let ((bsp (-> obj bsp))) (when (nonzero? (-> bsp adgifs)) (let ((adgifs (-> bsp adgifs))) @@ -479,6 +518,9 @@ (current-timer int) (initial-timer int) ) + ;; TODO REMOVE + (goto skip-hard-stuff) + 0 (let ((level-drawable-trees (-> loaded-level bsp drawable-trees))) 0 @@ -651,6 +693,8 @@ (set! (-> *subdivide-settings* close 3) f0-0) (set! (-> *subdivide-settings* far 3) f1-0) ) + + (label skip-hard-stuff) (dummy-25 loaded-level) (dummy-24 loaded-level) (set! (-> loaded-level status) 'loaded) @@ -676,11 +720,11 @@ (set! loading-level (-> obj heap)) (set! (-> *level* unknown-level-1) (the-as level (-> obj bsp))) (set! (-> *level* unknown-level-2) obj) - (dummy-18 (-> obj bsp)) + ;; (dummy-18 (-> obj bsp)) TODO (set! (-> obj status) 'alive) - (dummy-15 *game-info*) - (send-event *camera* 'level-activate (-> obj name)) - (send-event *target* 'level-activate (-> obj name)) + ;; (dummy-15 *game-info*) TODO + ;; (send-event *camera* 'level-activate (-> obj name)) + ;; (send-event *target* 'level-activate (-> obj name)) ) ) ) @@ -1210,9 +1254,12 @@ (set! *print-login* #f) (level-status-set! (level-get *level* startup-level) 'active) ) + + (load-dbg "Load complete. Level: ~A. Now starting display!~%" (-> *level* level0)) (on #t) + (load-dbg "Display started: ~A~%" *dproc*) (when arg1 - (dummy-9 *game-info* 'game #f (the-as string #f)) + ;; (dummy-9 *game-info* 'game #f (the-as string #f)) TODO ) 0 ) @@ -1575,3 +1622,11 @@ +(defmacro test-play () + `(begin + ;; before calling play, the C Kernel would set this. + (define *kernel-boot-message* 'play) + (load-package "game" global) + (play #t #t) + ) + ) diff --git a/goal_src/engine/load/file-io.gc b/goal_src/engine/load/file-io.gc index 8f8c40b5e..70022a0e2 100644 --- a/goal_src/engine/load/file-io.gc +++ b/goal_src/engine/load/file-io.gc @@ -161,7 +161,7 @@ ((or (= v1-0 (file-kind tpage)) (= v1-0 (file-kind dir-tpage))) TPAGE_FILE_VERSION ) - ((= kind (file-kind level-vs)) + ((= kind (file-kind level-bt)) LEVEL_BT_FILE_VERSION ) ((= v1-0 (file-kind art-group)) @@ -178,7 +178,7 @@ ((= v1-1 (file-kind tpage)) "texture-page" ) - ((= kind (file-kind level-vs)) + ((= kind (file-kind level-bt)) "bsp-header" ) ((= v1-1 (file-kind art-group)) diff --git a/goal_src/engine/util/types-h.gc b/goal_src/engine/util/types-h.gc index f06852e60..2472765ee 100644 --- a/goal_src/engine/util/types-h.gc +++ b/goal_src/engine/util/types-h.gc @@ -96,3 +96,17 @@ "turn a velocity value into a per-tick value" `(* (/ 1.0 ,TICKS_PER_SECOND) ,vel) ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Debugging Stuff +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; set to #t to get lots of prints during loading +(defglobalconstant DEBUG_LOAD #t) + +(defmacro load-dbg (fmt-str &rest args) + (if DEBUG_LOAD + `(format 0 ,(string-append "[LOAD] " fmt-str) ,@args) + '(empty) + ) + ) diff --git a/goal_src/goal-lib.gc b/goal_src/goal-lib.gc index 7a3c808b7..8d7dc1e54 100644 --- a/goal_src/goal-lib.gc +++ b/goal_src/goal-lib.gc @@ -69,13 +69,13 @@ `(begin (build-game) (dgo-load "kernel" global #xf #x200000) - (dgo-load "game" global #xf #x200000) + (load-package "game" global) ) ) (defmacro lg () "Load an already built game." - `(dgo-load "game" global #xf #x200000) + `(load-package "game" global) ) (defmacro tc () diff --git a/goalc/compiler/compilation/Debug.cpp b/goalc/compiler/compilation/Debug.cpp index 4aa4b3905..6647231c0 100644 --- a/goalc/compiler/compilation/Debug.cpp +++ b/goalc/compiler/compilation/Debug.cpp @@ -350,6 +350,7 @@ Val* Compiler::compile_disasm(const goos::Object& form, const goos::Object& rest m_debugger.read_memory(mem.data(), size, addr); + fmt::print("{}\n", m_debugger.get_info_about_addr(addr)); fmt::print("{}\n", disassemble_x86(mem.data(), mem.size(), m_debugger.get_x86_base_addr() + addr)); diff --git a/goalc/debugger/Debugger.cpp b/goalc/debugger/Debugger.cpp index 81fb0b3b8..e81318b9d 100644 --- a/goalc/debugger/Debugger.cpp +++ b/goalc/debugger/Debugger.cpp @@ -127,6 +127,26 @@ bool Debugger::attach_and_break() { return false; } +std::string Debugger::get_info_about_addr(u32 addr) { + if (addr >= EE_MAIN_MEM_LOW_PROTECT && addr < EE_MAIN_MEM_SIZE) { + auto map_loc = m_memory_map.lookup(addr); + if (map_loc.empty) { + return "Unknown Address"; + } + std::string result = fmt::format("Object: {}\n", map_loc.obj_name); + u64 obj_offset = addr - map_loc.start_addr; + FunctionDebugInfo* info = nullptr; + std::string name; + if (get_debug_info_for_object(map_loc.obj_name) + .lookup_function(&info, &name, obj_offset, map_loc.seg_id)) { + result += fmt::format("Name: {}\n", name); + } + return result; + } else { + return "Outside of GOAL memory"; + } +} + /*! * Read the registers, symbol table, and instructions near rip. * Print out some info about where we are. diff --git a/goalc/debugger/Debugger.h b/goalc/debugger/Debugger.h index 1f4cfef5d..eed875567 100644 --- a/goalc/debugger/Debugger.h +++ b/goalc/debugger/Debugger.h @@ -61,6 +61,7 @@ class Debugger { void update_break_info(); DebugInfo& get_debug_info_for_object(const std::string& object_name); const BreakInfo& get_cached_break_info() { return m_break_info; } + std::string get_info_about_addr(u32 addr); /*! * Get the x86 address of GOAL memory