jak1/speedruns: Some final touches for speedrunning in jak 1 (#1830)

* jak1: put common speedrunning code into it's own file

* jak1: enforce `60` fps while in speedrunning mode

* jak1: when speedrunning, display the version until you get the first powercell

* jak1: add an explicit option for skipping cutscenes

* jak1: extend `game-option` to allow any menu option to be disabled

* tests/jak1: allow whitelisting types to be redefined to satisfy typeconsistency checks

* jak1: add file headers

* jak1: cleanup bool checking

* test: delete the es substitle file

* test: add it back

* jak1: missed one cleanup spot related to bool comparisons
This commit is contained in:
Tyler Wilding 2022-09-02 18:15:42 -04:00 committed by GitHub
parent f1f18e7e05
commit 0896bef2bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 2556 additions and 2504 deletions

View file

@ -59,7 +59,10 @@ Type* TypeSystem::add_type(const std::string& name, std::unique_ptr<Type> type)
if (*kv->second != *type) {
// exists, and we are trying to change it!
if (m_allow_redefinition) {
// Check if the type is allowed to be redefined
if (m_allow_redefinition ||
std::find(m_types_allowed_to_be_redefined.begin(), m_types_allowed_to_be_redefined.end(),
kv->second->get_name()) != m_types_allowed_to_be_redefined.end()) {
fmt::print("[TypeSystem] Type {} was originally\n{}\nand is redefined as\n{}\n",
kv->second->get_name(), kv->second->print(), type->print());
// extra dangerous, we have allowed type redefinition!

View file

@ -259,6 +259,10 @@ class TypeSystem {
int get_size_in_type(const Field& field) const;
void add_type_to_allowed_redefinition_list(const std::string& type_name) {
m_types_allowed_to_be_redefined.push_back(type_name);
}
private:
std::string lca_base(const std::string& a, const std::string& b) const;
bool typecheck_base_types(const std::string& expected,
@ -284,6 +288,7 @@ class TypeSystem {
std::vector<std::unique_ptr<Type>> m_old_types;
std::vector<std::string> m_types_allowed_to_be_redefined;
bool m_allow_redefinition = false;
};

View file

@ -1609,6 +1609,7 @@
(hint-0 #x1300)
(hint-511 #x14ff)
(speedrunner-mode #x1500)
(cutscene-skips #x1501)
;; GAME-TEXT-ID ENUM ENDS
)

View file

@ -359,6 +359,9 @@
(#x1500 "SPEEDRUNNER MODE"
"SPEEDRUNNER MODE")
(#x1501 "CUTSCENE SKIPS"
"CUTSCENE SKIPS")
;; -----------------
;; test (DO NOT TRANSLATE)

View file

@ -199,6 +199,8 @@
("pc-anim-util.o" "pc-anim-util") ;; added
("autosplit-h.o" "autosplit-h") ;; added
("autosplit.o" "autosplit") ;; added
("speedruns-h.o" "speedruns-h") ;; added
("speedruns.o" "speedruns") ;; added
("pckernel.o" "pckernel") ;; added
("mood-tables.o" "mood-tables")
("mood.o" "mood")

View file

@ -195,6 +195,8 @@
("pc-anim-util.o" "pc-anim-util") ;; added
("autosplit-h.o" "autosplit-h") ;; added
("autosplit.o" "autosplit") ;; added
("speedruns-h.o" "speedruns-h") ;; added
("speedruns.o" "speedruns") ;; added
("pckernel.o" "pckernel") ;; added
("mood-tables.o" "mood-tables")
("mood.o" "mood")

View file

@ -436,7 +436,9 @@
;; save a sort of timestamp just so we know whether it took at least 1 frame
(#when PC_PORT
(define *play-anim-time* (current-time)))
(if (#if PC_PORT #t (and *debug-segment* *cheat-mode*))
(if (#if PC_PORT
(= (-> *pc-settings* cutscene-skips?) #t)
(and *debug-segment* *cheat-mode*))
(ja-play-spooled-anim
(the-as spool-anim arg1)
arg0

View file

@ -4721,6 +4721,7 @@
(flag "br-portuguese" 13 dm-text-language)
)
(flag "Discord RPC" #t ,(dm-lambda-boolean-flag (-> *pc-settings* discord-rpc?)))
(flag "Cutscene Skips" #t ,(dm-lambda-boolean-flag (-> *pc-settings* cutscene-skips?)))
(flag "Speedrunner Mode" #t ,(dm-lambda-boolean-flag (-> *pc-settings* speedrunner-mode?)))
(menu "PS2 settings"
;(flag "PS2 Load speed" #f ,(dm-lambda-boolean-flag (-> *pc-settings* ps2-read-speed?)))

View file

@ -695,9 +695,13 @@
(with-profiler "menu"
(with-pc
(if (and (-> *pc-settings* display-sha) *debug-segment*)
(draw-build-revision)))
(cond ((and (= (-> *pc-settings* speedrunner-mode?) #t)
(< (-> *autosplit-info-jak1* num-power-cells) 1))
;; display the revision before you collect your first powercell
(draw-build-revision))
((and (-> *pc-settings* display-sha) *debug-segment*)
;; otherwise, only draw if we are in debug mode and the setting isn't enabled
(draw-build-revision))))
(*menu-hook*)
(add-ee-profile-frame 'draw :g #x40)

View file

@ -227,10 +227,11 @@
(param2 float :offset-assert 28)
(param3 game-option-menu :offset-assert 32)
(value-to-modify pointer :offset-assert 36)
(option-disabled-func (function symbol) :offset-assert 40) ;; added in pc port
)
:method-count-assert 9
:size-assert #x28
:flag-assert #x900000028
:size-assert #x2C
:flag-assert #x90000002C
)

View file

@ -1727,18 +1727,10 @@
(let ((gp-1 (-> *setting-control* default auto-save)))
(sound-volume-off)
(set! (-> *game-info* mode) 'play)
;; Start a new game differently if speedrunning mode is active
(cond
;; Start a new game differently if speedrunning mode is active
((= (-> *pc-settings* speedrunner-mode?) #t)
(update-autosplit-jak1-new-game)
;; spawn at the warp gate
(initialize! *game-info* 'game (the-as game-save #f) "game-start")
;; disable hints (this seems to be overriden by your slot 1 save though)
(set! (-> *setting-control* default play-hints) #f)
;; skip intro cutscene
(close-specific-task! (game-task intro) (task-status need-resolution))
;; enable auto saving by default
(set! (-> *setting-control* default auto-save) #t))
(speedrun-start-run))
;; start the game normally
(else
(initialize! *game-info* 'game (the-as game-save #f) "intro-start")

View file

@ -759,6 +759,7 @@
(hint-0 #x1300)
(hint-511 #x14ff)
(speedrunner-mode #x1500)
(cutscene-skips #x1501)
;; GAME-TEXT-ID ENUM ENDS
)

View file

@ -2039,9 +2039,11 @@
;; Custom or Modified Code
(goal-src "pc/features/autosplit-h.gc")
(goal-src "pc/features/autosplit.gc" "autosplit-h" "task-control-h")
(goal-src "pc/features/speedruns-h.gc")
(goal-src "pc/features/speedruns.gc" "speedruns-h" "autosplit-h")
(goal-src "pc/pckernel-h.gc" "dma-buffer")
(goal-src "pc/util/pc-anim-util.gc" "target-h")
(goal-src "pc/pckernel.gc" "pc-anim-util" "settings" "video" "target-h" "autosplit-h")
(goal-src "pc/pckernel.gc" "pc-anim-util" "settings" "video" "target-h" "autosplit-h" "speedruns-h")
(goal-src "pc/subtitle.gc" "text" "pckernel" "hint-control" "loader-h" "gsound" "ambient")
(goal-src "pc/progress-pc.gc" "progress" "pckernel")
(goal-src "pc/util/anim-tester-x.gc" "pckernel" "gstring" "joint" "process-drawable" "art-h" "effect-control")

View file

@ -0,0 +1,4 @@
;;-*-Lisp-*-
(in-package goal)
(define-extern speedrun-start-run (function none))

View file

@ -0,0 +1,19 @@
;;-*-Lisp-*-
(in-package goal)
(defun speedrun-start-run ()
;; randomize game id so the autosplitter knows to restart
(update-autosplit-jak1-new-game)
;; spawn at the warp gate checkpoint
(initialize! *game-info* 'game (the-as game-save #f) "game-start")
;; disable hints (this seems to be overriden by your slot 1 save though)
(set! (-> *setting-control* default play-hints) #f)
;; ensure `force actors` is not enabled
(set! (-> *pc-settings* force-actors?) #f)
;; force FPS to `60`
(set-frame-rate! *pc-settings* 60)
;; skip intro cutscene
(close-specific-task! (game-task intro) (task-status need-resolution))
;; enable auto saving by default
(set! (-> *setting-control* default auto-save) #t)
(none))

View file

@ -318,6 +318,7 @@
(discord-rpc? symbol) ;; enable discord rich presence integration
(speedrunner-mode? symbol) ;; enable speedrunner mode
(cutscene-skips? symbol) ;; enable cutscene skips
(cheats pc-cheats)
(cheats-known pc-cheats)
@ -421,6 +422,7 @@
(set! (-> obj aspect-custom-y) 3)
(set! (-> obj discord-rpc?) #t)
(set! (-> obj speedrunner-mode?) #f)
(set! (-> obj cutscene-skips?) #t)
(set! (-> obj window-lock?) #t)
(reset-gfx obj)

View file

@ -98,7 +98,6 @@
(defmethod set-frame-rate! pc-settings ((obj pc-settings) (rate int))
"set the target framerate."
(pc-set-frame-rate rate)
(if (and (!= 'fullscreen (-> obj display-mode))
(!= (pc-get-screen-rate -1) rate))
@ -874,6 +873,7 @@
(("hinttitles?") (set! (-> obj hinttitles?) (file-stream-read-symbol file)))
(("discord-rpc?") (set! (-> obj discord-rpc?) (file-stream-read-symbol file)))
(("speedrunner-mode?") (set! (-> obj speedrunner-mode?) (file-stream-read-symbol file)))
(("cutscene-skips?") (set! (-> obj cutscene-skips?) (file-stream-read-symbol file)))
(("first-camera-h-inverted?") (set! (-> obj first-camera-h-inverted?) (file-stream-read-symbol file)))
(("first-camera-v-inverted?") (set! (-> obj first-camera-v-inverted?) (file-stream-read-symbol file)))
(("third-camera-h-inverted?") (set! (-> obj third-camera-h-inverted?) (file-stream-read-symbol file)))
@ -1000,6 +1000,7 @@
(format file " (skip-movies? ~A)~%" (-> obj skip-movies?))
(format file " (discord-rpc? ~A)~%" (-> obj discord-rpc?))
(format file " (speedrunner-mode? ~A)~%" (-> obj speedrunner-mode?))
(format file " (cutscene-skips? ~A)~%" (-> obj cutscene-skips?))
(format file " (first-camera-h-inverted? ~A)~%" (-> obj first-camera-h-inverted?))
(format file " (first-camera-v-inverted? ~A)~%" (-> obj first-camera-v-inverted?))
(format file " (third-camera-h-inverted? ~A)~%" (-> obj third-camera-h-inverted?))
@ -1158,8 +1159,8 @@
) ;; when debug_segment
(defun-debug draw-build-revision ()
(with-dma-buffer-add-bucket ((buf (-> (current-frame) debug-buf))
(defun draw-build-revision ()
(with-dma-buffer-add-bucket ((buf (-> (current-frame) global-buf))
(bucket-id debug-no-zbuf))
(draw-string-xy *pc-settings-built-sha*
buf

View file

@ -166,6 +166,7 @@
(define *misc-options* (new 'static 'boxed-array :type game-option
(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 on-off) :name (game-text-id discord-rpc) :scale #t)
(new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id cutscene-skips) :scale #t)
(new 'static 'game-option :option-type (game-option-type on-off) :name (game-text-id speedrunner-mode) :scale #t)
(new 'static 'game-option :option-type (game-option-type button) :name (game-text-id back) :scale #t)
)
@ -745,27 +746,37 @@
(set! (-> *game-options-pc* 5 value-to-modify) (&-> *progress-carousell* int-backup))
(set! (-> *game-options-pc* 6 value-to-modify) (&-> *progress-carousell* int-backup))
(set! (-> *game-options-pc* 7 value-to-modify) (&-> *progress-carousell* int-backup))
(set! (-> *graphic-options-pc* 1 value-to-modify) (&-> *progress-carousell* int-backup))
(set! (-> *graphic-options-pc* 2 value-to-modify) (&-> *pc-settings* monitor))
(set! (-> *graphic-options-pc* 3 value-to-modify) (&-> *pc-settings* vsync?))
(set! (-> *graphic-options-pc* 5 value-to-modify) (&-> *progress-carousell* int-backup))
(set! (-> *graphic-options-pc* 6 value-to-modify) (&-> *progress-carousell* int-backup))
;; disable changes to frame-rate while in speedrunner mode
(set! (-> *graphic-options-pc* 6 option-disabled-func) (lambda () (-> *pc-settings* speedrunner-mode?)))
(set! (-> *graphic-options-no-frame-rate-pc* 1 value-to-modify) (&-> *progress-carousell* int-backup))
(set! (-> *graphic-options-no-frame-rate-pc* 2 value-to-modify) (&-> *pc-settings* vsync?))
(set! (-> *graphic-options-no-frame-rate-pc* 4 value-to-modify) (&-> *progress-carousell* int-backup))
(set! (-> *misc-options* 0 value-to-modify) (&-> *pc-settings* money-starburst?))
(set! (-> *misc-options* 1 value-to-modify) (&-> *pc-settings* discord-rpc?))
(set! (-> *misc-options* 2 value-to-modify) (&-> *pc-settings* speedrunner-mode?))
(set! (-> *misc-options* 2 value-to-modify) (&-> *pc-settings* cutscene-skips?))
(set! (-> *misc-options* 3 value-to-modify) (&-> *pc-settings* speedrunner-mode?))
(set! (-> *camera-options* 0 value-to-modify) (&-> *pc-settings* first-camera-h-inverted?))
(set! (-> *camera-options* 1 value-to-modify) (&-> *pc-settings* first-camera-v-inverted?))
(set! (-> *camera-options* 2 value-to-modify) (&-> *pc-settings* third-camera-h-inverted?))
(set! (-> *camera-options* 3 value-to-modify) (&-> *pc-settings* third-camera-v-inverted?))
(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! (-> *gfx-ps2-options* 3 value-to-modify) (&-> *pc-settings* force-envmap?))
;(set! (-> *gfx-ps2-options* 3 value-to-modify) (&-> *pc-settings* force-actors?))
(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))
@ -1116,6 +1127,11 @@
)
((or (cpad-pressed? 0 x) (cpad-pressed? 0 circle))
;; pressed x or circle. advance!
;; first check if the option is disabled, if so leave early and do nothing
(when (and (!= (-> options (-> obj option-index) option-disabled-func) 0)
((-> options (-> obj option-index) option-disabled-func)))
(sound-play "menu-stats")
(return #f))
(cond
((not (-> obj selected-option))
;; no option already selected.
@ -1535,16 +1551,8 @@
(sound-volume-off)
(set! (-> *game-info* mode) 'play)
;; Start a new game differently if speedrunning mode is active
(cond ((= (-> *pc-settings* speedrunner-mode?) #t)
(update-autosplit-jak1-new-game)
;; spawn at the warp gate
(initialize! *game-info* 'game (the-as game-save #f) "game-start")
;; disable hints (this seems to be overriden by your slot 1 save though)
(set! (-> *setting-control* default play-hints) #f)
;; skip intro cutscene
(close-specific-task! (game-task intro) (task-status need-resolution))
;; enable auto saving by default
(set! (-> *setting-control* default auto-save) #t))
(cond ((-> *pc-settings* speedrunner-mode?)
(speedrun-start-run))
;; start the game normally
(else
(initialize! *game-info* 'game (the-as game-save #f) "intro-start")))
@ -1562,16 +1570,8 @@
(sound-volume-off)
(set! (-> *game-info* mode) 'play)
;; Start a new game differently if speedrunning mode is active
(cond ((= (-> *pc-settings* speedrunner-mode?) #t)
(update-autosplit-jak1-new-game)
;; spawn at the warp gate
(initialize! *game-info* 'game (the-as game-save #f) "game-start")
;; disable hints (this seems to be overriden by your slot 1 save though)
(set! (-> *setting-control* default play-hints) #f)
;; skip intro cutscene
(close-specific-task! (game-task intro) (task-status need-resolution))
;; enable auto saving by default
(set! (-> *setting-control* default auto-save) #t))
(cond ((-> *pc-settings* speedrunner-mode?)
(speedrun-start-run))
;; start the game normally
(else
(initialize! *game-info* 'game (the-as game-save #f) "intro-start")))
@ -1659,16 +1659,8 @@
(sound-volume-off)
(set! (-> *game-info* mode) 'play)
;; Start a new game differently if speedrunning mode is active
(cond ((= (-> *pc-settings* speedrunner-mode?) #t)
(update-autosplit-jak1-new-game)
;; spawn at the warp gate
(initialize! *game-info* 'game (the-as game-save #f) "game-start")
;; disable hints (this seems to be overriden by your slot 1 save though)
(set! (-> *setting-control* default play-hints) #f)
;; skip intro cutscene
(close-specific-task! (game-task intro) (task-status need-resolution))
;; enable auto saving by default
(set! (-> *setting-control* default auto-save) #t))
(cond ((-> *pc-settings* speedrunner-mode?)
(speedrun-start-run))
;; start the game normally
(else
(initialize! *game-info* 'game (the-as game-save #f) "intro-start")))
@ -1777,6 +1769,10 @@
(option-y y-off)
(locked? #f)
)
;; Check if the option should be disabled
(when (and (!= (-> options index option-disabled-func) 0)
((-> options index option-disabled-func)))
(set! locked? #t))
(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.

View file

@ -74,6 +74,9 @@ class Compiler {
void add_ignored_define_extern_symbol(const std::string& name) {
m_allow_inconsistent_definition_symbols.insert(name);
}
void add_ignored_type_definition(const std::string& type_name) {
m_ts.add_type_to_allowed_redefinition_list(type_name);
}
Debugger& get_debugger() { return m_debugger; }
listener::Listener& listener() { return m_listener; }
void poke_target() { m_listener.send_poke(); }

View file

@ -1,7 +1,7 @@
#include "goalc/compiler/Compiler.h"
#include "gtest/gtest.h"
void add_expected_type_mismatches(Compiler& c) {
void add_common_expected_type_mismatches(Compiler& c) {
c.add_ignored_define_extern_symbol("draw-drawable-tree-tfrag");
c.add_ignored_define_extern_symbol("draw-drawable-tree-trans-tfrag");
c.add_ignored_define_extern_symbol("draw-drawable-tree-dirt-tfrag");
@ -9,18 +9,26 @@ void add_expected_type_mismatches(Compiler& c) {
c.add_ignored_define_extern_symbol("tfrag-init-buffer");
}
void add_jak1_expected_type_mismatches(Compiler& c) {
c.add_ignored_type_definition("game-option");
}
// TODO - debatably delete these now that jak 1 is complete
TEST(Jak1TypeConsistency, MANUAL_TEST_TypeConsistencyWithBuildFirst) {
Compiler compiler(GameVersion::Jak1);
compiler.enable_throw_on_redefines();
add_expected_type_mismatches(compiler);
add_common_expected_type_mismatches(compiler);
add_jak1_expected_type_mismatches(compiler);
compiler.run_test_no_load("test/goalc/source_templates/with_game/test-build-all-code.gc");
compiler.run_test_no_load("decompiler/config/all-types.gc");
}
// TODO - debatably delete these now that jak 1 is complete
TEST(Jak1TypeConsistency, TypeConsistency) {
Compiler compiler(GameVersion::Jak1);
compiler.enable_throw_on_redefines();
add_expected_type_mismatches(compiler);
add_common_expected_type_mismatches(compiler);
add_jak1_expected_type_mismatches(compiler);
compiler.run_test_no_load("decompiler/config/all-types.gc");
compiler.run_test_no_load("test/goalc/source_templates/with_game/test-build-all-code.gc");
}
@ -28,7 +36,7 @@ TEST(Jak1TypeConsistency, TypeConsistency) {
TEST(Jak2TypeConsistency, TypeConsistency) {
Compiler compiler(GameVersion::Jak2);
compiler.enable_throw_on_redefines();
add_expected_type_mismatches(compiler);
add_common_expected_type_mismatches(compiler);
compiler.run_test_no_load("decompiler/config/jak2/all-types.gc");
compiler.run_test_no_load("test/goalc/source_templates/with_game/test-build-all-code.gc");
}