Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

g/j2: Implement speedrunner mode in jak 2 #2976

Merged
merged 8 commits into from
Sep 17, 2023
40 changes: 39 additions & 1 deletion common/util/FontUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1124,8 +1124,46 @@ static std::vector<ReplaceInfo> s_replace_info_jak2 = {
{"~Y~-6Hº~Z~+10H", "°"},

// Color / Emphasis
{"~[~0L", "<COLOR_DEFAULT>"},
{"~[~1L", "<COLOR_WHITE>"},
{"~[~32L", "<COLOR_DEFAULT>"}};
{"~[~2L", "<COLOR_TRANSPARENT>"},
{"~[~3L", "<COLOR_RED>"},
{"~[~4L", "<COLOR_ORANGE>"},
{"~[~5L", "<COLOR_YELLOW>"},
{"~[~6L", "<COLOR_GREEN>"},
{"~[~7L", "<COLOR_BLUE>"},
{"~[~8L", "<COLOR_CYAN>"},
{"~[~9L", "<COLOR_PINK>"},
{"~[~10L", "<COLOR_MENU-SELECTED>"},
{"~[~11L", "<COLOR_MENU-SELECTED-PARENT>"},
{"~[~12L", "<COLOR_MENU>"},
{"~[~13L", "<COLOR_MENU-PARENT>"},
{"~[~14L", "<COLOR_MENU-FUNC-BAD>"},
{"~[~15L", "<COLOR_MENU-FLAG-ON>"},
{"~[~16L", "<COLOR_MENU-FLAG-ON-PARENT>"},
{"~[~17L", "<COLOR_MENU-FLAG-OFF>"},
{"~[~18L", "<COLOR_MENU-FLAG-OFF-PARENT>"},
{"~[~19L", "<COLOR_MENU-INVALID>"},
{"~[~20L", "<COLOR_FLAT-YELLOW>"},
{"~[~21L", "<COLOR_COLOR-21>"},
{"~[~22L", "<COLOR_PAD-BACK>"},
{"~[~23L", "<COLOR_PAD-SHINE>"},
{"~[~24L", "<COLOR_PAD-SQUARE>"},
{"~[~25L", "<COLOR_PAD-CIRCLE>"},
{"~[~26L", "<COLOR_PAD-TRIANGLE>"},
{"~[~27L", "<COLOR_PAD-CROSS>"},
{"~[~28L", "<COLOR_PROGRESS-OLD-BLUE>"},
{"~[~29L", "<COLOR_PROGRESS-OLD-YELLOW>"},
{"~[~30L", "<COLOR_PROGRESS-OLD-SELECTED>"},
{"~[~31L", "<COLOR_PROGRESS-OLD-PERCENT>"},
{"~[~32L", "<COLOR_PROGRESS>"},
{"~[~33L", "<COLOR_PROGRESS-SELECTED>"},
{"~[~34L", "<COLOR_PROGRESS-FORCE-SELECTED>"},
{"~[~35L", "<COLOR_PROGRESS-OPTION-OFF>"},
{"~[~36L", "<COLOR_COLOR-36>"},
{"~[~37L", "<COLOR_CREDITS-STAFF-TITLE-1>"},
{"~[~38L", "<COLOR_CREDITS-STAFF-TITLE-2>"},
{"~[~39L", "<COLOR_COLOR-39>"}};

static std::vector<EncodeInfo> s_encode_info_jak2 = {
{"ˇ", {0x10}}, // caron
Expand Down
5 changes: 3 additions & 2 deletions game/kernel/jak1/kmachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ void InitIOP() {
}
}

AutoSplitterBlock gAutoSplitterBlock;
AutoSplitterBlock g_auto_splitter_block_jak1;

