mirror of
https://github.com/open-goal/jak-project
synced 2026-09-11 20:41:41 -04:00
427c952558
This PR fixes the alignment of text and other elements in several menus of Jak 3 (as well as some of Jak 2) when using Automatic or Custom aspect ratios. It also cleans up some of the relevant functions which are used to draw these menus (although I'm still learning how to clean goal code). I mostly used french text for testing (since the french text seems to push the font boundaries to their limits a bit more). I used Automatic 16:9 and Custom 4:1 aspect ratios for testing to see if my changes scale to other aspect ratios properly, comparing with PS2 4:3 for reference. ### Jak 3 ### Image Color Scale Before: - The black/white color scale would get stretched (beyond the limits of the menu in 4x1) <img width="1280" height="758" alt="color-scale-16x9-broken" src="https://github.com/user-attachments/assets/4b3b897e-1417-42da-86a1-dd78926ccb73" /> <img width="1283" height="747" alt="color-scale-4x1-broken" src="https://github.com/user-attachments/assets/44d192ba-5afe-43ae-9419-021123478a31" /> Reference (PS2 4:3 in OpenGoal): <img width="1278" height="773" alt="color-scale-reference" src="https://github.com/user-attachments/assets/d9bd8f4e-8f69-49a9-8a99-3fcd3d7a4097" /> After fixes: <img width="1283" height="765" alt="color-scale-16x9-fixed" src="https://github.com/user-attachments/assets/99422d7f-d688-4d91-8ce0-6ad0b7cb10df" /> <img width="1282" height="762" alt="color-scale-4x1-fixed" src="https://github.com/user-attachments/assets/6011f30a-0c31-4ea9-afe1-735ec36f3d32" /> ### Secrets menu Before: - The secret titles touch their costs (#4233). - The alignment of the top line showing orbs available/cost and total orbs collected is broken (more noticeable in 4:1) - The alignment of the titles for groups of secrets is broken (more noticeable in 4:1) - The indentation for secret titles relative to the group of secrets is also broken (again, more noticeable in 4:1) <img width="1286" height="758" alt="secrets-broken-16x9" src="https://github.com/user-attachments/assets/bd6c7dab-ce95-4349-bf1d-2a09f82fcbfe" /> <img width="1287" height="751" alt="secrets-broken-4x1" src="https://github.com/user-attachments/assets/3e1ce842-19ba-49b3-92f9-52034ae1982f" /> Reference (PS2 4:3 in OpenGoal): <img width="1280" height="761" alt="Screenshot from 2026-08-16 22-58-22" src="https://github.com/user-attachments/assets/7326a1c7-b479-4fb7-9450-377a05ab7963" /> After fixes: <img width="1280" height="722" alt="secrets-fixed-16x9" src="https://github.com/user-attachments/assets/0a66d45f-3aa3-4cc8-ac88-c6aef20f1319" /> <img width="1286" height="713" alt="secrets-fixed-4x1" src="https://github.com/user-attachments/assets/e8740739-42ac-4a12-aad1-e6620dfc73ed" /> ### Secrets purchase menu Before: - The text for the secret you're purchasing can get cut off if too big. - As before, the top line showing orb cost/orbs collected is misaligned. <img width="1288" height="754" alt="secrets-purchase-broken-16x9" src="https://github.com/user-attachments/assets/49b709e3-c015-42ba-b0aa-034769286d77" /> <img width="1281" height="756" alt="secrets-purchase-broken-4x1" src="https://github.com/user-attachments/assets/0c3c5e02-048a-4188-ada7-2413c384224b" /> Reference (PS2 4:3 in OpenGoal): <img width="1286" height="753" alt="secrets-purchase-reference" src="https://github.com/user-attachments/assets/bb0b1d1a-87f6-4343-8a82-2e1f968943cd" /> After fixes: <img width="1286" height="759" alt="secrets-purchase-fixed-16x9" src="https://github.com/user-attachments/assets/1d73593f-1d58-407e-9ce6-2da5bf0fd84b" /> <img width="1283" height="750" alt="secrets-purchase-fixed-4x1" src="https://github.com/user-attachments/assets/85c7e14d-c6b2-4b21-83e5-173af5cba185" /> ### Save/Load/Create Hero Mode Save menu Here I show the load game screen only but the bugs were the same among all 3 as the code is shared. The fixes apply to all 3 as well 😃 Before: - The header text is cut off in french. - There is a faint red rectangle to the right of the menu (look closely! It's a bit clearer and goes beyond the menu in 4x1). - The left yellow boxes around the save-games that are not selected do not scale properly (more noticeable in 4x1). <img width="1284" height="749" alt="load-broken-Automatic" src="https://github.com/user-attachments/assets/2ae3bd8b-42ec-49bc-9851-cbaace4ce64b" /> <img width="1285" height="751" alt="load-broken-4x1" src="https://github.com/user-attachments/assets/655de844-748c-43f9-a2e8-d779fe3a8e19" /> Reference (PS2 4:3 in OpenGoal): <img width="1281" height="762" alt="load-screen-4x3" src="https://github.com/user-attachments/assets/e4e320c9-999a-44a7-8b3e-34cfdbeef5a1" /> After Fixes: - Now headers that exceed the width of the menu screen will be shrunken down to fit. This will hopefully work for any other menus that need it as well 😃 - No more red rectangle on the right, and the yellow box to the left around the save games scales properly. <img width="1286" height="754" alt="load-fixed-automatic" src="https://github.com/user-attachments/assets/1a48d811-5684-4f7e-a12a-19e896e30b48" /> <img width="1288" height="749" alt="load-fixed-4x1" src="https://github.com/user-attachments/assets/f5a68cb1-576a-4927-977b-b3419aaf7c23" /> ### Missions menu Before: - Mission text is sometimes cut off on the right - Mission text is shifted to the right (more noticeable in 4x1) <img width="1286" height="753" alt="missions-alignment-broken-16x9" src="https://github.com/user-attachments/assets/37175eb7-e191-4c09-bb72-b40819acd99b" /> <img width="1281" height="750" alt="missions-alignment-broken-16x9-2" src="https://github.com/user-attachments/assets/482f351a-7386-4211-8434-cf60c0691fdb" /> <img width="1286" height="756" alt="missions-broken-4x1" src="https://github.com/user-attachments/assets/4cbfa4d0-999b-4265-bed0-957958663037" /> <img width="1290" height="750" alt="missions-broken-4x1-2" src="https://github.com/user-attachments/assets/4889b498-d6aa-4e6c-87fc-4dfadeac5827" /> Reference (PS2 4:3 in OpenGoal): <img width="1284" height="768" alt="missions-reference-1" src="https://github.com/user-attachments/assets/91a526c8-08c2-4a62-8219-09e967fab9c2" /> <img width="1276" height="755" alt="missions-reference-2" src="https://github.com/user-attachments/assets/65c4e944-5b1f-479a-bf7c-eca19c81f5d6" /> After: <img width="1281" height="760" alt="missions-fixed-16x9" src="https://github.com/user-attachments/assets/a972daf0-1872-46f0-a829-cd8d292df1d6" /> <img width="1282" height="750" alt="missions-fixed-16x9-2" src="https://github.com/user-attachments/assets/973611d6-a72c-43f8-b2f3-034e83f6c416" /> <img width="1289" height="760" alt="missions-alignment-fixed-4x1" src="https://github.com/user-attachments/assets/699c5dbc-8c39-468d-9e14-94007a789e48" /> <img width="1281" height="755" alt="missions-alignment-fixed-4x1-2" src="https://github.com/user-attachments/assets/89216187-d453-4d3e-8e8b-5ae365e7227d" /> ### Jak 2 ### Secrets menu orb icon Position was wrong in Automatic and some (but strangely, not all) Custom Aspect ratios. A correction for the aspect ratio was also being applied in the setter. Before: <img width="1284" height="755" alt="image" src="https://github.com/user-attachments/assets/0a15e238-1d98-4ba7-86ce-b295e8d78d7a" /> After: <img width="1283" height="755" alt="image" src="https://github.com/user-attachments/assets/bd97de44-ef41-426c-a76f-d4fe99a35285" /> ### Missions menu - Indentation was not working, even in 4:3, due to a typo. - Width was broken in Automatic and Custom Before: <img width="1281" height="753" alt="Screenshot from 2026-08-19 01-05-54" src="https://github.com/user-attachments/assets/6f5e3cc4-3522-45a5-a45b-34a46a7db544" /> After: <img width="1287" height="761" alt="image" src="https://github.com/user-attachments/assets/cae5498b-6ca4-40ab-a31c-feb8899bc1e7" />
645 lines
25 KiB
Common Lisp
645 lines
25 KiB
Common Lisp
;;-*-Lisp-*-
|
|
(in-package goal)
|
|
|
|
;; name: text.gc
|
|
;; name in dgo: text
|
|
;; dgos: GAME
|
|
|
|
;; DECOMP BEGINS
|
|
|
|
(kmemopen global "text-buffers")
|
|
|
|
(define *expand-buf-number* 0)
|
|
|
|
(define *game-text-word* (new 'global 'string 256 (the-as string #f)))
|
|
|
|
(define *game-text-line* (new 'global 'string 1024 (the-as string #f)))
|
|
|
|
(define *expanded-text-line0* (new 'global 'string 1024 (the-as string #f)))
|
|
|
|
(define *expanded-text-line1* (new 'global 'string 1024 (the-as string #f)))
|
|
|
|
(define *level-text-file-load-flag* #t)
|
|
|
|
(when (zero? (-> *common-text-heap* base))
|
|
(kheap-alloc *common-text-heap* (* 96 1024))
|
|
)
|
|
|
|
(kmemclose)
|
|
|
|
(defmethod relocate ((this game-text-info) (offset int))
|
|
(let ((v1-1 (-> *level* loading-level)))
|
|
(when v1-1
|
|
(set! (-> v1-1 loaded-text-info (-> v1-1 loaded-text-info-count)) this)
|
|
(+! (-> v1-1 loaded-text-info-count) 1)
|
|
)
|
|
)
|
|
this
|
|
)
|
|
|
|
(defmethod length ((this game-text-info))
|
|
(-> this length)
|
|
)
|
|
|
|
;; WARN: Return type mismatch uint vs int.
|
|
(defmethod asize-of ((this game-text-info))
|
|
(the-as int (+ (-> this type size) (* (-> this length) 8)))
|
|
)
|
|
|
|
|
|
(defmethod mem-usage ((this game-text-info) (usage memory-usage-block) (flags int))
|
|
(set! (-> usage length) (max 85 (-> usage length)))
|
|
(set! (-> usage data 84 name) "string")
|
|
(+! (-> usage data 84 count) 1)
|
|
(let ((v1-6 (asize-of this)))
|
|
(+! (-> usage data 84 used) v1-6)
|
|
(+! (-> usage data 84 total) (logand -16 (+ v1-6 15)))
|
|
)
|
|
(dotimes (s4-0 (-> this length))
|
|
(set! (-> usage length) (max 85 (-> usage length)))
|
|
(set! (-> usage data 84 name) "string")
|
|
(+! (-> usage data 84 count) 1)
|
|
(let ((v1-18 (asize-of (-> this data s4-0 text))))
|
|
(+! (-> usage data 84 used) v1-18)
|
|
(+! (-> usage data 84 total) (logand -16 (+ v1-18 15)))
|
|
)
|
|
)
|
|
this
|
|
)
|
|
|
|
(defun convert-korean-text ((arg0 string))
|
|
(local-vars (v1-21 int))
|
|
(let ((gp-0 (-> arg0 data)))
|
|
*expanded-text-line0*
|
|
(let ((s4-0 0))
|
|
0
|
|
(let ((s1-0 0)
|
|
(s5-0 (length arg0))
|
|
)
|
|
(set! *expand-buf-number* (logxor *expand-buf-number* 1))
|
|
(let ((s3-0 (if (zero? *expand-buf-number*)
|
|
*expanded-text-line0*
|
|
*expanded-text-line1*
|
|
)
|
|
)
|
|
)
|
|
(let ((s2-0 (+ (-> s3-0 allocated-length) -1)))
|
|
(clear s3-0)
|
|
(while (< s4-0 s5-0)
|
|
(cond
|
|
((= (-> gp-0 s4-0) 3)
|
|
(+! s4-0 1)
|
|
(while (and (< s4-0 s5-0) (!= (-> gp-0 s4-0) 3) (!= (-> gp-0 s4-0) 4))
|
|
(set! (-> s3-0 data s1-0) (-> gp-0 s4-0))
|
|
(+! s4-0 1)
|
|
(+! s1-0 1)
|
|
)
|
|
)
|
|
(else
|
|
(let ((v1-17 (+ s4-0 1)))
|
|
(-> gp-0 v1-17)
|
|
(set! s4-0 (+ v1-17 1))
|
|
)
|
|
(set! (-> s3-0 data s1-0) (the-as uint 126))
|
|
(let ((v1-19 (+ s1-0 1)))
|
|
(set! (-> s3-0 data v1-19) (the-as uint 89))
|
|
(let ((v1-20 (+ v1-19 1)))
|
|
(while (and (< s4-0 s5-0) (< v1-20 s2-0) (!= (-> gp-0 s4-0) 3) (!= (-> gp-0 s4-0) 4))
|
|
(cond
|
|
((= (-> gp-0 s4-0) 5)
|
|
(set! (-> s3-0 data v1-20) (the-as uint 1))
|
|
(+! s4-0 1)
|
|
(set! v1-21 (+ v1-20 1))
|
|
)
|
|
(else
|
|
(set! (-> s3-0 data v1-20) (the-as uint 3))
|
|
(set! v1-21 (+ v1-20 1))
|
|
)
|
|
)
|
|
(set! (-> s3-0 data v1-21) (-> gp-0 s4-0))
|
|
(+! s4-0 1)
|
|
(let ((v1-22 (+ v1-21 1)))
|
|
(set! (-> s3-0 data v1-22) (the-as uint 126))
|
|
(let ((v1-23 (+ v1-22 1)))
|
|
(set! (-> s3-0 data v1-23) (the-as uint 90))
|
|
(set! v1-20 (+ v1-23 1))
|
|
)
|
|
)
|
|
)
|
|
(set! (-> s3-0 data v1-20) (the-as uint 126))
|
|
(let ((v1-24 (+ v1-20 1)))
|
|
(set! (-> s3-0 data v1-24) (the-as uint 43))
|
|
(let ((v1-25 (+ v1-24 1)))
|
|
(set! (-> s3-0 data v1-25) (the-as uint 50))
|
|
(let ((v1-26 (+ v1-25 1)))
|
|
(set! (-> s3-0 data v1-26) (the-as uint 54))
|
|
(let ((v1-27 (+ v1-26 1)))
|
|
(set! (-> s3-0 data v1-27) (the-as uint 72))
|
|
(set! s1-0 (+ v1-27 1))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
(set! (-> s3-0 data s1-0) (the-as uint 0))
|
|
s3-0
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
;; 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
|
|
(arg1
|
|
(the-as string #f)
|
|
)
|
|
(else
|
|
(format (clear *temp-string*) "NO GAME TEXT")
|
|
*temp-string*
|
|
)
|
|
)
|
|
)
|
|
(else
|
|
(let* ((a1-2 0)
|
|
(a3-0 (+ (-> this length) 1))
|
|
(v1-2 (/ (+ a1-2 a3-0) 2))
|
|
)
|
|
(let ((t0-0 -1))
|
|
(while (and (!= (-> this data v1-2 id) arg0) (!= v1-2 t0-0))
|
|
(if (< (the-as uint arg0) (the-as uint (-> this data v1-2 id)))
|
|
(set! a3-0 v1-2)
|
|
(set! a1-2 v1-2)
|
|
)
|
|
(set! t0-0 v1-2)
|
|
(set! v1-2 (/ (+ a1-2 a3-0) 2))
|
|
)
|
|
)
|
|
(cond
|
|
((!= (-> this data v1-2 id) arg0)
|
|
(cond
|
|
(arg1
|
|
;; 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 (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))
|
|
)
|
|
)
|
|
)
|
|
((= (-> this language-id) 7)
|
|
(convert-korean-text (-> this data v1-2 text))
|
|
)
|
|
(else
|
|
(-> this data v1-2 text)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
))
|
|
|
|
(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*))
|
|
(dotimes (a3-0 (-> this loaded-text-info-count))
|
|
;; og:preserve-this added
|
|
(if (= (-> this loaded-text-info a3-0 language-id) (#if PC_PORT (the language-enum (-> *pc-settings* text-language))
|
|
(-> *setting-control* user-current language)))
|
|
(set! v1-0 (-> this loaded-text-info a3-0))
|
|
)
|
|
)
|
|
(lookup-text! v1-0 arg0 arg1)
|
|
)
|
|
)
|
|
|
|
(define text-is-loading #f)
|
|
|
|
;; WARN: Found some very strange gotos. Check result carefully, this is not well tested.
|
|
(defun load-game-text-info ((arg0 string) (arg1 (pointer object)) (arg2 kheap))
|
|
(local-vars (v0-4 int) (sv-16 object) (sv-20 int) (sv-24 int) (sv-32 int))
|
|
(set! sv-16 (-> arg1 0))
|
|
;; og:preserve-this added
|
|
(set! sv-20 (#if PC_PORT (the int (-> *pc-settings* text-language))
|
|
(-> *setting-control* user-current language)))
|
|
(set! sv-24 0)
|
|
(set! sv-32 (&- (-> arg2 top) (the-as uint (-> arg2 base))))
|
|
;; english -> UK english in PAL
|
|
;; og:preserve-this no longer necessary.
|
|
(#unless PC_PORT
|
|
(if (and (= (scf-get-territory) GAME_TERRITORY_SCEE) (= sv-24 (the int (language-enum english))) (not (demo?)))
|
|
(set! sv-24 (the int (language-enum uk-english)))
|
|
)
|
|
)
|
|
(when (and (or (= sv-16 #f)
|
|
(!= (-> (the-as game-text-info sv-16) language-id) sv-20)
|
|
(not (string= (-> (the-as game-text-info sv-16) group-name) arg0))
|
|
)
|
|
(not (load-in-progress? *level*))
|
|
)
|
|
(let ((v1-19 arg2))
|
|
(set! (-> v1-19 current) (-> v1-19 base))
|
|
)
|
|
(b! #t cfg-21 :delay (nop!))
|
|
(label cfg-20)
|
|
(set! v0-4 0)
|
|
(b! #t cfg-34 :delay (nop!))
|
|
(label cfg-21)
|
|
(let ((s3-0 str-load))
|
|
(format (clear *temp-string*) "~D~S.TXT" sv-20 arg0)
|
|
(b!
|
|
(not (s3-0
|
|
*temp-string*
|
|
-1
|
|
(logand -64 (&+ (-> arg2 current) 63))
|
|
(&- (-> arg2 top) (the-as uint (-> arg2 current)))
|
|
)
|
|
)
|
|
cfg-20
|
|
:delay (nop!)
|
|
)
|
|
)
|
|
(label cfg-23)
|
|
(let ((v1-23 (str-load-status (the-as (pointer int32) (& sv-24)))))
|
|
(cond
|
|
((= v1-23 'error)
|
|
(format 0 "Error loading text~%")
|
|
(return 0)
|
|
)
|
|
((>= sv-24 (+ sv-32 -300))
|
|
(format 0 "Game text heap overrun!~%")
|
|
(return 0)
|
|
)
|
|
((= v1-23 'busy)
|
|
(nop!)
|
|
(nop!)
|
|
(nop!)
|
|
(nop!)
|
|
(nop!)
|
|
(nop!)
|
|
(goto cfg-23)
|
|
)
|
|
)
|
|
)
|
|
(let ((s2-1 (logand -64 (&+ (-> arg2 current) 63))))
|
|
(flush-cache 0)
|
|
(let ((s3-1 link))
|
|
(format (clear *temp-string*) "~D~S.TXT" sv-20 arg0)
|
|
(set! (-> arg1 0) (s3-1 s2-1 (-> *temp-string* data) sv-24 arg2 0))
|
|
)
|
|
)
|
|
(if (<= (the-as int (-> arg1 0)) 0)
|
|
(set! (-> arg1 0) (the-as object #f))
|
|
)
|
|
)
|
|
(set! v0-4 0)
|
|
(label cfg-34)
|
|
v0-4
|
|
)
|
|
|
|
(defun load-level-text-files ((arg0 int))
|
|
;; og:preserve-this Load in English file to use as a fallback
|
|
(when (or *level-text-file-load-flag* (>= arg0 0))
|
|
(load-game-text-info "common" (&-> '*common-text* value) *common-text-heap*)
|
|
(#when PC_PORT
|
|
(protect ((-> *pc-settings* text-language))
|
|
(set! (-> *pc-settings* text-language) (pc-language english))
|
|
(load-game-text-info "common" (&-> '*fallback-text* value) *fallback-text-heap*))))
|
|
(none))
|
|
|
|
(defun draw-debug-text-box ((arg0 font-context))
|
|
(when *cheat-mode*
|
|
(let ((s5-0 (new 'static 'vector4w))
|
|
(gp-0
|
|
(new 'static 'inline-array vector4w 4
|
|
(new 'static 'vector4w)
|
|
(new 'static 'vector4w)
|
|
(new 'static 'vector4w)
|
|
(new 'static 'vector4w)
|
|
)
|
|
)
|
|
)
|
|
(set-vector! (-> gp-0 0) (the int (+ -256.0 (-> arg0 origin x))) (the int (+ -208.0 (-> arg0 origin y))) 0 1)
|
|
(set-vector!
|
|
(-> gp-0 1)
|
|
(the int (+ -256.0 (-> arg0 width) (-> arg0 origin x)))
|
|
(the int (+ -208.0 (-> arg0 origin y)))
|
|
0
|
|
1
|
|
)
|
|
(set-vector!
|
|
(-> gp-0 2)
|
|
(the int (+ -256.0 (-> arg0 width) (-> arg0 origin x)))
|
|
(the int (+ -208.0 (-> arg0 height) (-> arg0 origin y)))
|
|
0
|
|
1
|
|
)
|
|
(set-vector!
|
|
(-> gp-0 3)
|
|
(the int (+ -256.0 (-> arg0 origin x)))
|
|
(the int (+ -208.0 (-> arg0 height) (-> arg0 origin y)))
|
|
0
|
|
1
|
|
)
|
|
(set-vector! s5-0 128 128 128 128)
|
|
(add-debug-line2d #t (bucket-id debug-no-zbuf1) (-> gp-0 0) (-> gp-0 1) s5-0)
|
|
(add-debug-line2d #t (bucket-id debug-no-zbuf1) (-> gp-0 1) (-> gp-0 2) s5-0)
|
|
(add-debug-line2d #t (bucket-id debug-no-zbuf1) (-> gp-0 2) (-> gp-0 3) s5-0)
|
|
(add-debug-line2d #t (bucket-id debug-no-zbuf1) (-> gp-0 3) (-> gp-0 0) s5-0)
|
|
)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defun print-game-text-scaled ((arg0 string) (arg1 float) (arg2 font-context) (arg3 bucket-id))
|
|
(let ((f26-0 (-> arg2 width))
|
|
(f30-0 (-> arg2 height))
|
|
(f24-0 (-> arg2 origin x))
|
|
(f22-0 (-> arg2 origin y))
|
|
(f28-0 (-> arg2 scale))
|
|
)
|
|
(let ((f0-1 (* (-> arg2 width) arg1))
|
|
(f1-2 (* (-> arg2 height) arg1))
|
|
)
|
|
(if (logtest? (-> arg2 flags) (font-flags middle))
|
|
(+! (-> arg2 origin x) (* 0.5 (- f26-0 f0-1)))
|
|
)
|
|
(if (logtest? (-> arg2 flags) (font-flags middle-vert))
|
|
(+! (-> arg2 origin y) (* 0.5 (- f30-0 f1-2)))
|
|
)
|
|
(set-scale! arg2 (* f28-0 arg1))
|
|
(set! (-> arg2 width) f0-1)
|
|
(set! (-> arg2 height) f1-2)
|
|
)
|
|
(print-game-text arg0 arg2 #f 44 (bucket-id hud-draw-hud-alpha))
|
|
(set! (-> arg2 origin x) f24-0)
|
|
(set! (-> arg2 origin y) f22-0)
|
|
(set! (-> arg2 width) f26-0)
|
|
(set! (-> arg2 height) f30-0)
|
|
(set! (-> arg2 scale) f28-0)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
|
|
;; display-text : text to print
|
|
;; font-ctx : the font to draw the text with
|
|
;; invisible : will actually print the text if true, otherwise will not print
|
|
;; arg3: height of text if text is supposed to be large
|
|
;; bucket-id: buffer used to draw?
|
|
;; Returns the height of the printed text.
|
|
(defun print-game-text ((display-text string) (font-ctx font-context) (invisible symbol) (large-font-size int) (bucket-id bucket-id))
|
|
(local-vars
|
|
(font-origin-x float) ;; Initial x and y position of font context
|
|
(font-origin-y float)
|
|
(font-flags font-flags)
|
|
(font-color font-color)
|
|
(cur-ch-ptr (pointer uint8)) ;; Char pointer used to traverse chars of display-text
|
|
(font-cur-position float)
|
|
(font-origin-x-copy float)
|
|
(right-side float) ;; Right boundary of where there is to draw
|
|
(bottom-side float) ;; Bottom boundary of where there is to draw
|
|
(whitespace-width float) ;; The width of a whitespace char using font-ctx
|
|
(line-height float) ;; The height of a line printed with font-ctx
|
|
(non-empty-lines int) ;; The number of lines printed so far
|
|
(cur-ch uint) ;; Current character inside display-text
|
|
(game-word-len int) ;;The current length of game-text-word
|
|
(game-line-len int) ;;The current length of game-text-line
|
|
(num-lines int)
|
|
(next-ch uint) ;;The next character inside display-text
|
|
(word-break symbol) ;; True if and only if game-text-word is complete and should be put in game-text-line
|
|
(num-lines-to-print int) ;;The number of outstanding lines that still need to be printed.
|
|
(game-text-word-width int)
|
|
)
|
|
(cond
|
|
((< 0.1 (-> font-ctx scale)) ;; Only print if font's scale is greater than 0.1
|
|
;;Storing font-ctx properties to restore them later.
|
|
(set! font-origin-x (-> font-ctx origin x))
|
|
(set! font-origin-y (-> font-ctx origin y))
|
|
(set! font-flags (-> font-ctx flags))
|
|
(set! font-color (-> font-ctx color))
|
|
(set-context! *font-work* font-ctx)
|
|
(set! (-> font-ctx max-x) (-> font-ctx origin x))
|
|
(when (logtest? (-> font-ctx flags) (font-flags middle-vert)) ;; If middle-vert flag is set,
|
|
(logclear! (-> font-ctx flags) (font-flags middle-vert)) ;; Clear the flag
|
|
(+! (-> font-ctx origin y) ;; font's y-origin += 0.5 * (font-height - height needed to print display-text)
|
|
(the float
|
|
(the int (* 0.5 (- (-> font-ctx height) (print-game-text display-text font-ctx #t 44 (bucket-id hud-draw-hud-alpha)))))
|
|
)
|
|
)
|
|
)
|
|
(set! cur-ch-ptr (-> display-text data))
|
|
(set! font-cur-position (-> font-ctx origin x))
|
|
(set! font-origin-x-copy (-> font-ctx origin x))
|
|
(set! right-side (+ (-> font-ctx origin x) (-> font-ctx width)))
|
|
(set! bottom-side (+ (-> font-ctx origin y) (-> font-ctx height)))
|
|
(set! whitespace-width (-> (get-string-length " " font-ctx) length))
|
|
|
|
;;line-height is set to font-ctx scale * (large-font-size if font-ctx has its large flat set or 28.0)
|
|
(set! line-height (* (-> font-ctx scale)
|
|
(if (logtest? (-> font-ctx flags) (font-flags large))
|
|
(the float large-font-size)
|
|
28.0
|
|
)
|
|
)
|
|
)
|
|
(set! non-empty-lines 0)
|
|
(if (logtest? (-> font-ctx flags) (font-flags middle))
|
|
(+! (-> font-ctx origin x) (/ (-> font-ctx width) 2))
|
|
)
|
|
(set! cur-ch (-> cur-ch-ptr 0))
|
|
(set! game-word-len 0)
|
|
(set! game-line-len 0)
|
|
(set! num-lines 0)
|
|
(set! next-ch (-> cur-ch-ptr 1)) ;;Following character in display-text
|
|
(set! word-break (the-as symbol #f)) ;;Set to false
|
|
(set! num-lines-to-print 0)
|
|
(set! game-text-word-width 0)
|
|
(set! (-> *game-text-line* data 0) (the-as uint 0)) ;;zero
|
|
;; While there are more characters to read from display-text (cur-ch is not \0) into game-text-word,
|
|
;; game-text-word hasn't been written to game-text-line or game-text-line hasn't been printed
|
|
;; and the font context's vertical position isn't below the bottom of the drawing context.
|
|
(while (and (not (and (zero? cur-ch) (zero? game-word-len) (zero? game-line-len))) (>= bottom-side (-> font-ctx origin y)))
|
|
(set! game-text-word-width 0)
|
|
;; (set! cur-ch-ptr (&-> cur-ch-ptr 1))
|
|
;; (set! next-ch (-> cur-ch-ptr 0))
|
|
;; (set! cur-ch-ptr (&-> cur-ch-ptr -1))
|
|
(set! next-ch (-> cur-ch-ptr 1))
|
|
(cond
|
|
;; 0 < current character < 4
|
|
((and (> cur-ch 0) (< cur-ch (the-as uint 4)))
|
|
;; Copy current and next character from display text into game-text-word
|
|
(set! (-> *game-text-word* data game-word-len) cur-ch)
|
|
(set! game-word-len (+ game-word-len 1))
|
|
(set! (-> *game-text-word* data game-word-len) next-ch)
|
|
(set! game-word-len (+ game-word-len 1))
|
|
(set! cur-ch-ptr (&-> cur-ch-ptr 1)) ;; Increment pointer within display-text
|
|
)
|
|
;; Current character is a space or forward slash, or it's a minus and previous was a tilde.
|
|
;; Might need to check that cur-ch-ptr - 1 is not out of bounds?
|
|
((or (= cur-ch #\\s) (= cur-ch #\/) (and (= cur-ch #\-) (!= (-> cur-ch-ptr -1) #\~)))
|
|
(set! (-> *game-text-word* data game-word-len) cur-ch) ;;Write the character into the word
|
|
(set! game-word-len (+ game-word-len 1))
|
|
(set! word-break #t) ;; Should copy current game-text-word into game-text-line
|
|
)
|
|
;; Current character is 0
|
|
((zero? cur-ch)
|
|
(if (nonzero? game-word-len) ;;If game-text-word not empty
|
|
(set! word-break #t) ;; Should copy current game-text-word into game-text-line
|
|
)
|
|
(set! num-lines-to-print (+ num-lines-to-print 1))
|
|
)
|
|
;; Both current character and next are backslashes
|
|
((and (= cur-ch #\\) (= next-ch #\\))
|
|
(set! cur-ch-ptr (&-> cur-ch-ptr 1)) ;; Increment pointer within display-text
|
|
(if (nonzero? game-word-len)
|
|
(set! word-break #t) ;; Should copy current game-text-word into game-text-line
|
|
)
|
|
(set! num-lines-to-print (+ num-lines-to-print 1))
|
|
)
|
|
;; Current character and next are underscores
|
|
((and (= cur-ch #\_) (= next-ch #\_))
|
|
(set! cur-ch-ptr (&-> cur-ch-ptr 1)) ;; Increment pointer within display-text
|
|
(set! (-> *game-text-word* data game-word-len) #\\s) ;;Write a space into the word
|
|
(set! game-word-len (+ game-word-len 1))
|
|
)
|
|
(else ;;Write character into word and increment word length
|
|
(set! (-> *game-text-word* data game-word-len) cur-ch)
|
|
(set! game-word-len (+ game-word-len 1))
|
|
)
|
|
)
|
|
(when word-break
|
|
(set! (-> *game-text-word* data game-word-len) (the-as uint 0)) ;;Null terminate word
|
|
(let ((word-start font-cur-position))
|
|
;;Set game-text-word-width to the length of game-text-word using font-ctx
|
|
(set! game-text-word-width (the int (-> (get-string-length *game-text-word* font-ctx) length)))
|
|
(let ((word-end (+ word-start (the float game-text-word-width))))
|
|
(if (= (-> *game-text-word* data (+ game-word-len -1)) #\\s) ;; If last character is a space
|
|
(set! word-end (- word-end whitespace-width))
|
|
)
|
|
(cond
|
|
((< right-side word-end) ;; If word would exceed right side of screen,
|
|
(set! (-> font-ctx max-x) (fmax (-> font-ctx max-x) font-cur-position))
|
|
(set! num-lines-to-print (+ num-lines-to-print 1))
|
|
)
|
|
(else
|
|
;;Append game-word to the end of game-line
|
|
(copy-charp<-charp (&-> *game-text-line* data game-line-len) (-> *game-text-word* data))
|
|
(set! game-line-len (+ game-line-len game-word-len))
|
|
(set! game-word-len 0)
|
|
(set! font-cur-position (+ font-cur-position (the float game-text-word-width))) ;; Add the word width to font-cur-position
|
|
(set! (-> font-ctx max-x) (fmax (-> font-ctx max-x) font-cur-position))
|
|
(set! word-break (the-as symbol #f))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
(while (> num-lines-to-print 0)
|
|
;; Store the position of the current line + line-height
|
|
(let ((next-line-origin-y (+ (-> font-ctx origin y) line-height)))
|
|
;;Note: for now it seems like font-ctx start-line is always 0.
|
|
(when (>= num-lines (the-as int (-> font-ctx start-line)))
|
|
;; If game-text-line ends in a space, replace the space with 0
|
|
;; (should probably decrement length too??)
|
|
(when (= (-> *game-text-line* data (+ game-line-len -1)) #\\s)
|
|
(set! (-> *game-text-line* data (+ game-line-len -1)) (the-as uint 0))
|
|
0
|
|
)
|
|
;;Actually print the text onscreen if the text is not meant to be invisible.
|
|
(when (not invisible)
|
|
(with-dma-buffer-add-bucket ((s2-1 (-> *display* frames (-> *display* on-screen) global-buf))
|
|
bucket-id
|
|
)
|
|
(draw-string *game-text-line* s2-1 font-ctx)
|
|
)
|
|
)
|
|
(if (nonzero? (-> *game-text-line* data 0))
|
|
(set! non-empty-lines (+ non-empty-lines 1)) ;; Increment non-empty lines "printed"
|
|
)
|
|
;; Update the font-context to be positioned after the previous line
|
|
(set! (-> font-ctx origin y) next-line-origin-y)
|
|
)
|
|
)
|
|
(set! num-lines (+ num-lines 1))
|
|
(set! (-> *game-text-line* data 0) (the-as uint 0))
|
|
(set! game-line-len 0)
|
|
(set! num-lines-to-print (+ num-lines-to-print -1))
|
|
(set! font-cur-position font-origin-x-copy)
|
|
(when word-break
|
|
;;Copy game-text-word to the end of game-text-line
|
|
(copy-charp<-charp (&-> *game-text-line* data game-line-len) (-> *game-text-word* data))
|
|
(set! game-line-len (+ game-line-len game-word-len))
|
|
(set! game-word-len 0)
|
|
(set! word-break (the-as symbol #f)) ;; Reset
|
|
(set! font-cur-position (+ font-cur-position (the float game-text-word-width))) ;; Add word width to current position
|
|
)
|
|
)
|
|
(when (nonzero? cur-ch)
|
|
(set! cur-ch-ptr (&-> cur-ch-ptr 1))
|
|
(set! cur-ch (-> cur-ch-ptr 0))
|
|
)
|
|
)
|
|
;; Restore font-ctx properties.
|
|
(set! (-> font-ctx origin x) font-origin-x)
|
|
(set! (-> font-ctx origin y) font-origin-y)
|
|
(set! (-> font-ctx flags) font-flags)
|
|
(set! (-> font-ctx color) font-color)
|
|
;; og:preserve-this
|
|
(#when PC_PORT
|
|
(if (and *debug-segment* *display-text-box*)
|
|
(draw-debug-text-box font-ctx)))
|
|
;;
|
|
(if (> non-empty-lines 0)
|
|
(* line-height (the float non-empty-lines))
|
|
0.0
|
|
)
|
|
)
|
|
(else
|
|
0.0
|
|
)
|
|
)
|
|
)
|
|
|
|
(defun disable-level-text-file-loading ()
|
|
(set! *level-text-file-load-flag* #f)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defun enable-level-text-file-loading ()
|
|
(set! *level-text-file-load-flag* #t)
|
|
0
|
|
(none)
|
|
)
|