mirror of
https://github.com/open-goal/jak-project
synced 2026-07-08 14:36:52 -04:00
game: fix level select for untranslated languages and fix infinite recursion edge-case in lookup-text! (#3969)
The main bug this fixes is not being able to use level select when your language isn't translated. Why? Because they use the result from `lookup-text!` to determine if a menu item should be drawn or not. No text found, no menu item. However this uncovered a long-standing bug in my fallback extension to this code. If you call this function with a text-id that doesnt even have an english string, it will recursively keep calling itself until it crashes. Of course the first few tasks in the game are dummies and have no valid text-id so this had to be fixed. Should be fixed for all 3 games.
This commit is contained in:
@@ -67,10 +67,10 @@
|
||||
(+! (-> arg0 data 80 total) (logand -16 (+ v1-18 15)))))
|
||||
this)
|
||||
|
||||
(defmethod lookup-text! ((this game-text-info) (arg0 text-id) (arg1 symbol))
|
||||
"Look up text by ID. Will return the string.
|
||||
If the ID can't be found, and arg1 is #t, it will return #f,
|
||||
otherwise the temp string UNKNOWN ID <id number>"
|
||||
;; og:preserve-this extracted implementation out so that callers of `lookup-text!` were uneffected
|
||||
;; this implementation is different from the original (has fallback text lookup)
|
||||
(define-extern lookup-text-impl! (function game-text-info text-id symbol symbol string))
|
||||
(defun lookup-text-impl! ((this game-text-info) (arg0 text-id) (arg1 symbol) (fallback-call? symbol))
|
||||
;; binary search for it
|
||||
(let* ((a1-1 0) ;; min
|
||||
(a3-0 (+ (-> this length) 1)) ;; max
|
||||
@@ -88,19 +88,35 @@
|
||||
(cond
|
||||
((!= (-> this data v1-2 id) arg0) ;; didn't find it :(
|
||||
(cond
|
||||
(arg1 (the-as string #f))
|
||||
(else
|
||||
;; First, look up the id in the fallback
|
||||
(arg1
|
||||
;; og:preserve-this Added fallback to english is string is not found.
|
||||
(#if PC_PORT
|
||||
(if *fallback-text-lookup?*
|
||||
(let ((fallback-result (lookup-text! *fallback-text* arg0 #t)))
|
||||
(if (!= fallback-result #f) fallback-result (string-format "UNKNOWN ID ~D" arg0)))
|
||||
(if (and *fallback-text-lookup?* (not fallback-call?))
|
||||
(aif (lookup-text-impl! *fallback-text* arg0 #t #t)
|
||||
it
|
||||
(the-as string #f))
|
||||
(the-as string #f))
|
||||
(the-as string #f)))
|
||||
(else
|
||||
;; og:preserve-this Added fallback to english is string is not found.
|
||||
(#if PC_PORT
|
||||
(if (and *fallback-text-lookup?* (not fallback-call?))
|
||||
(aif (lookup-text-impl! *fallback-text* arg0 #t #t)
|
||||
it
|
||||
(string-format "UNKNOWN ID ~D" arg0))
|
||||
(string-format "UNKNOWN ID ~D" arg0))
|
||||
(string-format "UNKNOWN ID ~D" arg0)))))
|
||||
(else
|
||||
(-> this data v1-2 text) ;; found it!
|
||||
))))
|
||||
|
||||
(defmethod lookup-text! ((this game-text-info) (arg0 text-id) (arg1 symbol))
|
||||
"Look up text by ID. Will return the string.
|
||||
If the ID can't be found, and arg1 is #t, it will return #f,
|
||||
otherwise the temp string UNKNOWN ID <id number>"
|
||||
;; og:preserve-this call custom function
|
||||
(lookup-text-impl! this arg0 arg1 #f))
|
||||
|
||||
;; Game text loading.
|
||||
;; The implementation of loading is blocking.
|
||||
;; If you change languages, the game will freeze for a second while it loads
|
||||
|
||||
@@ -160,7 +160,10 @@
|
||||
)
|
||||
)
|
||||
|
||||
(defmethod lookup-text! ((this game-text-info) (arg0 text-id) (arg1 symbol))
|
||||
;; og:preserve-this extracted implementation out so that callers of `lookup-text!` were uneffected
|
||||
;; this implementation is different from the original (has fallback text lookup)
|
||||
(define-extern lookup-text-impl! (function game-text-info text-id symbol symbol string))
|
||||
(defun lookup-text-impl! ((this game-text-info) (arg0 text-id) (arg1 symbol) (fallback-call? symbol))
|
||||
(cond
|
||||
((= this #f)
|
||||
(cond
|
||||
@@ -192,15 +195,23 @@
|
||||
((!= (-> this data v1-2 id) arg0)
|
||||
(cond
|
||||
(arg1
|
||||
(the-as string #f)
|
||||
;; og:preserve-this Added fallback to english is string is not found.
|
||||
(#if PC_PORT
|
||||
(if (and *fallback-text-lookup?* (not fallback-call?))
|
||||
(aif (lookup-text-impl! *fallback-text* arg0 #t #t)
|
||||
it
|
||||
(the-as string #f))
|
||||
(the-as string #f))
|
||||
(the-as string #f))
|
||||
)
|
||||
(else
|
||||
;; og:preserve-this Added fallback to english is string is not found.
|
||||
(#if PC_PORT
|
||||
(if *fallback-text-lookup?*
|
||||
(aif (lookup-text! *fallback-text* arg0 #t)
|
||||
(if (and *fallback-text-lookup?* (not fallback-call?))
|
||||
(aif (lookup-text-impl! *fallback-text* arg0 #t #t)
|
||||
it
|
||||
(string-format "UNKNOWN ID ~D" arg0)))
|
||||
(string-format "UNKNOWN ID ~D" arg0))
|
||||
(string-format "UNKNOWN ID ~D" arg0))
|
||||
(string-format "UNKNOWN ID ~D" arg0))
|
||||
)
|
||||
)
|
||||
@@ -214,8 +225,14 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
))
|
||||
|
||||
(defmethod lookup-text! ((this game-text-info) (arg0 text-id) (arg1 symbol))
|
||||
"Look up text by ID. Will return the string.
|
||||
If the ID can't be found, and arg1 is #t, it will return #f,
|
||||
otherwise the temp string UNKNOWN ID <id number>"
|
||||
;; og:preserve-this call custom function
|
||||
(lookup-text-impl! this arg0 arg1 #f))
|
||||
|
||||
(defmethod lookup-text ((this level) (arg0 text-id) (arg1 symbol))
|
||||
(let ((v1-0 *common-text*))
|
||||
|
||||
@@ -159,7 +159,10 @@
|
||||
)
|
||||
)
|
||||
|
||||
(defmethod lookup-text! ((this game-text-info) (arg0 text-id) (arg1 symbol))
|
||||
;; og:preserve-this extracted implementation out so that callers of `lookup-text!` were uneffected
|
||||
;; this implementation is different from the original (has fallback text lookup)
|
||||
(define-extern lookup-text-impl! (function game-text-info text-id symbol symbol string))
|
||||
(defun lookup-text-impl! ((this game-text-info) (arg0 text-id) (arg1 symbol) (fallback-call? symbol))
|
||||
(cond
|
||||
((= this #f)
|
||||
(cond
|
||||
@@ -191,15 +194,23 @@
|
||||
((!= (-> this data v1-2 id) arg0)
|
||||
(cond
|
||||
(arg1
|
||||
(the-as string #f)
|
||||
;; og:preserve-this Added fallback to english is string is not found.
|
||||
(#if PC_PORT
|
||||
(if (and *fallback-text-lookup?* (not fallback-call?))
|
||||
(aif (lookup-text-impl! *fallback-text* arg0 #t #t)
|
||||
it
|
||||
(the-as string #f))
|
||||
(the-as string #f))
|
||||
(the-as string #f))
|
||||
)
|
||||
(else
|
||||
;; og:preserve-this Added fallback to English if string is not found.
|
||||
;; og:preserve-this Added fallback to english is string is not found.
|
||||
(#if PC_PORT
|
||||
(if *fallback-text-lookup?*
|
||||
(aif (lookup-text! *fallback-text* arg0 #t)
|
||||
(if (and *fallback-text-lookup?* (not fallback-call?))
|
||||
(aif (lookup-text-impl! *fallback-text* arg0 #t #t)
|
||||
it
|
||||
(string-format "UNKNOWN ID ~D" arg0)))
|
||||
(string-format "UNKNOWN ID ~D" arg0))
|
||||
(string-format "UNKNOWN ID ~D" arg0))
|
||||
(string-format "UNKNOWN ID ~D" arg0))
|
||||
)
|
||||
)
|
||||
@@ -213,8 +224,14 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
))
|
||||
|
||||
(defmethod lookup-text! ((this game-text-info) (arg0 text-id) (arg1 symbol))
|
||||
"Look up text by ID. Will return the string.
|
||||
If the ID can't be found, and arg1 is #t, it will return #f,
|
||||
otherwise the temp string UNKNOWN ID <id number>"
|
||||
;; og:preserve-this call custom function
|
||||
(lookup-text-impl! this arg0 arg1 #f))
|
||||
|
||||
(defmethod lookup-text ((this level) (arg0 text-id) (arg1 symbol))
|
||||
(let ((v1-0 *common-text*))
|
||||
|
||||
Reference in New Issue
Block a user