From 1924418084056c7ac339764b3deb739a400bf9ab Mon Sep 17 00:00:00 2001 From: Matt Dallmeyer Date: Wed, 4 Sep 2024 21:23:02 -0700 Subject: [PATCH] [jak2] Custom speedrun category continue select --- game/kernel/jak2/kmachine_extras.cpp | 4 ++ game/kernel/jak2/kmachine_extras.h | 2 + goal_src/jak2/pc/features/speedruns-h.gc | 5 +- goal_src/jak2/pc/features/speedruns.gc | 60 +++++++++++++++++++++++- 4 files changed, 69 insertions(+), 2 deletions(-) diff --git a/game/kernel/jak2/kmachine_extras.cpp b/game/kernel/jak2/kmachine_extras.cpp index 0f8c2c1a6..6c0aefe9e 100644 --- a/game/kernel/jak2/kmachine_extras.cpp +++ b/game/kernel/jak2/kmachine_extras.cpp @@ -609,6 +609,7 @@ void to_json(json& j, const SpeedrunCustomCategoryEntry& obj) { json_serialize(cheats); json_serialize(continue_point_name); json_serialize(completed_task); + json_serialize(continue_point); } void from_json(const json& j, SpeedrunCustomCategoryEntry& obj) { @@ -619,6 +620,7 @@ void from_json(const json& j, SpeedrunCustomCategoryEntry& obj) { json_deserialize_if_exists(cheats); json_deserialize_if_exists(continue_point_name); json_deserialize_if_exists(completed_task); + json_deserialize_if_exists(continue_point); } std::vector g_speedrun_practice_entries; @@ -894,6 +896,7 @@ void pc_sr_mode_init_custom_category_info(s32 entry_index, u32 speedrun_custom_c category->forbidden_features = json_info.forbidden_features; category->cheats = json_info.cheats; category->completed_task = json_info.completed_task; + category->continue_point = json_info.continue_point; } } @@ -920,6 +923,7 @@ void pc_sr_mode_dump_new_custom_category(u32 speedrun_custom_category_ptr) { new_category.cheats = category->cheats; new_category.completed_task = category->completed_task; new_category.continue_point_name = ""; + new_category.continue_point = category->continue_point; g_speedrun_custom_categories.push_back(new_category); // convert to json and write file json data = g_speedrun_custom_categories; diff --git a/game/kernel/jak2/kmachine_extras.h b/game/kernel/jak2/kmachine_extras.h index f10c13d5a..f9fc82673 100644 --- a/game/kernel/jak2/kmachine_extras.h +++ b/game/kernel/jak2/kmachine_extras.h @@ -194,6 +194,7 @@ struct SpeedrunCustomCategoryEntry { u64 cheats; std::string continue_point_name; u64 completed_task; + u32 continue_point; }; void to_json(json& j, const SpeedrunCustomCategoryEntry& obj); void from_json(const json& j, SpeedrunCustomCategoryEntry& obj); @@ -205,6 +206,7 @@ struct SpeedrunCustomCategory { u64 forbidden_features; u64 cheats; u8 completed_task; + u32 continue_point; }; } // namespace kmachine_extras diff --git a/goal_src/jak2/pc/features/speedruns-h.gc b/goal_src/jak2/pc/features/speedruns-h.gc index ed0013b67..b0bd92944 100644 --- a/goal_src/jak2/pc/features/speedruns-h.gc +++ b/goal_src/jak2/pc/features/speedruns-h.gc @@ -96,7 +96,9 @@ (features game-feature :offset-assert 8) (forbidden-features game-feature :offset-assert 16) (pc-cheats pc-cheats :offset-assert 24) - (completed-task game-task :offset-assert 32))) + (completed-task game-task :offset-assert 32) + (continue-point string :offset-assert 36) + )) (deftype speedrun-info (structure) ((category speedrun-category) @@ -132,3 +134,4 @@ idle)) (define-extern *speedrun-manager* (pointer speedrun-manager)) +(define-extern *main-continue-point-list* pair) diff --git a/goal_src/jak2/pc/features/speedruns.gc b/goal_src/jak2/pc/features/speedruns.gc index ebefbf7ad..ad666a690 100644 --- a/goal_src/jak2/pc/features/speedruns.gc +++ b/goal_src/jak2/pc/features/speedruns.gc @@ -16,6 +16,58 @@ (set! (-> *speedrun-info* active-practice-objective start-zone-init-params) (new 'static 'objective-zone-init-params)) (set! (-> *speedrun-info* active-practice-objective end-zone-init-params) (new 'static 'objective-zone-init-params)) +;; dynamically populate continue-point list, for custom category menu +(define *main-continue-point-list* '()) + +(defun is-main-level? ((lvl-name symbol)) + (case lvl-name + (('vinroom 'drillmid 'drill 'drillb 'sewer 'sewerb 'sewesc 'sewescb 'tomba 'tombb 'tombc 'tombd 'tombe 'tombboss + 'under 'underb 'palcab 'palshaft 'palboss 'palroof 'throne 'palent 'prison 'forexita 'forexitb 'forresca 'forrescb + 'fordumpa 'fordumpb 'fordumpc 'fordumpd 'strip 'ruins 'sagehut 'atoll 'mountain 'forest 'forestb 'mincan + 'ctygena 'ctygenb 'ctygenc 'ctysluma 'ctyslumb 'ctyslumc 'ctyport 'ctyfarma 'ctyfarmb 'ctyinda 'consite 'consiteb + 'ctyindb 'ctymarka 'ctymarkb 'ctypal 'stadium 'stadiumb 'stadiumc 'stadiumd 'skatea 'garage 'onintent 'kiosk + 'oracle 'hideout 'hiphog 'gungame 'dig1 'dig3a 'dig3b 'caspad 'castle 'casboss 'village1 'nest 'nestb) + #t) + (else + #f))) + +(defun is-main-continue? ((cont continue-point)) + (not (logtest? (-> cont flags) (continue-flags record-path demo-end record-sig demo intro title title-movie)))) + +(defun build-main-continue-point-list () + ;; reset list just to be safe + (set! *main-continue-point-list* '()) + (let ((lvl-ptr *level-load-list*)) + ;; loop thru levels + (while (not (null? lvl-ptr)) + (let* ((lvl (the-as level-load-info (-> (the-as symbol (car lvl-ptr)) value))) + (continue-ptr (-> lvl continues))) + (when (is-main-level? (-> lvl name)) + ;; loop thru level's continues + (while (not (null? continue-ptr)) + (let ((cont (the-as continue-point (car continue-ptr)))) + (when (is-main-continue? cont) + ;; this continue is valid, push to list + (cons! *main-continue-point-list* (-> cont name)))) + (set! continue-ptr (cdr continue-ptr))))) + (set! lvl-ptr (cdr lvl-ptr))))) + +(build-main-continue-point-list) + +(defun get-main-continue-point-count () + (let ((cont-ptr *main-continue-point-list*) + (count 0)) + (while (not (null? cont-ptr)) + (+! count 1) + (set! cont-ptr (cdr cont-ptr))) + count)) + +(defun get-main-continue-point-by-idx ((idx int)) + (let ((cont-ptr *main-continue-point-list*)) + (dotimes (i idx) + (set! cont-ptr (cdr cont-ptr))) + (the string (car cont-ptr)))) + (defmethod draw-timer ((this speedrun-timer)) (clear *temp-string*) (clear *pc-encoded-temp-string*) @@ -87,7 +139,7 @@ (clear *temp-string*) (pc-sr-mode-get-custom-category-continue-point (-> *speedrun-info* active-custom-category index) *temp-string*) (if (string= *temp-string* "") - (initialize! *game-info* 'game (the-as game-save #f) "game-start") + (initialize! *game-info* 'game (the-as game-save #f) (-> *speedrun-info* active-custom-category continue-point)) (initialize! *game-info* 'game (the-as game-save #f) *temp-string*)) (until (and *target* (= (-> *target* next-state name) 'target-stance)) (suspend)) @@ -369,6 +421,12 @@ :on-entry-confirm (lambda ((index int)) (set! (-> *speedrun-info* dump-custom-category completed-task) (the game-task index))) :entry-selected? (lambda ((index int)) (= (-> *speedrun-info* dump-custom-category completed-task) (the game-task index))) :on-reset (lambda () (set! (-> *speedrun-info* dump-custom-category completed-task) (game-task none)))) + (new 'static 'popup-menu-dynamic-submenu :label "Select starting continue" + :get-length (lambda () (get-main-continue-point-count)) + :get-entry-label (lambda ((index int) (str-dest string)) (copy-string<-string str-dest (get-main-continue-point-by-idx index))) + :on-entry-confirm (lambda ((index int)) (set! (-> *speedrun-info* dump-custom-category continue-point) (get-main-continue-point-by-idx index))) + :entry-selected? (lambda ((index int)) (string= (-> *speedrun-info* dump-custom-category continue-point) (get-main-continue-point-by-idx index))) + :on-reset (lambda () (set! (-> *speedrun-info* dump-custom-category continue-point) "game-start"))) (new 'static 'popup-menu-button :label "Save new category to file" :on-confirm (lambda () (pc-sr-mode-dump-new-custom-category (-> *speedrun-info* dump-custom-category)))))))) (new 'static 'popup-menu-button :label "Exit"