diff --git a/goal_src/jak1/engine/ui/text-h.gc b/goal_src/jak1/engine/ui/text-h.gc index c892702978..99d416cb59 100644 --- a/goal_src/jak1/engine/ui/text-h.gc +++ b/goal_src/jak1/engine/ui/text-h.gc @@ -837,6 +837,19 @@ ;; will store the COMMON text when it is loaded. (define *common-text* (the-as game-text-info #f)) +;; NOTE - PC PORT difference +;; Partial translations are a thing that we should support. Parts of translating the game are intentionally made +;; difficult for normal translators due to not wanting to make all the strings public (or in the case of subtitles, +;; we straight up didn't have them yet) +;; +;; So to remedy this, we always load the english text as a fallback so that if there is only a partial translation +;; the UX won't be horrible with everything displaying as UNKNOWN. +;; +;; One of the reasons we didn't do this is because it makes it obvious which strings are remaining, +;; but there are better ways to keep track or check if strings are missing. +(#when PC_PORT + (kheap-alloc (define *fallback-text-heap* (new 'global 'kheap)) (* 48 1024)) ;; 48K heap, should be plenty + (define *fallback-text* (the-as game-text-info #f))) (defun-extern print-game-text string font-context symbol int int float) diff --git a/goal_src/jak1/engine/ui/text.gc b/goal_src/jak1/engine/ui/text.gc index d045e92094..492f6f2711 100644 --- a/goal_src/jak1/engine/ui/text.gc +++ b/goal_src/jak1/engine/ui/text.gc @@ -113,7 +113,15 @@ (the-as string #f) ) (else - (string-format "UNKNOWN ID ~D" arg0) + ;; First, look up the id in the fallback + (#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))) + (string-format "UNKNOWN ID ~D" arg0)) + (string-format "UNKNOWN ID ~D" arg0)) ) ) ) @@ -237,14 +245,110 @@ v0-2 ) +(defun load-fallback-game-text-info ((txt-name string) (curr-text symbol) (heap kheap)) + "Largely duplication of `load-game-text-info` but is hardcoded to load english (language 0)" + (local-vars + (v0-2 int) + (heap-sym-heap game-text-info) + (lang language-enum) + (load-status int) + (heap-free int) + ) + (set! heap-sym-heap (the-as game-text-info (-> curr-text value))) + (set! lang (language-enum english)) + (set! load-status 0) + (set! heap-free (&- (-> heap top) (the-as uint (-> heap base)))) + + ;; only load if we actually need to + (when (or (= heap-sym-heap #f) ;; nothing loaded + (!= (-> heap-sym-heap language-id) (the-as uint lang)) ;; loaded, but wrong lang + (not (string= (-> heap-sym-heap group-name) txt-name)) ;; loaded, but wrong group + ) + + ;; clear the heap! + (let ((v1-16 heap)) + (set! (-> v1-16 current) (-> v1-16 base)) + ) + (b! #t cfg-14) + (label cfg-13) + (load-dbg "Strange error during text load.~%") + (set! v0-2 0) + (b! #t cfg-27) + (label cfg-14) + + ;; call str-load to start loading the TXT file to the heap + (let ((s3-0 str-load)) + (format (clear *temp-string*) "~D~S.TXT" lang txt-name) + ;; this branch is super weird. + (b! (not (s3-0 + *temp-string* + -1 + (logand -64 (&+ (-> heap current) 63)) + (&- (-> heap top) (the-as uint (-> heap current))) + ) + ) + cfg-13 + ) + ) + + ;; loop to wait until loading is complete + (label cfg-16) + (let ((v1-20 (str-load-status (the-as (pointer int32) (& load-status))))) + (cond + ((= v1-20 'error) + (format 0 "Error loading text~%") + (return 0) + ) + ((>= load-status (+ heap-free -300)) + (format 0 "Game text heap overrun!~%") + (return 0) + ) + ((= v1-20 'busy) + (begin + (nop!) + (nop!) + (nop!) + (nop!) + (nop!) + (nop!) + (goto cfg-16) + ) + ) + ) + ) + + ;; loading is done. now we link. + (let ((s2-1 (logand -64 (&+ (-> heap current) 63)))) + (flush-cache 0) + (let ((s3-1 link)) + (format (clear *temp-string*) "~D~S.TXT" lang txt-name) + (set! (-> curr-text value) + (s3-1 s2-1 (-> *temp-string* data) load-status heap 0) + ) + ) + ) + + ;; linking error occured? + (if (<= (the-as int (-> curr-text value)) 0) + (set! (-> curr-text value) (the-as object #f)) + ) + ) + (set! v0-2 0) + (label cfg-27) + + v0-2 + ) + (defun load-level-text-files ((arg0 int)) "Load the text files needed for level idx. This function made more sense back when text files were split up, but in the end they put everything in a single text group and file." - (if (or *level-text-file-load-flag* (>= arg0 0)) - (load-game-text-info "common" '*common-text* *common-text-heap*) - ) + (when (or *level-text-file-load-flag* (>= arg0 0)) + (load-game-text-info "common" '*common-text* *common-text-heap*) + (#when PC_PORT + (load-fallback-game-text-info "common" '*fallback-text* *fallback-text-heap*)) + ) (none) ) diff --git a/goal_src/jak1/pc/debug/default-menu-pc.gc b/goal_src/jak1/pc/debug/default-menu-pc.gc index 64235848e9..f93ef08f54 100644 --- a/goal_src/jak1/pc/debug/default-menu-pc.gc +++ b/goal_src/jak1/pc/debug/default-menu-pc.gc @@ -777,6 +777,7 @@ (flag "br-portuguese" 13 dm-text-language) (flag "hungarian" 14 dm-text-language) ) + (flag "Fallback Text Search" #f ,(dm-lambda-boolean-flag *fallback-text-lookup?*)) (flag "Discord RPC" #t ,(dm-lambda-boolean-flag (-> *pc-settings* discord-rpc?))) (flag "Speedrunner Mode" #t ,(dm-lambda-boolean-flag (-> *pc-settings* speedrunner-mode?))) (menu "PS2 settings" diff --git a/goal_src/jak1/pc/pckernel-impl.gc b/goal_src/jak1/pc/pckernel-impl.gc index e7699ee6c4..0ce46cffbe 100644 --- a/goal_src/jak1/pc/pckernel-impl.gc +++ b/goal_src/jak1/pc/pckernel-impl.gc @@ -55,6 +55,8 @@ ;;;; debug settings ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define *fallback-text-lookup?* #t) + (define *display-bug-report* #f) (define *mood-override-debug* #f)