g/j2: Fill out game options menu (#3003)

This commit is contained in:
Tyler Wilding
2023-09-23 13:08:13 -06:00
committed by GitHub
parent 4871f5dfc7
commit 10910400fa
20 changed files with 1360 additions and 207 deletions
+12
View File
@@ -1876,6 +1876,18 @@ const GameTextFontBank* get_font_bank(GameTextVersion version) {
return g_font_banks.at(version);
}
const GameTextFontBank* get_font_bank_from_game_version(GameVersion version) {
// Jak 1 has been patched to use V2
switch (version) {
case GameVersion::Jak1:
return get_font_bank(GameTextVersion::JAK1_V2);
case GameVersion::Jak2:
return get_font_bank(GameTextVersion::JAK2);
default:
ASSERT_MSG(false, "Unsupported game for get_font_bank_from_game_version");
}
}
const GameTextFontBank* get_font_bank(const std::string& name) {
if (auto it = sTextVerEnumMap.find(name); it == sTextVerEnumMap.end()) {
throw std::runtime_error(fmt::format("unknown text version {}", name));
+2
View File
@@ -16,6 +16,7 @@
#include <vector>
#include "common/common_types.h"
#include "common/versions/versions.h"
// version of the game text file's text encoding. Not real, but we need to differentiate them
// somehow, since the encoding changes.
@@ -92,5 +93,6 @@ extern GameTextFontBank g_font_bank_jak2;
extern std::map<GameTextVersion, GameTextFontBank*> g_font_banks;
const GameTextFontBank* get_font_bank(GameTextVersion version);
const GameTextFontBank* get_font_bank_from_game_version(GameVersion version);
const GameTextFontBank* get_font_bank(const std::string& name);
bool font_bank_exists(GameTextVersion version);
+21
View File
@@ -205,7 +205,28 @@ std::string to_lower(const std::string& str) {
std::transform(str.begin(), str.end(), new_str.begin(), ::tolower);
return new_str;
}
bool hex_char(char c) {
return !((c < '0' || c > '9') && (c < 'a' || c > 'f') && (c < 'A' || c > 'F'));
}
std::string titlize(const std::string& str) {
// Iterate through the string, capitalizing any character that either comes first, or is preceeded
// by whitespace
const auto trimmed_string = trim(str);
std::string new_str = "";
bool capitalize_next_char = true;
for (const auto& character : trimmed_string) {
if (capitalize_next_char) {
new_str.push_back(toupper(character));
capitalize_next_char = false;
} else {
if (character == ' ') {
capitalize_next_char = true;
}
new_str.push_back(character);
}
}
return new_str;
}
} // namespace str_util
+1
View File
@@ -32,4 +32,5 @@ std::string to_upper(const std::string& str);
std::string to_lower(const std::string& str);
/// Is this a valid character for a hex number?
bool hex_char(char c);
std::string titlize(const std::string& str);
} // namespace str_util
+24 -1
View File
@@ -7353,7 +7353,6 @@
(progress-camera-options-first-vert #x1282)
(progress-camera-options-third-horz #x1283)
(progress-camera-options-third-vert #x1284)
(progress-reset-to-default #x1285)
(progress-normal #x1286)
(progress-inverted #x1287)
(progress-ps2-parts #x1288)
@@ -7365,6 +7364,30 @@
(progress-frame-rate #x128e)
(progress-misc-game-options #x128f)
(progress-speedrunner-mode #x1290)
(progress-menu-input-options #x1291)
(progress-restore-defaults #x1292)
(progress-menu-controller-options #x1293)
(progress-controller-options-select-controller #x1294)
(progress-controller-options-analog-deadzone #x1295)
(progress-controller-options-ignore-if-unfocused #x1296)
(progress-controller-options-led-hp #x1297)
(progress-controller-options-led-darkjak #x1298)
(progress-input-options-enable-keyboard #x1299)
(progress-input-options-enable-mouse #x129a)
(progress-menu-mouse-options #x129b)
(progress-mouse-options-track-camera #x129c)
(progress-mouse-options-horz-sens #x129d)
(progress-mouse-options-vert-sens #x129e)
(progress-mouse-options-player-movement #x129f)
(progress-input-options-auto-hide-cursor #x1300)
(progress-menu-reassign-binds #x1301)
(progress-reassign-binds-controller #x1302)
(progress-reassign-binds-keyboard #x1303)
(progress-reassign-binds-mouse #x1304)
(progress-multiselect-no-items-found #x1305)
(progress-keybinds-waiting-for-bind #x1306)
(progress-keybinds-unset #x1307)
(progress-unknown-option #x1308)
)
;; ---text-id-h:text-id
@@ -0,0 +1,30 @@
{
"1280": "1000",
"1286": "1001",
"1287": "1002",
"1289": "1030",
"128e": "1060",
"128f": "100f",
"1290": "1500",
"1291": "1600",
"1292": "1007",
"1293": "160d",
"1294": "1601",
"1295": "1602",
"1296": "1603",
"1297": "1604",
"1299": "160e",
"129a": "160f",
"129b": "1610",
"129c": "1606",
"129d": "1607",
"129e": "1608",
"129f": "1609",
"1300": "1613",
"1301": "1611",
"1302": "160a",
"1303": "160b",
"1304": "160c",
"1307": "1614",
"1308": "1615"
}
@@ -108,10 +108,10 @@
"1261": "Bad Weather",
"1262": "Nice Weather",
"1280": "Camera Options",
"1281": "Left/Right (First Person)",
"1282": "Up/Down (First Person)",
"1283": "Left/Right (Third Person)",
"1284": "Up/Down (Third Person)",
"1281": "Left/Right (1st Person)",
"1282": "Up/Down (1st Person)",
"1283": "Left/Right (3rd Person)",
"1284": "Up/Down (3rd Person)",
"1285": "Reset to Default",
"1286": "Normal",
"1287": "Inverted",
@@ -122,6 +122,30 @@
"128c": "High",
"128d": "Credits",
"128e": "Frame Rate (Experimental)",
"128f": "Misc. Options",
"1290": "Speedrunner Mode"
"128f": "Miscellaneous",
"1290": "Speedrunner Mode",
"1291": "Input Options",
"1292": "Restore Defaults",
"1293": "Controller Options",
"1294": "Select Controller",
"1295": "Analog Deadzone",
"1296": "Ignore If Window Unfocused",
"1297": "Controller Led For HP",
"1298": "Controller Led For Dark Jak",
"1299": "Enable Keyboard",
"129a": "Enable Mouse",
"129b": "Mouse Options",
"129c": "Track Camera",
"129d": "Horizontal Sensitivity",
"129e": "Vertical Sensitivity",
"129f": "Player Movement",
"1300": "Auto Hide Cursor",
"1301": "Reassign Binds",
"1302": "Controller Binds",
"1303": "Keyboard Binds",
"1304": "Mouse Binds",
"1305": "No Options",
"1306": "Waiting",
"1307": "Unset",
"1308": "Unknown"
}
+22
View File
@@ -0,0 +1,22 @@
# Jak 2 shares many of the same custom menu strings as jak 1 obviously
# this is to copy them over so they are already translated.
# TODO - make it enumerate all languages
import json
with open("temp-text-id-mapping.json", "r", encoding="utf-8") as f:
mapping = json.load(f)
with open("./text/game_custom_text_en-US.json", "r", encoding="utf-8") as f:
jak2_file = json.load(f)
with open("../jak1/text/game_custom_text_en-US.json", "r", encoding="utf-8") as f:
jak1_file = json.load(f)
for jak2_id, jak1_id in mapping.items():
jak2_file[jak2_id] = jak1_file[jak1_id].title()
with open("./text/game_custom_text_en-US.json", "w", encoding="utf-8") as f:
json.dump(jak2_file, f, indent=2)
+28 -3
View File
@@ -6,6 +6,7 @@
#include "common/log/log.h"
#include "common/symbols.h"
#include "common/util/FileUtil.h"
#include "common/util/FontUtils.h"
#include "common/util/Timer.h"
#include "common/util/string_util.h"
@@ -455,7 +456,15 @@ u64 pc_get_display_name(u32 id, u32 str_dest_ptr) {
if (name.empty()) {
return bool_to_symbol(false);
}
strcpy(Ptr<String>(str_dest_ptr).c()->data(), str_util::to_upper(name).c_str());
if (g_game_version == GameVersion::Jak1) {
// The Jak 1 font has only caps
name = str_util::to_upper(name).c_str();
}
// Encode the string to the game font
const auto encoded_name = get_font_bank_from_game_version(g_game_version)
->convert_utf8_to_game(str_util::titlize(name).c_str());
strcpy(Ptr<String>(str_dest_ptr).c()->data(), encoded_name.c_str());
strcpy(Ptr<String>(str_dest_ptr).c()->data(), str_util::titlize(encoded_name).c_str());
return bool_to_symbol(true);
}
@@ -600,7 +609,16 @@ u64 pc_get_controller_name(u32 id, u32 str_dest_ptr) {
if (name.empty()) {
return bool_to_symbol(false);
}
strcpy(Ptr<String>(str_dest_ptr).c()->data(), str_util::to_upper(name).c_str());
if (g_game_version == GameVersion::Jak1) {
// The Jak 1 font has only caps
name = str_util::to_upper(name).c_str();
}
// Encode the string to the game font
const auto encoded_name = get_font_bank_from_game_version(g_game_version)
->convert_utf8_to_game(str_util::titlize(name).c_str());
strcpy(Ptr<String>(str_dest_ptr).c()->data(), encoded_name.c_str());
strcpy(Ptr<String>(str_dest_ptr).c()->data(), str_util::titlize(encoded_name).c_str());
return bool_to_symbol(true);
}
@@ -624,7 +642,14 @@ u64 pc_get_current_bind(s32 bind_assignment_info, u32 str_dest_ptr) {
if (name.empty()) {
return bool_to_symbol(false);
}
strcpy(Ptr<String>(str_dest_ptr).c()->data(), str_util::to_upper(name).c_str());
if (g_game_version == GameVersion::Jak1) {
// The Jak 1 font has only caps
name = str_util::to_upper(name).c_str();
}
// Encode the string to the game font
const auto encoded_name = get_font_bank_from_game_version(g_game_version)
->convert_utf8_to_game(str_util::titlize(name).c_str());
strcpy(Ptr<String>(str_dest_ptr).c()->data(), encoded_name.c_str());
return bool_to_symbol(true);
}
// TODO - return something that lets the runtime use a translatable string if unknown
+1 -1
View File
@@ -801,7 +801,7 @@
(define *temp-string* (new 'global 'string 256 (the string #f)))
(define *temp-string2* (new 'global 'string 256 (the string #f)))
(define *pc-cpp-temp-string*
"A conveniant place to retrieve a string from C++"
"A convenient place to retrieve a string from C++"
(new 'global 'string 256 (the-as string #f)))
(defmacro string-format (&rest args)
@@ -6709,7 +6709,9 @@
(set-hud-piece-position! (-> obj sprites 3) (+ sv-64 242 s1-0) (+ s2-0 -4))
(set! sv-256 (-> *display* frames (-> *display* on-screen) global-buf))
(set! sv-272 (-> sv-256 base))
;; bar
((method-of-type hud-sprite draw) (the-as hud-sprite (-> obj sprites)) sv-256 (-> *level* default-level))
;; bar background
(draw-sprite2d-xy
sv-256
(+ s1-0 s0-0 (the int (* 230.0 (-> (the-as (pointer float) sv-208)))))
@@ -6718,8 +6720,11 @@
9
(the-as rgba sv-240)
)
;; notch
(draw (-> obj sprites 1) sv-256 (-> *level* default-level))
;; left icon
(draw (-> obj sprites 2) sv-256 (-> *level* default-level))
;; right icon
(draw (-> obj sprites 3) sv-256 (-> *level* default-level))
(let ((a3-13 (-> sv-256 base)))
(let ((v1-183 (the-as object (-> sv-256 base))))
+24 -1
View File
@@ -681,7 +681,6 @@
(progress-camera-options-first-vert #x1282)
(progress-camera-options-third-horz #x1283)
(progress-camera-options-third-vert #x1284)
(progress-reset-to-default #x1285)
(progress-normal #x1286)
(progress-inverted #x1287)
(progress-ps2-parts #x1288)
@@ -693,6 +692,30 @@
(progress-frame-rate #x128e)
(progress-misc-game-options #x128f)
(progress-speedrunner-mode #x1290)
(progress-menu-input-options #x1291)
(progress-restore-defaults #x1292)
(progress-menu-controller-options #x1293)
(progress-controller-options-select-controller #x1294)
(progress-controller-options-analog-deadzone #x1295)
(progress-controller-options-ignore-if-unfocused #x1296)
(progress-controller-options-led-hp #x1297)
(progress-controller-options-led-darkjak #x1298)
(progress-input-options-enable-keyboard #x1299)
(progress-input-options-enable-mouse #x129a)
(progress-menu-mouse-options #x129b)
(progress-mouse-options-track-camera #x129c)
(progress-mouse-options-horz-sens #x129d)
(progress-mouse-options-vert-sens #x129e)
(progress-mouse-options-player-movement #x129f)
(progress-input-options-auto-hide-cursor #x1300)
(progress-menu-reassign-binds #x1301)
(progress-reassign-binds-controller #x1302)
(progress-reassign-binds-keyboard #x1303)
(progress-reassign-binds-mouse #x1304)
(progress-multiselect-no-items-found #x1305)
(progress-keybinds-waiting-for-bind #x1306)
(progress-keybinds-unset #x1307)
(progress-unknown-option #x1308)
)
;; ---text-id
+4 -2
View File
@@ -160,15 +160,16 @@
(define-extern __pc-get-tex-remap (function int int int))
;; Input Related Functions
;; TODO - add get current controller index
(define-extern pc-get-controller-count (function int))
(define-extern pc-get-controller-name (function int string))
(define-extern pc-get-controller-name (function int string string))
(deftype bind-assignment-info (structure)
((port int32)
(device-type int32)
(for-buttons? symbol)
(input-idx int32)
(analog-min-range? symbol)))
(define-extern pc-get-current-bind (function bind-assignment-info string))
(define-extern pc-get-current-bind (function bind-assignment-info string symbol))
(define-extern pc-waiting-for-bind? (function symbol))
(define-extern pc-set-waiting-for-bind! (function int symbol symbol int none))
(define-extern pc-stop-waiting-for-bind! (function none))
@@ -177,6 +178,7 @@
(define-extern pc-set-mouse-options! (function symbol symbol symbol none))
(define-extern pc-set-mouse-camera-sens! (function float float none))
(define-extern pc-current-controller-has-led? (function symbol))
(define-extern pc-current-controller-has-rumble? (function symbol))
(define-extern pc-set-controller-led! (function int int int int none))
(define-extern pc-ignore-background-controller-events! (function symbol none))
(define-extern pc-reset-bindings-to-defaults! (function int int none))
+4
View File
@@ -799,6 +799,10 @@
;; up from 256 bytes in jak 1
(define *temp-string* (new 'global 'string 2048 (the-as string #f)))
(define *pc-cpp-temp-string*
"A convenient place to retrieve a string from C++"
(new 'global 'string 2048 (the-as string #f)))
(defmacro string-format (&rest args)
"Formats into *temp-string* and returns it, for in-place string formating.
DO NOT USE *temp-string* WITH THIS MACRO! It is read as input AFTER all of the args evaluate."
+2
View File
@@ -432,3 +432,5 @@
(defmacro adjust-game-x (x)
`(adjust-game-x-centered CENTER_X ,x))
(defmacro adjust-game-x-int (x-float)
`(the int (adjust-game-x-centered CENTER_X (the float ,x-float))))
@@ -58,14 +58,13 @@
(defun draw-page-header ((font-ctx font-context) (text text-id))
(let ((x-pos 70)
(y-pos 85)
(y-pos 80)
(width 375))
(when (= (get-aspect-ratio) 'aspect16x9)
(set! x-pos 79)
(set! y-pos 55)
(set! width 356))
(set-scale! font-ctx 0.75)
(set! (-> font-ctx height) 20.0)
(set-scale! font-ctx 0.55)
(set! (-> font-ctx origin y) (the float y-pos))
(set-color! font-ctx (font-color progress))
(print-game-text (lookup-text! *common-text* text #f) font-ctx #f 44 (bucket-id progress)))
@@ -129,19 +128,23 @@
(restore-scissor hud-bounds buffer))
(none))
(defun-debug draw-generic-page-row-line ((y-coord int))
(with-dma-buffer-add-bucket ((buf (-> *display* frames (-> *display* on-screen) global-buf))
(bucket-id debug-no-zbuf2))
(draw-sprite2d-xy buf 0 y-coord 512 1 (static-rgba #xff #xff #xff #x40))))
(defmethod draw-option menu-generic-scrolling-page ((obj menu-generic-scrolling-page) (progress progress) (font-ctx font-context) (arg3 int) (arg4 symbol))
;; (inspect obj)
(when (or (zero? (-> obj mounted?)) (not (-> obj mounted?)))
(on-mount! obj))
;; the list has a total of 200px of y-height
;; with 10px of margin at the top and bottom, that leaves 180 / 4 = 45px per item
;; it's the responsibility of each generic component to center itself within these 45px lines
(when (not (-> *progress-pc-generic-store* clear-screen?))
(let ((font-alpha (fmax 0.0 (* 2.0 (- 0.5 (-> progress menu-transition)))))
(hud-bounds (new 'stack-no-clear 'hud-box))
(max-page-size (if (= (get-aspect-ratio) 'aspect16x9) 5 4))
(margin-top-bottom 10.0)
(line-height 45.0))
(let* ((font-alpha (fmax 0.0 (* 2.0 (- 0.5 (-> progress menu-transition)))))
(hud-bounds (new 'stack-no-clear 'hud-box))
(max-page-size (if (= (get-aspect-ratio) 'aspect16x9) 7 5))
(margin-top-bottom 0.0)
(line-height (/ (if (= (get-aspect-ratio) 'aspect16x9) 253.0 200.0) max-page-size)))
(set! (-> font-ctx alpha) font-alpha)
(set-color! font-ctx (font-color progress))
;; header
@@ -155,19 +158,21 @@
(set! (-> font-ctx origin y) (+ 86.0 margin-top-bottom))
(set! (-> font-ctx origin y) (+ 112.0 margin-top-bottom)))
;; render items
(let* ((menu-option-index (if (< (-> *progress-pc-generic-store* current-menu-hover-index) max-page-size)
0
(-> *progress-pc-generic-store* current-menu-hover-index)))
(let* ((menu-option-index (max 0 (* (/ (-> *progress-pc-generic-store* current-menu-hover-index) max-page-size) max-page-size)))
(end-index (min (-> obj menu-options length) (+ menu-option-index max-page-size))))
(while (< menu-option-index end-index)
(let ((menu-option (-> obj menu-options menu-option-index)))
(when (nonzero? menu-option)
;; save the y position as who knows where it will end up after the component finishes rendering
(let ((old-y-pos (-> font-ctx origin y)))
;; save the y,x position as who knows where it will end up after the component finishes rendering
(let ((old-y-pos (-> font-ctx origin y))
(old-x-pos (-> font-ctx origin x)))
(draw-option menu-option progress font-ctx menu-option-index
(= (-> obj selected-option-index) menu-option-index))
;; move to the next line
(set! (-> font-ctx origin y) (+ old-y-pos line-height))
;; - debugging, draw the dividing lines to make centering new items easier
(draw-generic-page-row-line (the int (-> font-ctx origin y)))
(set! (-> font-ctx origin x) old-x-pos)
;; reset the font color
(set-color! font-ctx (font-color progress)))))
(+! menu-option-index 1)))
@@ -192,34 +197,31 @@
(width (if (= (get-aspect-ratio) 'aspect4x3)
374
500)))
;; og:preserve-this
(#when PC_PORT
;; added for better widescreen handling
(when (not (-> *pc-settings* use-vis?))
(set! x-pos (the int (adjust-game-x (the float x-pos))))
(set! width (the int (* (-> *pc-settings* aspect-ratio-reciprocal) width)))))
(when (not (-> *pc-settings* use-vis?))
(set! x-pos (the int (adjust-game-x (the float x-pos))))
(set! width (the int (* (-> *pc-settings* aspect-ratio-reciprocal) width))))
(with-dma-buffer-add-bucket ((buffer (-> *display* frames (-> *display* on-screen) global-buf))
(bucket-id progress)
)
(draw-sprite2d-xy buffer x-pos y-pos width height
(new 'static 'rgba :r #x40 :g #x80 :b #x80 :a (the int (* 64.0 alpha)))))))
(defmethod draw-option menu-generic-boolean-option ((obj menu-generic-boolean-option) (arg0 progress) (arg1 font-context) (option-index int) (selected? symbol))
(defmethod draw-option menu-generic-boolean-option ((obj menu-generic-boolean-option) (arg0 progress) (font-ctx font-context) (option-index int) (selected? symbol))
(when (not (-> obj mounted?))
(on-mount! obj))
(let ((alpha (* 2.0 (- 0.5 (-> arg0 menu-transition))))
(line-height 23.0))
(line-height 18.0))
(max! alpha 0.0)
(set! (-> arg1 alpha) alpha)
(set-flags! arg1 (font-flags kerning middle large))
(set-scale! arg1 0.65)
(+! (-> arg1 origin y) 5.0)
(set! (-> font-ctx alpha) alpha)
(set-flags! font-ctx (font-flags kerning middle large))
(set-scale! font-ctx 0.45)
(+! (-> font-ctx origin y) (if (= (get-aspect-ratio) 'aspect4x3) 7.0 5.0))
(cond
(selected?
(set-color! arg1 (font-color progress-force-selected))
(draw-generic-highlight (the int (+ -1.0 (-> arg1 origin y))) 41 alpha)
(print-game-text (lookup-text! *common-text* (-> obj name) #f) arg1 #f 44 (bucket-id progress))
(+! (-> arg1 origin y) line-height)
(set-color! font-ctx (font-color progress-force-selected))
(draw-generic-highlight (the int (- (-> font-ctx origin y) 2.0)) 32 alpha)
(print-game-text (lookup-text! *common-text* (-> obj name) #f) font-ctx #f 44 (bucket-id progress))
(+! (-> font-ctx origin y) line-height)
(set! *temp-string* (clear *temp-string*))
(if (-> obj value)
(format *temp-string* "~33L~S~35L ~S" (lookup-text! *common-text* (-> obj truthy-text) #f) (lookup-text! *common-text* (-> obj falsey-text) #f))
@@ -227,22 +229,26 @@
;; hover case
(else
(cond
((and (nonzero? (-> obj should-disable?))
(!= (-> obj should-disable?) #f)
((-> obj should-disable?)))
(set-color! font-ctx (font-color progress-option-off))
(when (= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(draw-generic-highlight (the int (+ -1.0 (-> font-ctx origin y))) 15 0.5)))
((= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(set-color! arg1 (progress-selected 0))
(draw-generic-highlight (the int (+ -1.0 (-> arg1 origin y))) 22 alpha))
(set-color! font-ctx (progress-selected 0))
(draw-generic-highlight (the int (+ -1.0 (-> font-ctx origin y))) 15 alpha))
(else
(set-color! arg1 (font-color progress))))
(print-game-text (lookup-text! *common-text* (-> obj name) #f) arg1 #f 44 (bucket-id progress))
(+! (-> arg1 origin y) line-height)
(set-color! font-ctx (font-color progress))))
(print-game-text (lookup-text! *common-text* (-> obj name) #f) font-ctx #f 44 (bucket-id progress))
(+! (-> font-ctx origin y) line-height)
(set! *temp-string* (clear *temp-string*))
(let ((actual-value (if (and (nonzero? (-> obj get-value-fn)) (!= (-> obj get-value-fn) #f))
((-> obj get-value-fn))
#f)))
(let ((actual-value (call-get-value-fn obj)))
(if actual-value
(format *temp-string* "~1L~S~35L ~S" (lookup-text! *common-text* (-> obj truthy-text) #f) (lookup-text! *common-text* (-> obj falsey-text) #f))
(format *temp-string* "~35L~S ~1L~S~1L" (lookup-text! *common-text* (-> obj truthy-text) #f) (lookup-text! *common-text* (-> obj falsey-text) #f))))))
(set-scale! arg1 0.5)
(print-game-text *temp-string* arg1 #f 44 (bucket-id progress)))
(set-scale! font-ctx 0.35)
(print-game-text *temp-string* font-ctx #f 44 (bucket-id progress)))
(none))
(defmethod draw-option menu-generic-carousel-option ((obj menu-generic-carousel-option)
@@ -253,60 +259,330 @@
(when (not (-> obj mounted?))
(on-mount! obj))
(let ((alpha (fmax (* 2.0 (- 0.5 (-> progress menu-transition))) 0.0)))
(set! (-> font-ctx scale) 0.65)
(set! (-> font-ctx scale) 0.45)
(set! (-> font-ctx alpha) alpha)
(+! (-> font-ctx origin y) 2.5)
(+! (-> font-ctx origin y) 5.0)
(set-flags! font-ctx (font-flags kerning middle large))
;; the item label
(cond
(selected?
(set! (-> font-ctx color) (font-color progress-force-selected))
(draw-generic-highlight (the int (-> font-ctx origin y)) 44 alpha))
(draw-generic-highlight (the int (- (-> font-ctx origin y) 1.0)) 30 alpha))
((and (nonzero? (-> obj should-disable?))
(!= (-> obj should-disable?) #f)
((-> obj should-disable?)))
(set-color! font-ctx (font-color progress-option-off))
(when (= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(draw-generic-highlight (the int (+ -1.0 (-> font-ctx origin y))) 15 0.5)))
((= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(set! (-> font-ctx color) (progress-selected 0))
(draw-generic-highlight (the int (-> font-ctx origin y)) 24 alpha)))
(format (clear *temp-string*) "~S" (lookup-text! *common-text* (-> obj name) #f))
(print-game-text *temp-string* font-ctx #f 44 (bucket-id progress))
(+! (-> font-ctx origin y) 24.0)
(set! (-> font-ctx scale) 0.5)
(draw-generic-highlight (the int (- (-> font-ctx origin y) 1.0)) 16 alpha)))
(print-game-text (lookup-text! *common-text* (-> obj name) #f) font-ctx #f 44 (bucket-id progress))
(+! (-> font-ctx origin y) 18.0)
(set! (-> font-ctx scale) 0.35)
(set! (-> font-ctx color) (font-color progress))
(when selected?
;; left arrow
(+! (-> font-ctx origin x) -70.0)
(format (clear *temp-string*) "~33L~C" 163)
(print-game-text *temp-string* font-ctx #f 44 (bucket-id progress))
(+! (-> font-ctx origin x) 70.0)
(+! (-> font-ctx origin x) 70.0)
;; right arrow
(format (clear *temp-string*) "~33L~C" 161)
(print-game-text *temp-string* font-ctx #f 44 (bucket-id progress))
(+! (-> font-ctx origin x) -70.0)
(set! (-> font-ctx color) (progress-selected 0)))
;; the value
;; TODO - bounds checking would be smart
(if selected?
(print-game-text (lookup-text! *common-text* (-> obj items (-> obj item-index)) #f) font-ctx #f 44 (bucket-id progress))
(let ((actual-index (if (and (nonzero? (-> obj get-item-index-fn)) (!= (-> obj get-item-index-fn) #f))
((-> obj get-item-index-fn))
0)))
(print-game-text (lookup-text! *common-text* (-> obj items actual-index) #f) font-ctx #f 44 (bucket-id progress)))))
(cond
((or (< (-> obj item-index) 0) (> (-> obj item-index) (num-items obj)))
(print-game-text (lookup-text! *common-text* (text-id progress-multiselect-no-items-found) #f) font-ctx #f 44 (bucket-id progress)))
((and selected? (>= (-> obj item-index) 0) (< (-> obj item-index) (num-items obj)))
(format (clear *temp-string*) "~33L~C ~S ~33L~C" 163 (get-item-label obj (-> obj item-index)) 161)
(print-game-text *temp-string* font-ctx #f 44 (bucket-id progress)))
(else
(let ((actual-index (call-get-item-index-fn obj)))
(print-game-text (get-item-label obj actual-index) font-ctx #f 44 (bucket-id progress))))))
(none))
(defmethod draw-option menu-generic-link-option ((obj menu-generic-link-option) (arg0 progress) (arg1 font-context) (option-index int) (selected? symbol))
(when (not (-> obj mounted?))
(on-mount! obj))
(let ((alpha (* 2.0 (- 0.5 (-> arg0 menu-transition))))
(defun draw-generic-simple-string-option ((option menu-generic-option) (progress progress) (font-ctx font-context) (option-index int) (str string))
(let ((alpha (* 2.0 (- 0.5 (-> progress menu-transition))))
(line-height 23.0))
(max! alpha 0.0)
(set! (-> arg1 alpha) alpha)
(set-flags! arg1 (font-flags kerning middle large))
(set-scale! arg1 0.65)
(+! (-> arg1 origin y) 12.5)
(set! (-> font-ctx alpha) alpha)
(set-flags! font-ctx (font-flags kerning middle large))
(set-scale! font-ctx 0.45)
(+! (-> font-ctx origin y) (if (= (get-aspect-ratio) 'aspect4x3) 14.0 11.0))
(cond
((and (nonzero? (-> option should-disable?))
(!= (-> option should-disable?) #f)
((-> option should-disable?)))
(set-color! font-ctx (font-color progress-option-off))
(when (= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(draw-generic-highlight (the int (+ -1.0 (-> font-ctx origin y))) 15 0.5)))
((= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(set-color! font-ctx (progress-selected 0))
(draw-generic-highlight (the int (+ -1.0 (-> font-ctx origin y))) 17 alpha))
(else
(set-color! font-ctx (font-color progress))))
(print-game-text str font-ctx #f 44 (bucket-id progress)))
(none))
(defmethod draw-option menu-generic-link-option ((obj menu-generic-link-option) (progress progress) (font-ctx font-context) (option-index int) (selected? symbol))
(when (not (-> obj mounted?))
(on-mount! obj))
(draw-generic-simple-string-option obj progress font-ctx option-index (lookup-text! *common-text* (-> obj name) #f))
(none))
(defmethod draw-option menu-generic-confirm-option ((obj menu-generic-confirm-option) (progress progress) (font-ctx font-context) (option-index int) (selected? symbol))
(when (not (-> obj mounted?))
(on-mount! obj))
;; drawn different depending on whether or not the confirmation prompt is open
(cond
(selected?
;; TODO - this is duplicate code with the boolean option, but i ran out of arguments, make a struct or something later
(let ((alpha (* 2.0 (- 0.5 (-> progress menu-transition))))
(line-height 18.0))
(max! alpha 0.0)
(set! (-> font-ctx alpha) alpha)
(set-flags! font-ctx (font-flags kerning middle large))
(set-scale! font-ctx 0.45)
(+! (-> font-ctx origin y) (if (= (get-aspect-ratio) 'aspect4x3) 7.0 5.0))
(cond
(selected?
(set-color! font-ctx (font-color progress-force-selected))
(draw-generic-highlight (the int (- (-> font-ctx origin y) 2.0)) 32 alpha)
(print-game-text (lookup-text! *common-text* (-> obj name) #f) font-ctx #f 44 (bucket-id progress))
(+! (-> font-ctx origin y) line-height)
(set! *temp-string* (clear *temp-string*))
(if (-> obj confirmed?)
(format *temp-string* "~33L~S~35L ~S" (lookup-text! *common-text* (text-id progress-yes) #f) (lookup-text! *common-text* (text-id progress-no) #f))
(format *temp-string* "~35L~S ~33L~S~1L" (lookup-text! *common-text* (text-id progress-yes) #f) (lookup-text! *common-text* (text-id progress-no) #f))))
;; hover case
(else
(cond
((and (nonzero? (-> obj should-disable?))
(!= (-> obj should-disable?) #f)
((-> obj should-disable?)))
(set-color! font-ctx (font-color progress-option-off))
(when (= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(draw-generic-highlight (the int (+ -1.0 (-> font-ctx origin y))) 15 0.5)))
((= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(set-color! font-ctx (progress-selected 0))
(draw-generic-highlight (the int (+ -1.0 (-> font-ctx origin y))) 15 alpha))
(else
(set-color! font-ctx (font-color progress))))
(print-game-text (lookup-text! *common-text* (-> obj name) #f) font-ctx #f 44 (bucket-id progress))
(+! (-> font-ctx origin y) line-height)
(set! *temp-string* (clear *temp-string*))
(if (-> obj confirmed?)
(format *temp-string* "~1L~S~35L ~S" (lookup-text! *common-text* (text-id progress-yes) #f) (lookup-text! *common-text* (text-id progress-no) #f))
(format *temp-string* "~35L~S ~1L~S~1L" (lookup-text! *common-text* (text-id progress-yes) #f) (lookup-text! *common-text* (text-id progress-no) #f)))))
(set-scale! font-ctx 0.35)
(print-game-text *temp-string* font-ctx #f 44 (bucket-id progress))))
(else
(draw-generic-simple-string-option obj progress font-ctx option-index (lookup-text! *common-text* (-> obj name) #f))))
(none))
(defmethod draw-option menu-generic-slider-option ((obj menu-generic-slider-option) (arg0 progress) (font-ctx font-context) (option-index int) (selected? symbol))
(when (not (-> obj mounted?))
(on-mount! obj))
(let ((alpha (max 0.0 (* 2.0 (- 0.5 (-> arg0 menu-transition)))))
(slider-value (if selected? (-> obj value) (call-get-value-fn obj))))
(set! (-> font-ctx alpha) alpha)
(set-scale! font-ctx 0.45)
(+! (-> font-ctx origin y) 20.0)
(case (get-aspect-ratio)
(('aspect4x3))
(('aspect16x9)))
(set-flags! font-ctx (font-flags kerning middle large))
(cond
(selected?
(set-scale! font-ctx 0.35)
(+! (-> font-ctx origin y) (if (= (get-aspect-ratio) 'aspect4x3) -15.0 -15.0))
(set-color! font-ctx (font-color progress-force-selected))
(draw-generic-highlight (the int (+ -2.0 (-> font-ctx origin y))) 35 alpha)
(if (= (-> obj show-decimal?) #t)
(print-game-text (string-format "~S: ~,,2f" (lookup-text! *common-text* (-> obj name) #f) slider-value) font-ctx #f 44 (bucket-id progress))
(print-game-text (string-format "~S: ~D" (lookup-text! *common-text* (-> obj name) #f) slider-value) font-ctx #f 44 (bucket-id progress)))
(set! (-> obj bar-sprite tex) (lookup-texture-by-id (new 'static 'texture-id :index #xb :page #xc93)))
(set! (-> obj bar-sprite scale-x) 2.0)
(set! (-> obj bar-sprite scale-y) 0.5)
(let ((sprite-color-0 (-> obj bar-sprite color2)))
(set! (-> sprite-color-0 0) 128)
(set! (-> sprite-color-0 1) 128)
(set! (-> sprite-color-0 2) 128)
(set! (-> sprite-color-0 3) 128)
)
(set! (-> obj bar-sprite pos z) #x3fffff)
(set! (-> obj bar-sprite pos w) 0)
(set! (-> obj bar-cursor-sprite tex) (lookup-texture-by-id (new 'static 'texture-id :index #xc :page #xc93)))
(set! (-> obj bar-cursor-sprite scale-x) 0.2)
(set! (-> obj bar-cursor-sprite scale-y) 1.0)
(let ((sprite-color-1 (-> obj bar-cursor-sprite color2)))
(set! (-> sprite-color-1 0) 128)
(set! (-> sprite-color-1 1) 128)
(set! (-> sprite-color-1 2) 128)
(set! (-> sprite-color-1 3) 128)
)
(set! (-> obj bar-cursor-sprite pos z) #x3fffff)
(set! (-> obj bar-cursor-sprite pos w) 0)
;; bar
(set-hud-piece-position! (-> obj bar-sprite) (the int (adjust-game-x 135.0)) (+ (the int (-> font-ctx origin y)) (if (= (get-aspect-ratio) 'aspect4x3) 18 15)))
;; calculate the percentage of the bar based on the range
;; (actual + abs(range-min)) / (range-max + abs(range-min)) = percentage
(let* ((percentage (/ (+ slider-value (fabs (-> obj min-value)))
(+ (-> obj max-value) (fabs (-> obj min-value)))))
;; cursor (135 -> 365) = 230 pixels
(cursor-x-pos (adjust-game-x-int (+ 135 (* (if (= (get-aspect-ratio) 'aspect4x3) 230.0 231.0) percentage))))
(bar-remainder (- (adjust-game-x-int 365) cursor-x-pos)))
;; cursor position
(set-hud-piece-position! (-> obj bar-cursor-sprite) cursor-x-pos (+ (the int (-> font-ctx origin y)) (if (= (get-aspect-ratio) 'aspect4x3) 14 11)))
(with-dma-buffer-add-bucket ((buffer (-> *display* frames (-> *display* on-screen) global-buf))
(bucket-id progress))
(draw (-> obj bar-sprite) buffer (-> *level* default-level))
;; bar mask
;; TODO - bar remainder isnt correct on custom aspect ratios since those internally still return `aspect4x3` for (get-aspect-ratio), this is a larger issue though
;; perhaps just standardize menu size in general and ditch aspect ratio differences.
(draw-sprite2d-xy buffer (+ cursor-x-pos 10) (+ (the int (-> font-ctx origin y)) (if (= (get-aspect-ratio) 'aspect4x3) 23 20)) (+ bar-remainder (if (= (get-aspect-ratio) 'aspect4x3) 9 6)) 6
(new 'static 'rgba :r (the int (* 0.0 alpha slider-value))
:g (the int (* 0.0 alpha slider-value))
:b (the int (* 0.0 alpha slider-value))
:a (the int (* 128.0 alpha))))
(draw (-> obj bar-cursor-sprite) buffer (-> *level* default-level)))))
(else
(+! (-> font-ctx origin y) -8.0)
(cond
((and (nonzero? (-> obj should-disable?))
(!= (-> obj should-disable?) #f)
((-> obj should-disable?)))
(set-color! font-ctx (font-color progress-option-off))
(when (= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(draw-generic-highlight (the int (+ -1.0 (-> font-ctx origin y))) 15 0.5)))
((= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(set-color! font-ctx (progress-selected 0))
(draw-generic-highlight (the int (+ -2.0 (-> font-ctx origin y))) 18 alpha))
(else
(set-color! font-ctx (font-color progress))))
(if (= (-> obj show-decimal?) #t)
(print-game-text (string-format "~S: ~,,2f" (lookup-text! *common-text* (-> obj name) #f) slider-value) font-ctx #f 44 (bucket-id progress))
(print-game-text (string-format "~S: ~D" (lookup-text! *common-text* (-> obj name) #f) slider-value) font-ctx #f 44 (bucket-id progress)))))
)
(none))
(defmethod draw-option menu-generic-details-page ((obj menu-generic-details-page) (progress progress) (font-ctx font-context) (option-index int) (selected? symbol))
(when (or (zero? (-> obj mounted?)) (not (-> obj mounted?)))
(on-mount! obj))
;; the list has a total of 200px of y-height
;; with 10px of margin at the top and bottom, that leaves 180 / 4 = 45px per item
;; it's the responsibility of each generic component to center itself within these 45px lines
(when (not (-> *progress-pc-generic-store* clear-screen?))
(let* ((font-alpha (fmax 0.0 (* 2.0 (- 0.5 (-> progress menu-transition)))))
(hud-bounds (new 'stack-no-clear 'hud-box))
(max-page-size (if (= (get-aspect-ratio) 'aspect16x9) 12 10))
(margin-top-bottom 0.0)
(line-height (/ (if (= (get-aspect-ratio) 'aspect16x9) 253.0 200.0) max-page-size)))
(set! (-> font-ctx alpha) font-alpha)
(set-color! font-ctx (font-color progress))
;; header
(draw-page-header font-ctx (-> obj name))
;; background borders
(draw-page-border (-> obj box 0) font-alpha)
;; background
(draw-page-background font-alpha)
(begin-scissor-scrolling-page hud-bounds)
(if (= (get-aspect-ratio) 'aspect16x9)
(set! (-> font-ctx origin y) (+ 86.0 margin-top-bottom))
(set! (-> font-ctx origin y) (+ 112.0 margin-top-bottom)))
;; render items
(let* ((entry-index (max 0 (* (/ (-> *progress-pc-generic-store* current-menu-hover-index) max-page-size) max-page-size)))
(end-index (min (-> obj entries length) (+ entry-index max-page-size))))
(while (< entry-index end-index)
(let ((entry (-> obj entries entry-index)))
(when (nonzero? entry)
;; save the y,x position as who knows where it will end up after the component finishes rendering
(let ((old-y-pos (-> font-ctx origin y))
(old-x-pos (-> font-ctx origin x)))
(draw-option entry progress font-ctx entry-index
(= (-> obj selected-entry-index) entry-index))
;; move to the next line
(set! (-> font-ctx origin y) (+ old-y-pos line-height))
;; - debugging, draw the dividing lines to make center new items easier
(draw-generic-page-row-line (the int (-> font-ctx origin y)))
(set! (-> font-ctx origin x) old-x-pos)
;; reset the font color
(set-color! font-ctx (font-color progress)))))
(+! entry-index 1)))
;; end
(end-scissor-scrolling-page hud-bounds 1.0)
(set-flags! font-ctx (font-flags kerning large))
(let* ((draw-up-arrow? (and (not (zero? (-> *progress-pc-generic-store* current-menu-hover-index)))
(>= (-> *progress-pc-generic-store* current-menu-hover-index) max-page-size)))
(last-page-remainder (mod (-> obj entries length) max-page-size))
(last-page-starting-index (if (zero? last-page-remainder)
(- (-> obj entries length) max-page-size)
(- (-> obj entries length) last-page-remainder)))
(draw-down-arrow? (and (> (-> obj entries length) max-page-size)
(< (-> *progress-pc-generic-store* current-menu-hover-index) last-page-starting-index))))
(draw-scrolling-page-up-down-arrows font-ctx draw-up-arrow? draw-down-arrow?))))
(none))
(defmethod draw-option menu-generic-details-keybind-entry ((obj menu-generic-details-keybind-entry) (progress progress) (font-ctx font-context) (option-index int) (selected? symbol))
(when (or (zero? (-> obj mounted?)) (not (-> obj mounted?)))
(on-mount! obj))
;; TODO - implement `should-disable?` if it's ever relevant (its not right now)
(let ((alpha (* 2.0 (- 0.5 (-> progress menu-transition))))
(line-height 23.0))
(max! alpha 0.0)
(set! (-> font-ctx alpha) alpha)
(set-scale! font-ctx 0.40)
(cond
((= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(set-color! arg1 (progress-selected 0))
(draw-generic-highlight (the int (+ -1.0 (-> arg1 origin y))) 22 alpha))
(set-color! font-ctx (progress-selected 0))
(draw-generic-highlight (the int (+ 2.0 (-> font-ctx origin y))) 18 alpha))
(else
(set-color! arg1 (font-color progress))))
(print-game-text (lookup-text! *common-text* (-> obj name) #f) arg1 #f 44 (bucket-id progress)))
(set-color! font-ctx (font-color progress))))
;; Print left aligned text
(set-flags! font-ctx (font-flags kerning left large))
(-! (-> font-ctx origin y) 1.0)
(when (= (get-aspect-ratio) 'aspect16x9)
(+! (-> font-ctx origin x) 5.0))
(print-game-text (get-keybind-string obj) font-ctx #f 44 (bucket-id progress))
;; Now print the right aligned text
(set! (-> font-ctx origin x) (the float (adjust-game-x (if (= (get-aspect-ratio) 'aspect16x9) 430.0 438.0))))
(+! (-> font-ctx origin y) 6.0)
(set-flags! font-ctx (font-flags kerning right large))
(let ((bind (pc-get-current-bind (-> obj bind-info) *pc-cpp-temp-string*)))
(cond
(selected?
(print-game-text (string-format "~S...(~Ds)" (lookup-text! *common-text* (text-id progress-keybinds-waiting-for-bind) #f)
(inc (/ (- (seconds 5) (- (current-time) (-> *progress-pc-generic-store* keybind-select-time))) TICKS_PER_SECOND)))
font-ctx #f 44 (bucket-id progress)))
((= bind #f)
(print-game-text (lookup-text! *common-text* (text-id progress-keybinds-unset) #f) font-ctx #f 44 (bucket-id progress)))
((string= *pc-cpp-temp-string* "unknown")
(print-game-text (lookup-text! *common-text* (text-id progress-unknown-option) #f) font-ctx #f 44 (bucket-id progress)))
(else
(print-game-text *pc-cpp-temp-string* font-ctx #f 44 (bucket-id progress))))))
(none))
(defmethod draw-option menu-generic-details-confirm-entry ((obj menu-generic-details-confirm-entry) (progress progress) (font-ctx font-context) (option-index int) (selected? symbol))
(when (or (zero? (-> obj mounted?)) (not (-> obj mounted?)))
(on-mount! obj))
;; TODO - implement `should-disable?` if it's ever relevant (its not right now)
(let ((alpha (* 2.0 (- 0.5 (-> progress menu-transition))))
(line-height 23.0))
(max! alpha 0.0)
(set! (-> font-ctx alpha) alpha)
(set-scale! font-ctx 0.40)
(cond
((= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(set-color! font-ctx (progress-selected 0))
(draw-generic-highlight (the int (+ 2.0 (-> font-ctx origin y))) 18 alpha))
(else
(set-color! font-ctx (font-color progress))))
;; Print left aligned text
(set-flags! font-ctx (font-flags kerning left large))
(-! (-> font-ctx origin y) 1.0)
(when (= (get-aspect-ratio) 'aspect16x9)
(+! (-> font-ctx origin x) 5.0))
(print-game-text (lookup-text! *common-text* (-> obj name) #f) font-ctx #f 44 (bucket-id progress))
(when selected?
;; Now print the right aligned text, if the option is selected
(set! (-> font-ctx origin x) (if (= (get-aspect-ratio) 'aspect16x9) 430.0 438.0))
(+! (-> font-ctx origin y) 6.0)
(set-flags! font-ctx (font-flags kerning right large))
(clear *temp-string*)
(if (-> obj confirmed?)
(format *temp-string* "~33L~S~35L ~S" (lookup-text! *common-text* (text-id progress-yes) #f) (lookup-text! *common-text* (text-id progress-no) #f))
(format *temp-string* "~35L~S ~33L~S~1L" (lookup-text! *common-text* (text-id progress-yes) #f) (lookup-text! *common-text* (text-id progress-no) #f)))
(print-game-text *temp-string* font-ctx #f 44 (bucket-id progress))))
(none))
@@ -1,10 +1,6 @@
;;-*-Lisp-*-
(in-package goal)
;; TODO:
;; - slider
;; - disabled options
;; - detail list
(deftype generic-progress-state-entry (structure)
"All info that is pushed onto a 'stack' when navigating to a sub-menu with
@@ -16,13 +12,16 @@
;; so we can restore back to the same menu position
(hover-index int32)
;; symbol used normally for progress stuff
(progress-id symbol)))
(progress-id symbol))
(:methods
(call-on-load (_type_) none)))
(deftype progress-pc-generic-store (structure)
"Isolated type for keeping track of some global state, as re-using the normal [[*progress*]] object
can lead to unexpected behaviour -- they change some values all over the place"
((current-menu-hover-index int32)
(clear-screen? symbol)
(keybind-select-time time-frame)
(history-stack generic-progress-state-entry 10 :inline)
(history-stack-index int32))
(:methods
@@ -30,16 +29,34 @@
(navigate! (_type_ progress menu-option-list (function none)) none)
(back! (_type_ progress) none)
(has-history? (_type_) symbol)
(clear-history-if-empty! (_type_) none)))
(clear-history-if-empty! (_type_) none)
(clear-history! (_type_) none)))
(define *progress-pc-generic-store* (new 'static 'progress-pc-generic-store))
(deftype menu-generic-option (menu-option)
((mounted? symbol))
((mounted? symbol)
(should-disable? (function symbol)))
(:methods
(on-mount! "Called when the menu item is first drawn as a means to initialize defaults, etc" (_type_) none)))
(on-mount! "Called when the menu item is first drawn as a means to initialize defaults, etc" (_type_) none)
(should-disable? (_type_) symbol)))
(deftype menu-generic-scrolling-page (menu-generic-option)
"A menu option that holds menu options"
(;; props
(menu-options (array menu-option))
;; state
(selected-option-index int32)
(last-move time-frame)))
(deftype menu-generic-link-option (menu-generic-option)
"A very simple link option that allows you to link to any other [[menu-option-list]]"
(;; props
(target menu-option-list)
;; generic function to potentially run some setup code when the entry is loaded
;; this is not called from the link option, but rather stored in the history entry
(on-load (function none))))
;; TODO - make methods for calling the lambdas just to reduce duplication (checking if the value is set, etc)
(deftype menu-generic-boolean-option (menu-generic-option)
"Generic two option menu entry (ie. yes/no)"
(;; props
@@ -49,46 +66,156 @@
(value symbol)
;; lambdas
(get-value-fn (function symbol))
(on-confirm (function symbol none))))
(on-confirm (function symbol none)))
(:methods
(call-get-value-fn (_type_) symbol)
(call-on-confirm (_type_ symbol) none)))
;; TODO - make methods for calling the lambdas just to reduce duplication (checking if the value is set, etc)
(deftype menu-generic-carousel-option (menu-generic-option)
"Generic left-right menu entry (ie. language selection)"
(;; props
;; - either you can provide a list of hard-coded items (takes precedence)
(items (array text-id))
;; - or you can provide functions that return the max-size and the string labels at those indicies
(get-max-size-fn (function int))
(get-item-label-fn (function int string))
(no-items-label text-id) ;; TODO - implement if `progress-multiselect-no-items-found` isn't ever sufficient
;; state
(item-index int32)
;; lambdas
(get-item-index-fn (function int))
(on-confirm (function int none))))
(on-confirm (function int none)))
(:methods
(num-items (_type_) int)
(get-item-label (_type_ int) string)
(call-get-item-index-fn (_type_) int)
(call-on-confirm (_type_ int) none)))
(deftype menu-generic-scrolling-page (menu-generic-option)
"A menu option that holds menu options"
(deftype menu-generic-confirm-option (menu-generic-option)
"A button option that confirms before triggering it's action"
(;; props
(menu-options (array menu-option))
(header text-id)
(on-confirm (function none))
;; state
(selected-option-item menu-option)
(selected-option-index int32)
(confirmed? symbol))
(:methods
(call-on-confirm (_type_) none)))
(deftype menu-generic-slider-option (menu-generic-option)
"A generic slider, can go into the negative as well."
(;; props
(min-value float)
(max-value float)
(step float)
(show-decimal? symbol)
;; state
(value float)
(bar-sprite hud-sprite :inline)
(bar-cursor-sprite hud-sprite :inline)
(last-sound-played time-frame)
;; lambdas
(get-value-fn (function float))
(on-confirm (function float none)))
(:methods
(call-get-value-fn (_type_) float)
(call-on-confirm (_type_ float) none)))
(deftype menu-generic-details-entry (menu-generic-option)
"A generic details list entry"
())
(defenum controller-keybind
:type int8
(select 0)
(l3 1)
(r3 2)
(start 3)
(dpad-up 4)
(dpad-right 5)
(dpad-down 6)
(dpad-left 7)
(l2 8)
(r2 9)
(l1 10)
(r1 11)
(triangle 12)
(circle 13)
(cross 14)
(square 15)
(l-analog-up 16)
(l-analog-down 17)
(l-analog-left 18)
(l-analog-right 19)
(r-analog-up 20)
(r-analog-down 21)
(r-analog-left 22)
(r-analog-right 23))
(defenum input-device-type
:type int8
(controller 0)
(keyboard 1)
(mouse 2))
(deftype menu-generic-details-keybind-entry (menu-generic-details-entry)
((keybind controller-keybind)
(device-type input-device-type)
;; state
(bind-info bind-assignment-info :inline))
(:methods
(get-keybind-string (_type_) string)))
(deftype menu-generic-details-confirm-entry (menu-generic-details-entry)
(;; props
(on-confirm (function none))
;; state
(confirmed? symbol))
(:methods
(call-on-confirm (_type_) none)))
(deftype menu-generic-details-page (menu-generic-option)
"A generic details list page, compact rows that can be selected.
This is very similar to the [[menu-generic-scrolling-page]] component but instead of holding
[[menu-option]]s, it holds [[menu-generic-details-entry]]'s"
((entries (array menu-generic-details-entry))
;; state
(selected-entry-index int32)
(last-move time-frame)))
;; TODO - make methods for calling the lambdas just to reduce duplication (checking if the value is set, etc)
(deftype menu-generic-link-option (menu-generic-option)
"A very simple link option that allows you to link to any other menu-option"
(;; props
(target menu-option-list)
;; generic function to potentially run some setup code when the entry is loaded
(on-load (function none))))
(defmacro progress-new-generic-option (option)
`(new 'static 'menu-option-list :options (new 'static 'boxed-array :type menu-option ,option)))
(defmacro progress-new-generic-scrolling-page (title &rest options)
`(new 'static 'menu-option-list
:options (new 'static 'boxed-array :type menu-option
(new 'static 'menu-generic-scrolling-page
:name ,title ; (text-id progress-misc-game-options)
:name ,title
:menu-options (new 'static 'boxed-array :type menu-option
,@options)))))
(defmacro progress-new-generic-link (text target)
(defmacro progress-new-generic-link (text target &key (should-disable? #f))
`(new 'static 'menu-generic-link-option
:name ,text
:should-disable? ,should-disable?
:target ,target))
(defmacro progress-new-generic-link-to-scrolling-page (title &key (should-disable? #f) &rest options)
`(new 'static 'menu-generic-link-option
:name ,title
:should-disable? ,should-disable?
:target (new 'static 'menu-option-list
:options (new 'static 'boxed-array :type menu-option
(new 'static 'menu-generic-scrolling-page
:name ,title
:menu-options (new 'static 'boxed-array :type menu-option
,@options))))))
(defmacro progress-new-generic-link-to-details-page (title &key (should-disable? #f) &rest entries)
`(new 'static 'menu-generic-link-option
:name ,title
:should-disable? ,should-disable?
:target (new 'static 'menu-option-list
:options (new 'static 'boxed-array :type menu-option
(new 'static 'menu-generic-details-page
:name ,title
:entries (new 'static 'boxed-array :type menu-generic-details-entry
,@entries))))))
+356 -63
View File
@@ -1,8 +1,54 @@
;;-*-Lisp-*-
(in-package goal)
(defmethod call-on-load generic-progress-state-entry ((this generic-progress-state-entry))
(when (and (nonzero? (-> this on-load)) (!= (-> this on-load) #f))
((-> this on-load)))
(none))
(defmethod call-get-value-fn menu-generic-boolean-option ((this menu-generic-boolean-option))
(if (and (nonzero? (-> this get-value-fn)) (!= (-> this get-value-fn) #f))
((-> this get-value-fn))
#f))
(defmethod call-on-confirm menu-generic-boolean-option ((this menu-generic-boolean-option) (val symbol))
(when (and (nonzero? (-> this on-confirm)) (!= (-> this on-confirm) #f))
((-> this on-confirm) val))
(none))
(defmethod call-get-item-index-fn menu-generic-carousel-option ((this menu-generic-carousel-option))
(if (and (nonzero? (-> this get-item-index-fn)) (!= (-> this get-item-index-fn) #f))
((-> this get-item-index-fn))
0))
(defmethod call-on-confirm menu-generic-carousel-option ((this menu-generic-carousel-option) (val int))
(when (and (nonzero? (-> this on-confirm)) (!= (-> this on-confirm) #f))
((-> this on-confirm) val))
(none))
(defmethod call-on-confirm menu-generic-confirm-option ((this menu-generic-confirm-option))
(when (and (nonzero? (-> this on-confirm)) (!= (-> this on-confirm) #f))
((-> this on-confirm)))
(none))
(defmethod call-get-value-fn menu-generic-slider-option ((this menu-generic-slider-option))
(if (and (nonzero? (-> this get-value-fn)) (!= (-> this get-value-fn) #f))
((-> this get-value-fn))
0.0))
(defmethod call-on-confirm menu-generic-slider-option ((this menu-generic-slider-option) (val float))
(when (and (nonzero? (-> this on-confirm)) (!= (-> this on-confirm) #f))
((-> this on-confirm) val))
(none))
(defmethod init! progress-pc-generic-store ((this progress-pc-generic-store))
(set! (-> this clear-screen?) #f)
(set! (-> this keybind-select-time) 0)
(none))
(defmethod call-on-confirm menu-generic-details-confirm-entry ((this menu-generic-details-confirm-entry))
(when (and (nonzero? (-> this on-confirm)) (!= (-> this on-confirm) #f))
((-> this on-confirm)))
(none))
(defmethod navigate! progress-pc-generic-store ((this progress-pc-generic-store) (progress progress) (target menu-option-list) (on-load (function none)))
@@ -43,8 +89,7 @@
(> (-> this history-stack-index) 0))
(defmethod clear-history-if-empty! progress-pc-generic-store ((this progress-pc-generic-store))
;; if we are have no history, just reset the entry. This is so we don't preserve state
;; after completely exiting the menu
"if we have no history, just reset the entry. This is so we don't preserve state after completely exiting the menu"
(when (not (has-history? this))
(set! (-> this history-stack-index) 0)
(set! (-> this clear-screen?) #f)
@@ -56,10 +101,18 @@
(set! (-> stack-entry progress-id) #f)))
(none))
(defmethod clear-history! progress-pc-generic-store ((this progress-pc-generic-store))
(set! (-> this history-stack-index) 0)
(set! (-> this clear-screen?) #t)
(set! (-> this current-menu-hover-index) 0)
(none))
(defmethod on-mount! menu-generic-option ((this menu-generic-option))
(set! (-> this mounted?) #t)
(none))
;; TODO - call the parent methods, when there is an elegant way to do so (not having to know the ID)
(defmethod on-mount! menu-generic-carousel-option ((this menu-generic-carousel-option))
(set! (-> this mounted?) #t)
(set! (-> this item-index) 0)
@@ -67,10 +120,47 @@
(defmethod on-mount! menu-generic-scrolling-page ((this menu-generic-scrolling-page))
(set! (-> this mounted?) #t)
(set! (-> this selected-option-item) #f)
(set! (-> this selected-option-index) -1)
(none))
(defmethod on-mount! menu-generic-details-page ((this menu-generic-details-page))
(set! (-> this mounted?) #t)
(set! (-> this selected-entry-index) -1)
(none))
(defmethod on-mount! menu-generic-confirm-option ((this menu-generic-confirm-option))
(set! (-> this mounted?) #t)
(set! (-> this confirmed?) #f)
(none))
(defun controller-keybind->input-index ((bind controller-keybind))
(case bind
(((controller-keybind l-analog-up)) 1)
(((controller-keybind l-analog-down)) 1)
(((controller-keybind l-analog-left)) 0)
(((controller-keybind l-analog-right)) 0)
(((controller-keybind r-analog-up)) 3)
(((controller-keybind r-analog-down)) 3)
(((controller-keybind r-analog-left)) 2)
(((controller-keybind r-analog-right)) 2)
(else (the int bind))))
(defmethod on-mount! menu-generic-details-keybind-entry ((this menu-generic-details-keybind-entry))
(set! (-> this mounted?) #t)
(set! (-> this bind-info port) 0) ;; always port 0 for now
(set! (-> this bind-info device-type) (the int (-> this device-type)))
(set! (-> this bind-info for-buttons?) #t)
(set! (-> this bind-info analog-min-range?) #f)
(set! (-> this bind-info input-idx) (controller-keybind->input-index (-> this keybind)))
(case (-> this keybind)
(((controller-keybind l-analog-up) (controller-keybind l-analog-down) (controller-keybind l-analog-left) (controller-keybind l-analog-right)
(controller-keybind r-analog-up) (controller-keybind r-analog-down) (controller-keybind r-analog-left) (controller-keybind r-analog-right))
(set! (-> this bind-info for-buttons?) #f)
(case (-> this keybind)
(((controller-keybind l-analog-up) (controller-keybind l-analog-left) (controller-keybind r-analog-up) (controller-keybind r-analog-left))
(set! (-> this bind-info analog-min-range?) #t)))))
(none))
;; Progress Code Overrides
(defmethod respond-to-cpad progress ((obj progress))
@@ -83,7 +173,8 @@
(has-generic-history? (has-history? *progress-pc-generic-store*)))
(when (and option-array (= (-> obj menu-transition) 0.0))
(let ((in-generic-page? (and (= (-> option-array length) 1)
(type? (-> option-array 0) menu-generic-scrolling-page))))
(or (type? (-> option-array 0) menu-generic-scrolling-page)
(type? (-> option-array 0) menu-generic-details-page)))))
(cond
;; If it's a scrolling menu, we have to pull from it's list of items
(in-generic-page?
@@ -163,53 +254,65 @@
;; Component implementation
;; - input handling
(defmethod respond-progress menu-generic-scrolling-page ((obj menu-generic-scrolling-page) (progress progress) (selected? symbol))
"Handle progress menu navigation logic."
(if (or (= (-> obj selected-option-item) #f)
(zero? (-> obj selected-option-item)))
(cond
((or (cpad-pressed? 0 down l-analog-down)
(and (cpad-hold? 0 down l-analog-down)
(>= (- (current-time) (the-as int (-> obj last-move))) (seconds 0.5))))
(set! (-> obj last-move) (current-time))
(cond
((< (-> *progress-pc-generic-store* current-menu-hover-index) (dec (-> obj menu-options length)))
(+! (-> *progress-pc-generic-store* current-menu-hover-index) 1)
(sound-play "roll-over"))
(else
(set! (-> *progress-pc-generic-store* current-menu-hover-index) 0)
(sound-play "roll-over"))))
((or (cpad-pressed? 0 up l-analog-up)
(and (cpad-hold? 0 up l-analog-up)
(>= (- (current-time) (the-as int (-> obj last-move))) (seconds 0.5))))
(let ((selected-item? #f))
(if (= (-> obj selected-option-index) -1)
(cond
((or (cpad-pressed? 0 down l-analog-down)
(and (cpad-hold? 0 down l-analog-down)
(>= (- (current-time) (the-as int (-> obj last-move))) (seconds 0.5))))
(set! (-> obj last-move) (current-time))
(+! (-> *progress-pc-generic-store* current-menu-hover-index) -1)
(sound-play "roll-over")
(when (< (-> *progress-pc-generic-store* current-menu-hover-index) 0)
(set! (-> *progress-pc-generic-store* current-menu-hover-index) (dec (-> obj menu-options length)))))
((cpad-pressed? 0 confirm)
;; ignore confirm if it's a link
(when (and (< (-> *progress-pc-generic-store* current-menu-hover-index) (-> obj menu-options length))
(not (type? (-> obj menu-options (-> *progress-pc-generic-store* current-menu-hover-index)) menu-generic-link-option)))
(set! (-> obj selected-option-index) (-> *progress-pc-generic-store* current-menu-hover-index))
(set! (-> obj selected-option-item) (-> obj menu-options (-> *progress-pc-generic-store* current-menu-hover-index))))
(sound-play "generic-beep"))
((cpad-pressed? 0 triangle)
;; we are in a sub-page, time to go back
(when (has-history? *progress-pc-generic-store*)
(back! *progress-pc-generic-store* progress)
(sound-play "score-slide")))
)
(cond
((cpad-pressed? 0 confirm)
(set! (-> obj selected-option-index) -1)
(set! (-> obj selected-option-item) #f))
((cpad-pressed? 0 triangle)
(set! (-> obj selected-option-index) -1)
(set! (-> obj selected-option-item) #f))))
;; propagate event to menu-option
(when (< (-> *progress-pc-generic-store* current-menu-hover-index) (-> obj menu-options length))
(respond-progress (-> obj menu-options (-> *progress-pc-generic-store* current-menu-hover-index)) progress selected?))
(cond
((< (-> *progress-pc-generic-store* current-menu-hover-index) (dec (-> obj menu-options length)))
(+! (-> *progress-pc-generic-store* current-menu-hover-index) 1)
(sound-play "roll-over"))
(else
(set! (-> *progress-pc-generic-store* current-menu-hover-index) 0)
(sound-play "roll-over"))))
((or (cpad-pressed? 0 up l-analog-up)
(and (cpad-hold? 0 up l-analog-up)
(>= (- (current-time) (the-as int (-> obj last-move))) (seconds 0.5))))
(set! (-> obj last-move) (current-time))
(+! (-> *progress-pc-generic-store* current-menu-hover-index) -1)
(sound-play "roll-over")
(when (< (-> *progress-pc-generic-store* current-menu-hover-index) 0)
(set! (-> *progress-pc-generic-store* current-menu-hover-index) (dec (-> obj menu-options length)))))
((cpad-pressed? 0 confirm)
(when (< (-> *progress-pc-generic-store* current-menu-hover-index) (-> obj menu-options length))
(let ((menu-option (-> obj menu-options (-> *progress-pc-generic-store* current-menu-hover-index))))
;; if the option is disabled, return early
(when (and (type? menu-option menu-generic-option)
(nonzero? (-> (the-as menu-generic-option menu-option) should-disable?))
(!= (-> (the-as menu-generic-option menu-option) should-disable?) #f)
((-> (the-as menu-generic-option menu-option) should-disable?)))
(sound-play "roll-over")
(logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons confirm))
(logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons confirm))
(return 0))
;; ignore confirm if it's a link
(cond
((type? menu-option menu-generic-link-option)
(set! selected-item? #t))
(else
(set! (-> obj selected-option-index) (-> *progress-pc-generic-store* current-menu-hover-index))
(sound-play "generic-beep"))))))
((cpad-pressed? 0 triangle)
;; we are in a sub-page, time to go back
(when (has-history? *progress-pc-generic-store*)
(back! *progress-pc-generic-store* progress)
(sound-play "score-slide"))))
;; menu option already selected
(cond
((cpad-pressed? 0 confirm)
(set! (-> obj selected-option-index) -1))
((cpad-pressed? 0 triangle)
(set! (-> obj selected-option-index) -1))))
;; propagate event to menu-option
(when (< (-> *progress-pc-generic-store* current-menu-hover-index) (-> obj menu-options length))
(respond-progress (-> obj menu-options (-> *progress-pc-generic-store* current-menu-hover-index)) progress (or selected? selected-item?))))
0)
(defmethod respond-progress menu-generic-boolean-option ((obj menu-generic-boolean-option) (progress progress) (selected? symbol))
@@ -221,16 +324,13 @@
(set! (-> obj value) #t))
(sound-play "generic-beep"))
((cpad-pressed? 0 confirm)
(when (and (nonzero? (-> obj on-confirm)) (!= (-> obj on-confirm) #f))
((-> obj on-confirm) (-> obj value)))
(call-on-confirm obj (-> obj value))
(sound-play "generic-beep")))
(cond
((cpad-pressed? 0 confirm)
;; set the value, this is so we edit the component's state and not the actual underlying value
;; in other words, don't change the setting until the user has actually confirmed the change!
(when (and (nonzero? (-> obj get-value-fn))
(!= (-> obj get-value-fn) #f))
(set! (-> obj value) ((-> obj get-value-fn)))))))
(set! (-> obj value) (call-get-value-fn obj)))))
0)
(defmethod respond-progress menu-generic-carousel-option ((obj menu-generic-carousel-option) (progress progress) (selected? symbol))
@@ -239,30 +339,223 @@
((cpad-pressed? 0 left l-analog-left)
(dec! (-> obj item-index))
(when (< (-> obj item-index) 0)
(set! (-> obj item-index) (dec (-> obj items length))))
(set! (-> obj item-index) (dec (num-items obj))))
(sound-play "generic-beep"))
((cpad-pressed? 0 right l-analog-right)
(inc! (-> obj item-index))
(when (>= (-> obj item-index) (-> obj items length))
(when (>= (-> obj item-index) (num-items obj))
(set! (-> obj item-index) 0))
(sound-play "generic-beep"))
((cpad-pressed? 0 confirm)
(when (and (nonzero? (-> obj on-confirm)) (!= (-> obj on-confirm) #f))
((-> obj on-confirm) (-> obj item-index)))
(call-on-confirm obj (-> obj item-index))
(sound-play "generic-beep")))
(cond
((cpad-pressed? 0 confirm)
;; set the value, this is so we edit the component's state and not the actual underlying value
;; in other words, don't change the setting until the user has actually confirmed the change!
(when (and (nonzero? (-> obj get-item-index-fn)) (!= (-> obj get-item-index-fn) #f))
(set! (-> obj item-index) ((-> obj get-item-index-fn)))))))
(set! (-> obj item-index) (call-get-item-index-fn obj)))))
0)
(defmethod respond-progress menu-generic-link-option ((obj menu-generic-link-option) (progress progress) (selected? symbol))
(when (>= (-> *progress-pc-generic-store* current-menu-hover-index) 0)
(when (and selected? (cpad-pressed? 0 confirm))
(navigate! *progress-pc-generic-store* progress (-> obj target) (-> obj on-load))
(set! (-> progress selected-option) #f)
(sound-play "score-slide"))
0)
(defmethod respond-progress menu-generic-confirm-option ((obj menu-generic-confirm-option) (progress progress) (selected? symbol))
(if selected?
(cond
((cpad-pressed? 0 left l-analog-left right l-analog-right)
(if (-> obj confirmed?)
(set! (-> obj confirmed?) #f)
(set! (-> obj confirmed?) #t))
(sound-play "generic-beep"))
((cpad-pressed? 0 confirm)
(call-on-confirm obj)
(sound-play "generic-beep")))
(cond
((cpad-pressed? 0 confirm)
(navigate! *progress-pc-generic-store* progress (-> obj target) (-> obj on-load))
(set! (-> progress selected-option) #f)
(sound-play "score-slide"))))
(set! (-> obj confirmed?) #f))))
0)
(defmethod respond-progress menu-generic-slider-option ((obj menu-generic-slider-option) (progress progress) (selected? symbol))
(if selected?
(cond
((and (> (-> obj value) (-> obj min-value))
(cpad-hold? 0 left l-analog-left))
;; TODO - might not work well on higher frame-rates
(set! (-> obj value) (fmax (- (-> obj value) (-> obj step)) (-> obj min-value)))
(when (< (seconds 0.03) (- (current-time) (-> obj last-sound-played)))
(set! (-> obj last-sound-played) (current-time))
(sound-play-by-name (static-sound-name "menu-slide") (new-sound-id) 512 0 0 (sound-group sfx) #t)))
((and (< (-> obj value) (-> obj max-value))
(cpad-hold? 0 right l-analog-right))
;; TODO - might not work well on higher frame-rates
(set! (-> obj value) (fmin (+ (-> obj value) (-> obj step)) (-> obj max-value)))
(when (< (seconds 0.03) (- (current-time) (-> obj last-sound-played)))
(set! (-> obj last-sound-played) (current-time))
(sound-play-by-name (static-sound-name "menu-slide") (new-sound-id) 512 0 0 (sound-group sfx) #t)))
((cpad-pressed? 0 confirm)
(call-on-confirm obj (-> obj value))
(sound-play "generic-beep")))
(cond
((cpad-pressed? 0 confirm)
;; set the value, this is so we edit the component's state and not the actual underlying value
;; in other words, don't change the setting until the user has actually confirmed the change!
(set! (-> obj value) (call-get-value-fn obj)))))
0)
(defmethod respond-progress menu-generic-details-page ((obj menu-generic-details-page) (progress progress) (selected? symbol))
(if (= (-> obj selected-entry-index) -1)
(cond
((or (cpad-pressed? 0 down l-analog-down)
(and (cpad-hold? 0 down l-analog-down)
(>= (- (current-time) (the-as int (-> obj last-move))) (seconds 0.5))))
(set! (-> obj last-move) (current-time))
(cond
((< (-> *progress-pc-generic-store* current-menu-hover-index) (dec (-> obj entries length)))
(+! (-> *progress-pc-generic-store* current-menu-hover-index) 1)
(sound-play "roll-over"))
(else
(set! (-> *progress-pc-generic-store* current-menu-hover-index) 0)
(sound-play "roll-over"))))
((or (cpad-pressed? 0 up l-analog-up)
(and (cpad-hold? 0 up l-analog-up)
(>= (- (current-time) (the-as int (-> obj last-move))) (seconds 0.5))))
(set! (-> obj last-move) (current-time))
(+! (-> *progress-pc-generic-store* current-menu-hover-index) -1)
(sound-play "roll-over")
(when (< (-> *progress-pc-generic-store* current-menu-hover-index) 0)
(set! (-> *progress-pc-generic-store* current-menu-hover-index) (dec (-> obj entries length)))))
((cpad-pressed? 0 confirm)
(when (< (-> *progress-pc-generic-store* current-menu-hover-index) (-> obj entries length))
(set! (-> obj selected-entry-index) (-> *progress-pc-generic-store* current-menu-hover-index))
(sound-play "generic-beep")))
((cpad-pressed? 0 triangle)
;; we are in a sub-page, time to go back
(when (has-history? *progress-pc-generic-store*)
(back! *progress-pc-generic-store* progress)
(sound-play "score-slide"))))
;; menu option already selected
(cond
((cpad-pressed? 0 confirm)
(set! (-> obj selected-entry-index) -1))
((cpad-pressed? 0 triangle)
(set! (-> obj selected-entry-index) -1))
;; keybinds
((nonzero? (-> *progress-pc-generic-store* keybind-select-time))
;; when the bind has been set, or it's expired
(when (or (not (pc-waiting-for-bind?))
(>= (- (current-time) (the-as int (-> *progress-pc-generic-store* keybind-select-time))) (seconds 5.0)))
(set! (-> *progress-pc-generic-store* keybind-select-time) 0)
(set! (-> obj selected-entry-index) -1)
(set! (-> progress selected-option) #f)
(cond
((not (pc-waiting-for-bind?))
(sound-play "generic-beep"))
(else
(pc-stop-waiting-for-bind!)
(sound-play "roll-over")))))))
;; propagate event to menu-option
(when (< (-> *progress-pc-generic-store* current-menu-hover-index) (-> obj entries length))
(respond-progress (-> obj entries (-> *progress-pc-generic-store* current-menu-hover-index)) progress selected?))
0)
(defmethod respond-progress menu-generic-details-keybind-entry ((obj menu-generic-details-keybind-entry) (progress progress) (selected? symbol))
(when (not selected?)
(cond
((cpad-pressed? 0 confirm)
(let ((bind-info (-> obj bind-info)))
(pc-set-waiting-for-bind! (-> bind-info device-type) (not (-> bind-info for-buttons?)) (-> bind-info analog-min-range?) (-> bind-info input-idx)))
(set! (-> *progress-pc-generic-store* keybind-select-time) (current-time)))))
0)
(defmethod respond-progress menu-generic-details-confirm-entry ((obj menu-generic-details-confirm-entry) (progress progress) (selected? symbol))
(if selected?
(cond
((cpad-pressed? 0 left l-analog-left right l-analog-right)
(if (-> obj confirmed?)
(set! (-> obj confirmed?) #f)
(set! (-> obj confirmed?) #t))
(sound-play "generic-beep"))
((cpad-pressed? 0 confirm)
(call-on-confirm obj)
(sound-play "generic-beep")))
(cond
((cpad-pressed? 0 confirm)
(set! (-> obj confirmed?) #f))))
0)
;; - rest of component logic
(defmethod num-items menu-generic-carousel-option ((this menu-generic-carousel-option))
"Get the number of items in the carousel"
(if (and (nonzero? (-> this items)) (!= (-> this items) #f))
(-> this items length)
(if (and (and (nonzero? (-> this get-max-size-fn)) (!= (-> this get-max-size-fn) #f))
(and (nonzero? (-> this get-item-label-fn)) (!= (-> this get-max-size-fn) #f)))
((-> this get-max-size-fn))
0)))
(defmethod get-item-label menu-generic-carousel-option ((this menu-generic-carousel-option) (item-index int))
"Gets the string label of the currently choosen item, preferring the `items` array if it exists"
(if (and (nonzero? (-> this items)) (!= (-> this items) #f))
(lookup-text! *common-text* (-> this items item-index) #f)
(if (and (nonzero? (-> this get-item-label-fn)) (!= (-> this get-max-size-fn) #f))
((-> this get-item-label-fn) item-index)
"#ERROR")))
;; TODO - it could be possible to map certain controllers to buttons (ie. dualshock controllers could have nice mappings instead of SDL named ones)
(defmethod get-keybind-string menu-generic-details-keybind-entry ((this menu-generic-details-keybind-entry))
(case (-> this keybind)
(((controller-keybind cross))
"~Y~22L<~Z~Y~27L*~Z~Y~1L>~Z~Y~23L[~Z~+26H Cross")
(((controller-keybind square))
"~Y~22L<~Z~Y~24L#~Z~Y~1L>~Z~Y~23L[~Z~+26H S~+7Vq~-7Vuare")
(((controller-keybind circle))
"~Y~22L<~Z~Y~25L@~Z~Y~1L>~Z~Y~23L[~Z~+26H Circle")
(((controller-keybind triangle))
"~Y~22L<~Z~Y~26L;~Z~Y~1L>~Z~Y~23L[~Z~+26H Trian~+7Vg~-7Vle")
(((controller-keybind dpad-up))
"~Y~0L\ca1~Z~3L~+17H~-13V\ca2~Z~0L~+17H~+14V\ca0~Z~0L~+32H\ca3~Z~+56H D-Pad U~+7Vp~-7V")
(((controller-keybind dpad-down))
"~Y~0L\ca1~Z~0L~+17H~-13V\ca2~Z~3L~+17H~+14V\ca0~Z~0L~+32H\ca3~Z~+56H D-Pad Down")
(((controller-keybind dpad-right))
"~Y~0L\ca1~Z~0L~+17H~-13V\ca2~Z~0L~+17H~+14V\ca0~Z~3L~+32H\ca3~Z~+56H D-Pad Ri~+7Vg~-7Vht")
(((controller-keybind dpad-left))
"~Y~3L\ca1~Z~0L~+17H~-13V\ca2~Z~0L~+17H~+14V\ca0~Z~0L~+32H\ca3~Z~+56H D-Pad Left")
(((controller-keybind l1))
"~Y~22L~-2H~-12V\ca6\ca7~Z~22L~-2H~+17V\cb0\cb1~Z~1L~+4H~+3V\c95~Z~+38H L1")
(((controller-keybind l2))
"~Y~22L~-2H~-6V\ca8\ca9~Z~22L~-2H~+16V\cb2\cb3~Z~1L~+5H~-2V\c97~Z~+38H L2")
(((controller-keybind l3))
"\c91 L3")
(((controller-keybind r1))
"~Y~22L~-2H~-12V\ca6\ca7~Z~22L~-2H~+17V\cb0\cb1~Z~1L~+6H~+3V\c94~Z~+38H R1")
(((controller-keybind r2))
"~Y~22L~-2H~-6V\ca8\ca9~Z~22L~-2H~+16V\cb2\cb3~Z~1L~+5H~-2V\c96~Z~+38H R2")
(((controller-keybind r3))
"\c91 R3")
(((controller-keybind select))
"\c92 Select")
(((controller-keybind start))
"\c92 Start")
(((controller-keybind l-analog-up))
"~Y~1L\c91~Z~-17V~6L\c98~Z~+26H Left Analo~+7Vg~-7V U~+7Vp~-7V")
(((controller-keybind l-analog-down))
"~Y~1L\c91~Z~+15V~6L\c9c~Z~+26H Left Analo~+7Vg~-7V Down")
(((controller-keybind l-analog-left))
"~Y~1L\c91~Z~-17H~6L\c9e~Z~+26H Left Analo~+7Vg~-7V Left")
(((controller-keybind l-analog-right))
"~Y~1L\c91~Z~+17H~6L\ca4~Z~+26H Left Analo~+7Vg~-7V Ri~+7Vg~-7Vht")
(((controller-keybind r-analog-up))
"~Y~1L\c91~Z~-17V~6L\c98~Z~+26H Ri~+7Vg~-7Vht Analo~+7Vg~-7V U~+7Vp~-7V")
(((controller-keybind r-analog-down))
"~Y~1L\c91~Z~+15V~6L\c9c~Z~+26H Ri~+7Vg~-7Vht Analo~+7Vg~-7V Down")
(((controller-keybind r-analog-left))
"~Y~1L\c91~Z~-17H~6L\c9e~Z~+26H Ri~+7Vg~-7Vht Analo~+7Vg~-7V Left")
(((controller-keybind r-analog-right))
"~Y~1L\c91~Z~+17H~6L\ca4~Z~+26H Ri~+7Vg~-7Vht Analo~+7Vg~-7V Ri~+7Vg~-7Vht")
(else
"Unknown Bind")))
+2 -2
View File
@@ -355,8 +355,7 @@
(-> *progress-pc-generic-store* history-stack-index))))
;; call the on-load function is appropriate, this can be used to perform some kind of generic setup
;; for the particular route
(when (and (nonzero? (-> curr-history-entry on-load)) (!= (-> curr-history-entry on-load) #f))
((-> curr-history-entry on-load)))
(call-on-load curr-history-entry)
;; restore state from the history entry
(set! (-> *progress-pc-generic-store* clear-screen?) #f)
(set! (-> *progress-pc-generic-store* current-menu-hover-index) (-> curr-history-entry hover-index))
@@ -751,6 +750,7 @@
(when (and *progress-process* *progress-state* (!= (-> *progress-state* starting-state) 'title))
(stop-music-player)
(set-next-state (-> *progress-process* 0) 'go-away 0)
(clear-history! *progress-pc-generic-store*)
)
0
(none)
+283 -22
View File
@@ -1,24 +1,263 @@
;;-*-Lisp-*-
(in-package goal)
#|
Additional PC port specific file for overriding/expanding the progress menu
This gives us more freedom to write code how we want.
#|@file
Additional PC port specific file for overriding/expanding the progress menu
This gives us more freedom to write code how we want.
|#
(set! (-> *main-options-debug* options 9) (new 'static 'menu-main-menu-option :name (text-id progress-music-player) :scale #t :next-state 'music-player))
;; in jak 2, the options dont have to be all-caps anymore!
;; encode controller/display names - current bug waiting to happen
(define *game-options-pc*
(progress-new-generic-scrolling-page (text-id progress-root-game-options)
(new 'static 'menu-generic-boolean-option
:name (text-id progress-vibration)
:truthy-text (text-id progress-on)
:falsey-text (text-id progress-off)
:get-value-fn (lambda () (-> *setting-control* user-default vibration))
:on-confirm (lambda ((val symbol)) (set! (-> *setting-control* user-default vibration) val)))
(progress-new-generic-link-to-scrolling-page (text-id progress-menu-input-options)
(progress-new-generic-link-to-scrolling-page (text-id progress-camera-options)
(new 'static 'menu-generic-boolean-option
:name (text-id progress-camera-options-first-horz)
:truthy-text (text-id progress-normal)
:falsey-text (text-id progress-inverted)
:get-value-fn (lambda () (-> *pc-settings* first-camera-h-inverted?))
:on-confirm (lambda ((val symbol))
(set! (-> *pc-settings* first-camera-h-inverted?) val)
(commit-to-file *pc-settings*)))
(new 'static 'menu-generic-boolean-option
:name (text-id progress-camera-options-first-vert)
:truthy-text (text-id progress-normal)
:falsey-text (text-id progress-inverted)
:get-value-fn (lambda () (-> *pc-settings* first-camera-v-inverted?))
:on-confirm (lambda ((val symbol))
(set! (-> *pc-settings* first-camera-v-inverted?) val)
(commit-to-file *pc-settings*)))
(new 'static 'menu-generic-boolean-option
:name (text-id progress-camera-options-third-horz)
:truthy-text (text-id progress-normal)
:falsey-text (text-id progress-inverted)
:get-value-fn (lambda () (-> *pc-settings* third-camera-h-inverted?))
:on-confirm (lambda ((val symbol))
(set! (-> *pc-settings* third-camera-h-inverted?) val)
(commit-to-file *pc-settings*)))
(new 'static 'menu-generic-boolean-option
:name (text-id progress-camera-options-third-vert)
:truthy-text (text-id progress-normal)
:falsey-text (text-id progress-inverted)
:get-value-fn (lambda () (-> *pc-settings* third-camera-v-inverted?))
:on-confirm (lambda ((val symbol))
(set! (-> *pc-settings* third-camera-v-inverted?) val)
(commit-to-file *pc-settings*)))
(new 'static 'menu-generic-confirm-option
:name (text-id progress-restore-defaults)
:on-confirm (lambda ((val symbol))
(reset-camera *pc-settings* #t)
(commit-to-file *pc-settings*))))
(progress-new-generic-link-to-scrolling-page (text-id progress-menu-controller-options) :should-disable? (lambda () (<= (pc-get-controller-count) 0))
(new 'static 'menu-generic-carousel-option
:name (text-id progress-controller-options-select-controller)
:get-max-size-fn (lambda () (pc-get-controller-count))
:get-item-label-fn (lambda ((index int))
(pc-get-controller-name index *pc-cpp-temp-string*)
*pc-cpp-temp-string*)
:get-item-index-fn (lambda () 0)
:on-confirm (lambda ((index int)) (pc-set-controller! 0 index)))
(new 'static 'menu-generic-boolean-option
:name (text-id progress-vibration)
:should-disable? (lambda () (not (pc-current-controller-has-rumble?)))
:truthy-text (text-id progress-on)
:falsey-text (text-id progress-off)
:get-value-fn (lambda () (-> *setting-control* user-default vibration))
:on-confirm (lambda ((val symbol)) (set! (-> *setting-control* user-default vibration) val)))
(new 'static 'menu-generic-slider-option
:name (text-id progress-controller-options-analog-deadzone)
:min-value 0.0
:max-value 1.0
:step 0.01
:show-decimal? #t
:get-value-fn (lambda () (-> *pc-settings* stick-deadzone))
:on-confirm (lambda ((val float))
(set! (-> *pc-settings* stick-deadzone) val)
(commit-to-file *pc-settings*)))
(new 'static 'menu-generic-boolean-option
:name (text-id progress-controller-options-ignore-if-unfocused)
:truthy-text (text-id progress-on)
:falsey-text (text-id progress-off)
:get-value-fn (lambda () (-> *pc-settings* ignore-controller-win-unfocused?))
:on-confirm (lambda ((val symbol))
(set! (-> *pc-settings* ignore-controller-win-unfocused?) val)
(commit-to-file *pc-settings*)))
(new 'static 'menu-generic-boolean-option
:name (text-id progress-controller-options-led-hp)
:should-disable? (lambda () (not (pc-current-controller-has-led?)))
:truthy-text (text-id progress-on)
:falsey-text (text-id progress-off)
:get-value-fn (lambda () (-> *pc-settings* controller-hp-led?))
:on-confirm (lambda ((val symbol))
(set! (-> *pc-settings* controller-hp-led?) val)
(commit-to-file *pc-settings*)))
(new 'static 'menu-generic-boolean-option
:name (text-id progress-controller-options-led-darkjak)
:should-disable? (lambda () (not (pc-current-controller-has-led?)))
:truthy-text (text-id progress-on)
:falsey-text (text-id progress-off)
:get-value-fn (lambda () (-> *pc-settings* controller-eco-led?))
:on-confirm (lambda ((val symbol))
(set! (-> *pc-settings* controller-eco-led?) val)
(commit-to-file *pc-settings*)))
(new 'static 'menu-generic-confirm-option
:name (text-id progress-restore-defaults)
:on-confirm (lambda ((val symbol))
(reset-input *pc-settings* 'controller #t)
(set-ignore-controller-in-bg! *pc-settings* (-> *pc-settings* ignore-controller-win-unfocused?))
(commit-to-file *pc-settings*))))
(new 'static 'menu-generic-boolean-option
:name (text-id progress-input-options-enable-keyboard)
:truthy-text (text-id progress-on)
:falsey-text (text-id progress-off)
:get-value-fn (lambda () (-> *pc-settings* keyboard-enabled?))
:on-confirm (lambda ((val symbol))
(set! (-> *pc-settings* keyboard-enabled?) val)
(commit-to-file *pc-settings*)))
(new 'static 'menu-generic-boolean-option
:name (text-id progress-input-options-enable-mouse)
:truthy-text (text-id progress-on)
:falsey-text (text-id progress-off)
:get-value-fn (lambda () (-> *pc-settings* mouse-enabled?))
:on-confirm (lambda ((val symbol))
(set! (-> *pc-settings* mouse-enabled?) val)
(commit-to-file *pc-settings*)))
(progress-new-generic-link-to-scrolling-page (text-id progress-menu-mouse-options) :should-disable? (lambda () (not (-> *pc-settings* mouse-enabled?)))
(new 'static 'menu-generic-boolean-option
:name (text-id progress-mouse-options-track-camera)
:truthy-text (text-id progress-on)
:falsey-text (text-id progress-off)
:get-value-fn (lambda () (-> *pc-settings* mouse-camera?))
:on-confirm (lambda ((val symbol))
(set! (-> *pc-settings* mouse-camera?) val)
(commit-to-file *pc-settings*)))
(new 'static 'menu-generic-slider-option
:name (text-id progress-mouse-options-horz-sens)
:should-disable? (lambda () (not (-> *pc-settings* mouse-camera?)))
:min-value -30.0
:max-value 30.0
:step 0.10
:show-decimal? #t
:get-value-fn (lambda () (-> *pc-settings* mouse-xsens))
:on-confirm (lambda ((val float))
(set! (-> *pc-settings* mouse-xsens) val)
(commit-to-file *pc-settings*)))
(new 'static 'menu-generic-slider-option
:name (text-id progress-mouse-options-vert-sens)
:should-disable? (lambda () (not (-> *pc-settings* mouse-camera?)))
:min-value -30.0
:max-value 30.0
:step 0.10
:show-decimal? #t
:get-value-fn (lambda () (-> *pc-settings* mouse-ysens))
:on-confirm (lambda ((val float))
(set! (-> *pc-settings* mouse-ysens) val)
(commit-to-file *pc-settings*)))
(new 'static 'menu-generic-boolean-option
:name (text-id progress-mouse-options-player-movement)
:truthy-text (text-id progress-on)
:falsey-text (text-id progress-off)
:get-value-fn (lambda () (-> *pc-settings* mouse-movement?))
:on-confirm (lambda ((val symbol))
(set! (-> *pc-settings* mouse-movement?) val)
(commit-to-file *pc-settings*)))
(new 'static 'menu-generic-confirm-option
:name (text-id progress-restore-defaults)
:on-confirm (lambda ((val symbol))
(reset-input *pc-settings* 'mouse #t)
(update-mouse-controls! *pc-settings*)
(commit-to-file *pc-settings*))))
(new 'static 'menu-generic-boolean-option
:name (text-id progress-input-options-auto-hide-cursor)
:truthy-text (text-id progress-on)
:falsey-text (text-id progress-off)
:get-value-fn (lambda () (-> *pc-settings* auto-hide-cursor?))
:on-confirm (lambda ((val symbol))
(set! (-> *pc-settings* auto-hide-cursor?) val)
(update-mouse-controls! *pc-settings*)
(commit-to-file *pc-settings*)))
;; TODO - there is a bug where if you restore default binds and that changes your `X` bind,
;; the next X input is ignored, figure this out eventually / make an issue for it.
(progress-new-generic-link-to-scrolling-page (text-id progress-menu-reassign-binds)
(progress-new-generic-link-to-details-page (text-id progress-reassign-binds-controller) :should-disable? (lambda () (<= (pc-get-controller-count) 0))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind select) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind l3) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind r3) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind start) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind dpad-up) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind dpad-right) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind dpad-down) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind dpad-left) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind l2) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind r2) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind l1) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind r1) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind triangle) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind circle) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind cross) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind square) :device-type (input-device-type controller))
(new 'static 'menu-generic-details-confirm-entry
:name (text-id progress-restore-defaults)
:on-confirm (lambda () (pc-reset-bindings-to-defaults! 0 0))))
(progress-new-generic-link-to-details-page (text-id progress-reassign-binds-keyboard) :should-disable? (lambda () (not (-> *pc-settings* keyboard-enabled?)))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind l-analog-up) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind l-analog-down) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind l-analog-left) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind l-analog-right) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind r-analog-up) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind r-analog-down) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind r-analog-left) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind r-analog-right) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind select) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind l3) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind r3) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind start) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind dpad-up) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind dpad-right) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind dpad-down) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind dpad-left) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind l2) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind r2) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind l1) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind r1) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind triangle) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind circle) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind cross) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind square) :device-type (input-device-type keyboard))
(new 'static 'menu-generic-details-confirm-entry
:name (text-id progress-restore-defaults)
:on-confirm (lambda () (pc-reset-bindings-to-defaults! 0 1))))
(progress-new-generic-link-to-details-page (text-id progress-reassign-binds-mouse) :should-disable? (lambda () (not (-> *pc-settings* mouse-enabled?)))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind select) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind l3) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind r3) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind start) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind dpad-up) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind dpad-right) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind dpad-down) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind dpad-left) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind l2) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind r2) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind l1) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind r1) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind triangle) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind circle) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind cross) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-keybind-entry :keybind (controller-keybind square) :device-type (input-device-type mouse))
(new 'static 'menu-generic-details-confirm-entry
:name (text-id progress-restore-defaults)
:on-confirm (lambda () (pc-reset-bindings-to-defaults! 0 2)))))
(new 'static 'menu-generic-confirm-option
:name (text-id progress-restore-defaults)
:on-confirm (lambda ((val symbol))
(reset-input *pc-settings* 'input #t)
(set-enable-keyboard! *pc-settings* (-> *pc-settings* keyboard-enabled?))
(update-mouse-controls! *pc-settings*)
(commit-to-file *pc-settings*))))
(new 'static 'menu-generic-boolean-option
:name (text-id progress-subtitles)
:truthy-text (text-id progress-on)
@@ -55,18 +294,40 @@
;; NOTE - this doesn't actually work (naughty dog tried it too in their progress code)
;; fix it eventually
(load-level-text-files (the-as int (-> *setting-control* user-default language)))))
(progress-new-generic-link (text-id progress-misc-game-options)
(progress-new-generic-scrolling-page (text-id progress-misc-game-options)
(new 'static 'menu-generic-boolean-option
:name (text-id progress-speedrunner-mode)
:truthy-text (text-id progress-on)
:falsey-text (text-id progress-off)
:get-value-fn (lambda () (-> *pc-settings* speedrunner-mode?))
:on-confirm (lambda ((val symbol))
(set! (-> *pc-settings* speedrunner-mode?) val)
(commit-to-file *pc-settings*)))))))
(progress-new-generic-link-to-scrolling-page (text-id progress-misc-game-options)
(new 'static 'menu-generic-boolean-option
:name (text-id progress-discord-rpc)
:truthy-text (text-id progress-on)
:falsey-text (text-id progress-off)
:get-value-fn (lambda () (-> *pc-settings* discord-rpc?))
:on-confirm (lambda ((val symbol))
(set! (-> *pc-settings* discord-rpc?) val)
(commit-to-file *pc-settings*)))
(new 'static 'menu-generic-boolean-option
:name (text-id progress-speedrunner-mode)
:truthy-text (text-id progress-on)
:falsey-text (text-id progress-off)
:get-value-fn (lambda () (-> *pc-settings* speedrunner-mode?))
:on-confirm (lambda ((val symbol))
(set! (-> *pc-settings* speedrunner-mode?) val)
(commit-to-file *pc-settings*))))))
;; TODO - migrate this menu as well
;; graphic options
;; resolution
;; display mode
;; display select (disable if windowed)
;; vsync
;; aspect ratio
;; msaa
;; frame rate (dont go beyond refresh rate) (disable if SRMode)
;; ps2 options
;; lod bg
;; lod fg
;; particle culling
;; force env mapping
;; actor culling
(define *graphic-options-pc*
(new 'static 'menu-option-list
:y-center 198