/*!
* Initialize GOAL Runtime. This is the main initialization which is called before entering
Expand Down Expand Up @@ -357,7 +357,8 @@ int InitMachine() {
}

// TODO - better place to put this?
gAutoSplitterBlock.pointer_to_symbol =
// TODO - yes, see jak2's code!
g_auto_splitter_block_jak1.pointer_to_symbol =
(u64)g_ee_main_mem + intern_from_c("*autosplit-info-jak1*")->value;

lg::info("InitListenerConnect");
Expand Down
2 changes: 1 addition & 1 deletion game/kernel/jak1/kmachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,5 @@ struct AutoSplitterBlock {
const char marker[20] = "UnLiStEdStRaTs_JaK1";
u64 pointer_to_symbol = 0;
};
extern AutoSplitterBlock gAutoSplitterBlock;
extern AutoSplitterBlock g_auto_splitter_block_jak1;
} // namespace jak1
12 changes: 10 additions & 2 deletions game/kernel/jak2/kmachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,8 @@ void InitIOP() {
}
printf("InitIOP OK\n");
}
AutoSplitterBlock gAutoSplitterBlock;

AutoSplitterBlock g_auto_splitter_block_jak2;

int InitMachine() {
// heap_start = malloc(0x10);
Expand Down Expand Up @@ -662,7 +663,7 @@ void pc_set_levels(u32 lev_list) {
}

void init_autosplit_struct() {
gAutoSplitterBlock.pointer_to_symbol =
g_auto_splitter_block_jak2.pointer_to_symbol =
(u64)g_ee_main_mem + (u64)intern_from_c("*autosplit-info-jak2*")->value();
}

Expand Down Expand Up @@ -741,6 +742,12 @@ inline u64 bool_to_symbol(const bool val) {
// return bool_to_symbol(false);
//}

void encode_utf8_string(u32 src_str_ptr, u32 str_dest_ptr) {
auto str = std::string(Ptr<String>(src_str_ptr).c()->data());
std::string converted = get_font_bank(GameTextVersion::JAK2)->convert_utf8_to_game(str);
strcpy(Ptr<String>(str_dest_ptr).c()->data(), converted.c_str());
}

void InitMachine_PCPort() {
// PC Port added functions
init_common_pc_port_functions(
Expand All @@ -756,6 +763,7 @@ void InitMachine_PCPort() {
make_function_symbol_from_c("__pc-set-levels", (void*)pc_set_levels);
make_function_symbol_from_c("__pc-get-tex-remap", (void*)lookup_jak2_texture_dest_offset);
make_function_symbol_from_c("pc-init-autosplitter-struct", (void*)init_autosplit_struct);
make_function_symbol_from_c("pc-encode-utf8-string", (void*)encode_utf8_string);

// discord rich presence
make_function_symbol_from_c("pc-discord-rpc-update", (void*)update_discord_rpc);
Expand Down
2 changes: 1 addition & 1 deletion game/kernel/jak2/kmachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,6 @@ struct AutoSplitterBlock {
u64 pointer_to_symbol = 0;
};

extern AutoSplitterBlock gAutoSplitterBlock;
extern AutoSplitterBlock g_auto_splitter_block_jak2;

} // namespace jak2
4 changes: 2 additions & 2 deletions goal_src/jak1/pc/features/speedruns.gc
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@
(initialize! *game-info* 'game (the-as game-save #f) "jungle-start")
)
(((speedrun-category il-misty))
;; spawn at start of misty
;; spawn at start of misty
(initialize! *game-info* 'game (the-as game-save #f) "misty-start")
)
(((speedrun-category il-firecanyon))
Expand Down Expand Up @@ -240,7 +240,7 @@
(set! (-> *setting-control* default auto-save) #t)
(none)
)

(defun setup-speedrun-post-blackout ()
(when (and (-> *speedrun-info* needs-post-blackout-setup?) (>= (-> *display* base-frame-counter) (-> *game-info* blackout-time)))
(set! (-> *speedrun-info* needs-post-blackout-setup?) #f)
Expand Down
3 changes: 1 addition & 2 deletions goal_src/jak1/pc/pckernel-common.gc
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,7 @@
(update-discord-rpc obj)

;; update auto-splitter info
(when (-> *pc-settings* speedrunner-mode?)
(update-speedrun obj))
(update-speedrun obj)

(when (not (-> obj use-vis?))
(update-video-hacks obj)
Expand Down
2 changes: 1 addition & 1 deletion goal_src/jak1/pc/pckernel.gc
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@

(defmethod update-speedrun pc-settings-jak1 ((obj pc-settings-jak1))
"update speedrun module"
(with-profiler "speedrun-update-jak1"
(with-profiler "speedrun-update"
(speedrun-mode-update))
(none))

Expand Down
4 changes: 3 additions & 1 deletion goal_src/jak2/dgos/game.gd
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,8 @@
"settings.o"
"autosplit-h.o" ;; added
"autosplit.o" ;; added
"popup-menu-h.o" ;; added
"speedruns-h.o" ;; added
"speedruns.o" ;; added
"mood-tables.o"
"mood-tables2.o"
"mood.o"
Expand Down Expand Up @@ -327,6 +327,8 @@
"board-states.o"
"mech-h.o"
"menu.o"
"popup-menu.o" ;; added
"speedruns.o" ;; added
"drawable.o"
"drawable-group.o"
"drawable-inline-array.o"
Expand Down
4 changes: 3 additions & 1 deletion goal_src/jak2/engine/game/game-save.gc
Original file line number Diff line number Diff line change
Expand Up @@ -1778,7 +1778,9 @@ auto-save-post
)
(suspend)
)
(activate-progress *dproc* 'icon-info)
;; og:preserve-this Disable the auto-save prompt in speedrunner mode, we get it
(when (not (-> *pc-settings* speedrunner-mode?))
(activate-progress *dproc* 'icon-info))
(while *progress-process*
(suspend)
)
Expand Down
2 changes: 2 additions & 0 deletions goal_src/jak2/engine/game/main.gc
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,8 @@
;; draw and update menus
(with-profiler 'menu-hook *profile-menu-hook-color*
(*menu-hook*)
(when *speedrun-menu*
(draw! (-> *speedrun-menu* 0)))
)

;; load text files as needed from the menu update
Expand Down
27 changes: 26 additions & 1 deletion goal_src/jak2/engine/level/level-info.gc
Original file line number Diff line number Diff line change
Expand Up @@ -3308,6 +3308,31 @@
)
:want-sound (new 'static 'array symbol 3 'ctywide1 'forexit1 'forexit2)
)
;; og:preserve-this Added to enable fast-game-starts with hero mode
(new 'static 'continue-point
:name "game-start-hero"
:level 'prison
:flags (continue-flags game-start hero-mode)
:trans (new 'static 'vector :x 1942413.2 :y 34479.31 :z 275525.62 :w 1.0)
:quat (new 'static 'vector :y 0.4562 :w 0.8898)
:camera-trans (new 'static 'vector :x 1921090.8 :y 53425.766 :z 237949.75 :w 1.0)
:camera-rot (new 'static 'inline-array vector3s 3
(new 'static 'vector3s :data (new 'static 'array float 3 0.869 0.0 -0.4947))
(new 'static 'vector3s :data (new 'static 'array float 3 0.0663 0.9909 0.1165))
(new 'static 'vector3s :data (new 'static 'array float 3 0.4903 -0.134 0.8611))
)
:on-goto #f
:vis-nick 'prison
:want (new 'static 'inline-array level-buffer-state 6
(new 'static 'level-buffer-state :name 'prison :display? 'display :force-vis? #f :force-inside? #f)
(new 'static 'level-buffer-state :name 'forexita :display? #f :force-vis? #f :force-inside? #f)
(new 'static 'level-buffer-state :name #f :display? #f :force-vis? #f :force-inside? #f)
(new 'static 'level-buffer-state :name #f :display? #f :force-vis? #f :force-inside? #f)
(new 'static 'level-buffer-state :name #f :display? #f :force-vis? #f :force-inside? #f)
(new 'static 'level-buffer-state :name #f :display? #f :force-vis? #f :force-inside? #f)
)
:want-sound (new 'static 'array symbol 3 'ctywide1 'forexit1 'forexit2)
)
(new 'static 'continue-point
:name "prison-intro-start"
:level 'prison
Expand Down Expand Up @@ -15698,4 +15723,4 @@
(cons! *level-load-list* 'teststdd)
(cons! *level-load-list* 'wasall)
(cons! *level-load-list* 'stadocc)
)
)
8 changes: 8 additions & 0 deletions goal_src/jak2/engine/target/target-death.gc
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,14 @@
)
(cond
((logtest? (-> arg0 flags) (continue-flags game-start))
;; og:preserve-this Added to make fast-game-start work with hero-mode
(when (logtest? (-> arg0 flags) (continue-flags hero-mode))
(logior! (-> self game secrets) (game-secrets hero-mode))
(logior! (-> self game purchase-secrets) (game-secrets hero-mode))
;; TODO - there might be a better way to do this, the way hero-mode is set kinda feels like a side-effect
;; `update-task-masks` gets called during the `intro-start-hero` via `setting-control::apply-settings`
;; Which runs the following line if hero-mode is enabled
(set! (-> *game-info* features) (game-feature gun gun-yellow gun-red gun-blue gun-dark)))
(case *kernel-boot-message*
(('kiosk)
(let ((s5-5 (ppointer->handle (auto-save-command 'restore 0 0 *default-pool* #f))))
Expand Down
21 changes: 14 additions & 7 deletions goal_src/jak2/engine/ui/progress/progress.gc
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,22 @@
arg0
)

(defun progress-intro-start ((arg0 symbol))
(defun progress-intro-start ((hero-mode? symbol))
(set! (-> *game-info* mode) 'play)
(if arg0
(initialize! *game-info* 'game (the-as game-save #f) "intro-start-hero")
(initialize! *game-info* 'game (the-as game-save #f) "intro-start")
)
(cond
;; Start a new game differently if speedrunning mode is active
((= (-> *pc-settings* speedrunner-mode?) #t)
(if hero-mode?
(set-category! *speedrun-info* (speedrun-category newgame-heromode))
(set-category! *speedrun-info* (speedrun-category newgame-normal)))
(start-run! *speedrun-info*))
;; start the game normally
(else
(if hero-mode?
(initialize! *game-info* 'game (the-as game-save #f) "intro-start-hero")
(initialize! *game-info* 'game (the-as game-save #f) "intro-start"))))
(set-master-mode 'game)
0
)
0)

(defmethod init-defaults progress ((obj progress))
"Initialize default menu settings."
Expand Down
2 changes: 2 additions & 0 deletions goal_src/jak2/kernel-defs.gc
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@
(define-extern pc-is-imgui-visible? (function symbol))
(define-extern pc-rand (function int))

(define-extern pc-encode-utf8-string (function string string none))

;; Used to dump fixture data for the editor, re-enable end-to-end if you need it
;; (define-extern has-level-been-dumped-lights? (function string symbol))
;; (define-extern has-level-been-dumped-regions? (function string symbol))
Expand Down
2 changes: 2 additions & 0 deletions goal_src/jak2/kernel/gstring.gc
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,8 @@
)
)

(define *pc-encoded-temp-string* (new 'global 'string 2048 (the-as string #f)))

(kmemclose)


Expand Down
11 changes: 6 additions & 5 deletions goal_src/jak2/pc/features/autosplit-h.gc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
;;
;; DO NOT change the order, appending to the end is safe!

(deftype autosplit-info-jak2 (structure)
(deftype autosplit-info (structure)
(;; Version Info
(version-major uint16)
(version-minor uint16)
Expand Down Expand Up @@ -127,8 +127,9 @@
(res-stadium-burning-bush-race-class1-r uint8)
;; TODO - orbs in level X
;; end marker just to make things look nice in a memory view
(end-marker uint8 4)))
(end-marker uint8 4))
(:methods
(reset! (_type_) none)
(update! (_type_) none)))

(define-extern *autosplit-info-jak2* autosplit-info-jak2)
(define-extern update-autosplit-info-jak2 (function none))
(define-extern update-autosplit-jak2-new-game (function none))
(define-extern *autosplit-info-jak2* autosplit-info)
19 changes: 8 additions & 11 deletions goal_src/jak2/pc/features/autosplit.gc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
;;-*-Lisp-*-
(in-package goal)

(define *autosplit-info-jak2* (new 'static 'autosplit-info-jak2))
(define *autosplit-info-jak2* (new 'static 'autosplit-info))
(pc-init-autosplitter-struct)
;; Setup Version
(set! (-> *autosplit-info-jak2* version-major) 0)
Expand All @@ -14,16 +14,14 @@

(defmacro autosplit-flag-task-complete! (field-name task-name)
"Given a field name in the autosplitter struct, and a [[game-task]] name to check, sets either a 0 or a 1"
`(set! (-> *autosplit-info-jak2* ,field-name) (if (task-complete? *game-info* (game-task ,task-name)) 1 0)))
`(set! (-> this ,field-name) (if (task-complete? *game-info* (game-task ,task-name)) 1 0)))

(defun update-autosplit-info-jak2 ()
(defmethod update! autosplit-info ((this autosplit-info))
;; general statistics
(set! (-> *autosplit-info-jak2* num-orbs) (the int (-> *game-info* skill-total)))
(set! (-> *autosplit-info-jak2* num-skullgems) (the int (-> *game-info* gem-total)))

(set! (-> this num-orbs) (the int (-> *game-info* skill-total)))
(set! (-> this num-skullgems) (the int (-> *game-info* gem-total)))
;; loading/cutscene related flags
(set! (-> *autosplit-info-jak2* in-cutscene?) (if (movie?) 1 0))

(set! (-> this in-cutscene?) (if (movie?) 1 0))
;; need resolution flags
(autosplit-flag-task-complete! res-fortress-escape fortress-escape)
(autosplit-flag-task-complete! res-city-help-kid city-help-kid)
Expand Down Expand Up @@ -129,10 +127,9 @@
(autosplit-flag-task-complete! res-stadium-burning-bush-race-class3-r stadium-burning-bush-race-class3-r)
(autosplit-flag-task-complete! res-stadium-burning-bush-race-class2-r stadium-burning-bush-race-class2-r)
(autosplit-flag-task-complete! res-stadium-burning-bush-race-class1-r stadium-burning-bush-race-class1-r)

(none))


(defun update-autosplit-jak2-new-game ()
(set! (-> *autosplit-info-jak2* game-hash) (pc-get-unix-timestamp))
(defmethod reset! autosplit-info ((this autosplit-info))
(set! (-> this game-hash) (pc-get-unix-timestamp))
(none))