jak-project/goal_src/jak1/pc/subtitle.gc

846 lines
28 KiB
Common Lisp
Raw Normal View History

;;-*-Lisp-*-
(in-package goal)
#|
Code for subtitles for the PC port. A PC actor pool is provided, and the subtitle process lives there.
It automatically detects the currently playing cutscene and plays the subtitles for it on channel 0.
The other two channels are for hints, first checked automatically by name, then by text ID.
There is a hack in ambient.gc to store the name of the last ambient hint vag played to aid in this.
Similarly to the generic text file, only one subtitles text file is loaded at once, stored in a specific
heap.
In Jak 2, the subtitles are stored directly within the .STR files. We don't have that luxury here, unfortunately.
|#
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; constants
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defconstant PC_SUBTITLE_FILE_SIZE (* 192 1024)) ;; 192K heap for subtitles. adjust later if necessary.
(defconstant PC_SUBTITLE_FILE_NAME "subtit")
(defglobalconstant PC_SUBTITLE_DEBUG #f)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; types and enums
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;------------------------
;; data
;;;------------------------
;; enum for the subtitle channels, no more than 2 bytes!
(defenum pc-subtitle-channel
:type int16
(invalid -1) (movie 0) (hint 1) (hint-named 2))
(defconstant SUBTITLE_CHANNEL_COUNT 3)
(defenum pc-subtitle-flags
:bitfield #t
:type uint32
(offscreen) ;; speaker is offscreen.
)
;; information about a single line of subtitles
(deftype subtitle-keyframe (structure)
(
(frame int32) ;; the frame to play the subtitle line on
(string string) ;; the text for the subtitle line
(speaker string) ;; name of the speaker. leave blank for no speaker.
(flags pc-subtitle-flags) ;; flags
)
:pack-me
)
;; an individual entry to a subtitle text making up a scene, comprised of a series of keyframes (frame+line of text)
(deftype subtitle-text (structure)
(
;; the channel to play the text on, useful for lookup since it can also be used to tell subtitle types apart
(kind pc-subtitle-channel)
;; the amount of keyframes
(length int16)
;; data
(keyframes (inline-array subtitle-keyframe))
;; now we store a way to identify and lookup the subtitles.
;; the name of the spool-anim
(name string :offset 8)
;; the game-text-id if this is for a hint
(id game-text-id :offset 12)
;; the 8-character name for an ambient or hint
(hash uint64 :offset 8)
)
:size-assert #x10 ;; compact!
)
;; the global subtitle text info bank
(deftype subtitle-text-info (basic)
((length int32)
(lang pc-subtitle-lang)
(dummy int32)
(data subtitle-text :inline :dynamic)
)
(:methods
(get-scene-by-name (_type_ pc-subtitle-channel string) subtitle-text)
(get-scene-by-text-id (_type_ pc-subtitle-channel game-text-id) subtitle-text)
)
)
(defmacro subtitle-flags? (sub &rest flags)
`(logtest? (-> ,sub flags) (pc-subtitle-flags ,@flags)))
;;;----------------------------------
;; process type
;;;----------------------------------
;; graphic parameters for subtitles
(deftype subtitle-bank (structure)
(
(scale float)
(width float)
(height float)
(lines float)
(notice-height float)
(hint-height float)
)
)
(define *SUBTITLE-bank*
(new 'static 'subtitle-bank
:scale 0.49
:width 0.87
:height 0.75
:lines 2.0
:notice-height 0.2
:hint-height 0.8
))
;; the subtitle process! it lives on the PC actor pool and awaits for incoming subtitle messages, or a movie
(deftype subtitle (process)
(
(font font-context) ;; the font to use for the subtitles.
(bank-backup subtitle-bank :inline) ;; debug backup.
(state-time time-frame) ;; a timestamp, used for notices
(notice-id game-text-id) ;; what notice text to display at the top of the screen
( spool-name string)
(old-spool-name string)
(text-id game-text-id)
(cur-channel pc-subtitle-channel)
(want-subtitle subtitle-keyframe) ;; the subtitle we want to display
(hint-subtitle? symbol)
)
(:methods
(subtitle-format (_type_ subtitle-keyframe) string)
)
(:states
subtitle-debug)
)
;;;----------------------------------------------
;; globals
;;;----------------------------------------------
;; the subtitle process.
(define *subtitle* (the (pointer subtitle) #f))
;; subtitle text data
(define *subtitle-text* (the subtitle-text-info #f))
(kheap-alloc (define *subtitle-text-heap* (new 'global 'kheap)) PC_SUBTITLE_FILE_SIZE)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; loading files
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defmethod get-scene-by-name subtitle-text-info ((obj subtitle-text-info) (kind pc-subtitle-channel) (name string))
"get a subtitle scene info with the corresponding name. #f = none found"
;; invalid kind so return invalid scene.
(if (or (not name) (= kind (pc-subtitle-channel invalid)))
(return (the subtitle-text #f)))
(dotimes (i (-> obj length))
;; name and kind matches, return that!
(when (and (= kind (-> obj data i kind)) (string= (-> obj data i name) name))
(return (-> obj data i))
)
)
(the subtitle-text #f))
(defmethod get-scene-by-text-id subtitle-text-info ((obj subtitle-text-info) (kind pc-subtitle-channel) (id game-text-id))
"get a subtitle scene info with the corresponding name. #f = none found"
;; invalid kind so return invalid scene.
(if (= kind (pc-subtitle-channel invalid))
(return (the subtitle-text #f)))
(dotimes (i (-> obj length))
;; name and kind matches, return that!
(when (and (= kind (-> obj data i kind)) (= (-> obj data i id) id))
(return (-> obj data i))
)
)
(the subtitle-text #f))
(defun load-subtitle-text-info ((txt-name string) (curr-text symbol) (heap kheap))
"load a subtitles text file onto a heap.
txt-name = language-agnostic file name
curr-text = a symbol to a subtitle-text-info to link the file to
heap = the text heap to load the file onto"
(let ((heap-sym-heap (the-as subtitle-text-info (-> curr-text value)))
(lang (-> *pc-settings* subtitle-language))
(load-status 0)
(heap-free (&- (-> heap top) (the-as uint (-> heap base)))))
;; current text has nothing loaded, or language doesn't match.
(when (or (= heap-sym-heap #f)
(!= (-> heap-sym-heap lang) lang)
)
;; so reload.
;; reset the text heap.
(kheap-reset heap)
;; try to load load...
(while (not (str-load (string-format "~D~S.TXT" lang txt-name) -1 (logand -64 (&+ (-> heap current) 63)) (&- (-> heap top) (-> heap current))))
(return 0)
)
;; load succeeded. check status.
(label retry)
(let ((status (str-load-status (the-as (pointer int32) (& load-status)))))
(when (= status 'error)
(format 0 "Error loading subtitle~%")
(return 0)
(goto loaded)
)
(cond
((>= load-status (+ heap-free -300))
(format 0 "Game subtitle heap overrun!~%")
(return 0)
)
((= status 'busy)
;; still loading.
(goto retry)
)
)
)
(label loaded)
;; link the text file!
(let ((new-mem (logand -64 (&+ (-> heap current) 63))))
(flush-cache 0)
(set! (-> curr-text value) (link new-mem (-> (string-format "~D~S.TXT" lang txt-name) data) load-status heap 0))
)
;; if linking failed just make the text invalid.
(if (<= (the-as int (-> curr-text value)) 0)
(set! (-> curr-text value) (the-as object #f))
)
))
0)
[game] pc port progress menu (#1281) * fix typo * more typo * shorten discord rpc text * allow expanding enums after the fact (untested) * make `game_text` work similar to subtitles * update progress decomp * update some types + `do-not-decompile` in bitfield * fixes and fall back to original progress code * update `progress` decomp with new enums * update config files * fix enums and debug menu * always allocate (but not use) a lot of particles * small rework to display mode options * revert resolution/aspect-ratio symbol mess * begin the override stuff * make `progress-draw` more readable * more fixes * codacy good boy points * first step overriding code * finish progress overrides, game options menu fully functional! * minor fixes * Update game.gp * Update sparticle-launcher.gc * clang * change camera controls text * oops * some cleanup * derp * nice job * implement menu scrolling lol * make scrollable menus less cramped, fix arrows * make some carousell things i guess * add msaa carousell to test * oops * Update progress-pc.gc * make `pc-get-screen-size` (untested) * resolution menu * input fixes * return when selecting resolution * scroll fixes * Update progress-pc.gc * add "fit to screen" button * bug * complete resolutions menu * aspect ratio menu * subtitles language * subtitle speaker * final adjustments * ref test * fix tests * fix ref! * reduce redundancy a bit * fix mem leaks? * save settings on progress exit * fix init reorder * remove unused code * rename goal project-like files to the project extension * sha display toggle * aspect ratio settings fixes * dont store text db's in compiler * properly save+load native aspect stuff
2022-04-11 18:38:54 -04:00
(defun load-level-subtitle-files ((idx int))
"Load the subtitle 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."
[game] pc port progress menu (#1281) * fix typo * more typo * shorten discord rpc text * allow expanding enums after the fact (untested) * make `game_text` work similar to subtitles * update progress decomp * update some types + `do-not-decompile` in bitfield * fixes and fall back to original progress code * update `progress` decomp with new enums * update config files * fix enums and debug menu * always allocate (but not use) a lot of particles * small rework to display mode options * revert resolution/aspect-ratio symbol mess * begin the override stuff * make `progress-draw` more readable * more fixes * codacy good boy points * first step overriding code * finish progress overrides, game options menu fully functional! * minor fixes * Update game.gp * Update sparticle-launcher.gc * clang * change camera controls text * oops * some cleanup * derp * nice job * implement menu scrolling lol * make scrollable menus less cramped, fix arrows * make some carousell things i guess * add msaa carousell to test * oops * Update progress-pc.gc * make `pc-get-screen-size` (untested) * resolution menu * input fixes * return when selecting resolution * scroll fixes * Update progress-pc.gc * add "fit to screen" button * bug * complete resolutions menu * aspect ratio menu * subtitles language * subtitle speaker * final adjustments * ref test * fix tests * fix ref! * reduce redundancy a bit * fix mem leaks? * save settings on progress exit * fix init reorder * remove unused code * rename goal project-like files to the project extension * sha display toggle * aspect ratio settings fixes * dont store text db's in compiler * properly save+load native aspect stuff
2022-04-11 18:38:54 -04:00
;; just load common.
[game] pc port progress menu (#1281) * fix typo * more typo * shorten discord rpc text * allow expanding enums after the fact (untested) * make `game_text` work similar to subtitles * update progress decomp * update some types + `do-not-decompile` in bitfield * fixes and fall back to original progress code * update `progress` decomp with new enums * update config files * fix enums and debug menu * always allocate (but not use) a lot of particles * small rework to display mode options * revert resolution/aspect-ratio symbol mess * begin the override stuff * make `progress-draw` more readable * more fixes * codacy good boy points * first step overriding code * finish progress overrides, game options menu fully functional! * minor fixes * Update game.gp * Update sparticle-launcher.gc * clang * change camera controls text * oops * some cleanup * derp * nice job * implement menu scrolling lol * make scrollable menus less cramped, fix arrows * make some carousell things i guess * add msaa carousell to test * oops * Update progress-pc.gc * make `pc-get-screen-size` (untested) * resolution menu * input fixes * return when selecting resolution * scroll fixes * Update progress-pc.gc * add "fit to screen" button * bug * complete resolutions menu * aspect ratio menu * subtitles language * subtitle speaker * final adjustments * ref test * fix tests * fix ref! * reduce redundancy a bit * fix mem leaks? * save settings on progress exit * fix init reorder * remove unused code * rename goal project-like files to the project extension * sha display toggle * aspect ratio settings fixes * dont store text db's in compiler * properly save+load native aspect stuff
2022-04-11 18:38:54 -04:00
(if (or *level-text-file-load-flag* (>= idx 0))
(load-subtitle-text-info PC_SUBTITLE_FILE_NAME '*subtitle-text* *subtitle-text-heap*)
)
(none))
(defmacro reload-subtitles ()
"rebuild and reload subtitles."
`(begin
(asm-text-file subtitle :files ("game/assets/game_subtitle.gp"))
(if *subtitle-text*
(+! (-> *subtitle-text* lang) (the-as pc-subtitle-lang 1)))))
[game] pc port progress menu (#1281) * fix typo * more typo * shorten discord rpc text * allow expanding enums after the fact (untested) * make `game_text` work similar to subtitles * update progress decomp * update some types + `do-not-decompile` in bitfield * fixes and fall back to original progress code * update `progress` decomp with new enums * update config files * fix enums and debug menu * always allocate (but not use) a lot of particles * small rework to display mode options * revert resolution/aspect-ratio symbol mess * begin the override stuff * make `progress-draw` more readable * more fixes * codacy good boy points * first step overriding code * finish progress overrides, game options menu fully functional! * minor fixes * Update game.gp * Update sparticle-launcher.gc * clang * change camera controls text * oops * some cleanup * derp * nice job * implement menu scrolling lol * make scrollable menus less cramped, fix arrows * make some carousell things i guess * add msaa carousell to test * oops * Update progress-pc.gc * make `pc-get-screen-size` (untested) * resolution menu * input fixes * return when selecting resolution * scroll fixes * Update progress-pc.gc * add "fit to screen" button * bug * complete resolutions menu * aspect ratio menu * subtitles language * subtitle speaker * final adjustments * ref test * fix tests * fix ref! * reduce redundancy a bit * fix mem leaks? * save settings on progress exit * fix init reorder * remove unused code * rename goal project-like files to the project extension * sha display toggle * aspect ratio settings fixes * dont store text db's in compiler * properly save+load native aspect stuff
2022-04-11 18:38:54 -04:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; subtitle process and drawing!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun-recursive print-game-subtitle float ((str string) (font-ctxt font-context) (opaque symbol) (alpha int) (line-height int))
"Print text. Not worth commenting until we get stack variables in lets, I think"
(local-vars
(sv-112 float)
(sv-116 float)
(sv-120 float)
(sv-124 float)
(sv-128 float)
(sv-132 float)
(sv-136 float)
(sv-140 (pointer uint8))
(sv-144 float)
(sv-148 float)
(sv-152 float)
(sv-156 float)
(sv-160 float)
(sv-164 float)
(sv-168 int)
(sv-176 int)
(sv-184 int)
(sv-192 int)
(sv-200 int)
(sv-208 symbol)
(sv-212 symbol)
)
(let ((gp-0 (new
'stack
'font-context
*font-default-matrix*
(the int (-> font-ctxt origin x))
(the int (-> font-ctxt origin y))
0.0
(font-color default)
(font-flags shadow kerning)
)
)
)
(when (< 0.1 (-> font-ctxt scale))
(set! sv-112 (-> font-ctxt mat vector 0 x))
(set! sv-116 (-> font-ctxt mat vector 1 y))
(set! sv-120 (-> *video-parms* relative-x-scale))
(set! sv-124 (-> *video-parms* relative-y-scale))
(set! sv-128 (-> *video-parms* relative-x-scale-reciprical))
(set! sv-132 (-> *video-parms* relative-y-scale-reciprical))
(set! sv-136 (-> font-ctxt scale))
(set! (-> gp-0 origin z) (-> font-ctxt origin z))
(set! (-> gp-0 flags) (-> font-ctxt flags))
(set! (-> gp-0 color) (-> font-ctxt color))
(set! (-> gp-0 scale) sv-136)
(when (logtest? (-> gp-0 flags) (font-flags left))
(logclear! (-> gp-0 flags) (font-flags left))
(let ((f30-0 (-> gp-0 width))
(f28-0 (-> gp-0 height))
)
(set! (-> gp-0 width) (-> font-ctxt width))
(set! (-> gp-0 height) (-> font-ctxt height))
(+! (-> gp-0 origin y)
(the float (the int (* 0.5 (- (-> gp-0 height) (print-game-subtitle str gp-0 #t 128 22)))))
)
(set! (-> gp-0 width) f30-0)
(set! (-> gp-0 height) f28-0)
)
)
(set! (-> gp-0 mat vector 0 x) (* (-> gp-0 mat vector 0 x) sv-136))
(set! (-> gp-0 mat vector 1 y) (* (-> gp-0 mat vector 1 y) sv-136))
(set! (-> *video-parms* relative-x-scale) (* (-> *video-parms* relative-x-scale) sv-136))
(set! (-> *video-parms* relative-y-scale) (* (-> *video-parms* relative-y-scale) sv-136))
(set! (-> *video-parms* relative-x-scale-reciprical) (/ 1.0 (-> *video-parms* relative-x-scale)))
(set! (-> *video-parms* relative-y-scale-reciprical) (/ 1.0 sv-136))
(set! sv-140 (-> str data))
(set! sv-144 (-> gp-0 origin x))
(set! sv-148 (-> gp-0 origin x))
(set! sv-152 (+ (-> gp-0 origin x) (-> font-ctxt width)))
(set! sv-156 (+ (-> gp-0 origin y) (-> font-ctxt height)))
(set! sv-160 (* (get-string-length " " gp-0) (-> *video-parms* relative-x-scale)))
(set! sv-164 (* (if (logtest? (-> gp-0 flags) (font-flags large))
(the float line-height)
14.0
)
sv-136
)
)
(set! sv-168 0)
(if (logtest? (-> gp-0 flags) (font-flags middle))
(+! (-> gp-0 origin x) (* 0.5 (-> font-ctxt width)))
)
(set! sv-176 (the-as int (-> sv-140 0)))
(set! sv-184 0)
(set! sv-192 0)
(set! sv-200 0)
(set! sv-208 (the-as symbol #f))
(set! sv-212 (the-as symbol #f))
(set! (-> *game-text-line* data 0) (the-as uint 0))
(while (or (not (and (zero? sv-176) (zero? sv-184) (zero? sv-192))) (>= sv-156 (-> gp-0 origin y)))
(cond
((= sv-176 32)
(set! (-> *game-text-word* data sv-184) (the-as uint sv-176))
(set! sv-184 (+ sv-184 1))
(set! sv-208 #t)
)
((zero? sv-176)
(if (zero? sv-184)
(set! sv-212 #t)
(set! sv-208 #t)
)
)
(else
(if (= sv-176 95)
(set! sv-176 32)
)
(set! (-> *game-text-word* data sv-184) (the-as uint sv-176))
(set! sv-184 (+ sv-184 1))
)
)
(when (= sv-208 #t)
(set! (-> *game-text-word* data sv-184) (the-as uint 0))
(let* ((f30-1 sv-144)
(f0-49 (* (get-string-length *game-text-word* gp-0) (-> *video-parms* relative-x-scale)))
(f1-14 (+ f30-1 f0-49))
)
(if (= (-> *game-text-word* data (+ sv-184 -1)) 32)
(set! f1-14 (- f1-14 sv-160))
)
(cond
((< sv-152 f1-14)
(set! sv-144 (+ sv-148 f0-49))
(set! sv-212 #t)
)
(else
(set! sv-144 (+ sv-144 f0-49))
)
)
)
)
(when (= sv-212 #t)
(when (>= sv-200 (the-as int (-> gp-0 start-line)))
(let ((f30-2 (+ (-> gp-0 origin y) sv-164)))
(when (>= sv-156 f30-2)
(when (= (-> *game-text-line* data (+ sv-192 -1)) 32)
(set! (-> *game-text-line* data (+ sv-192 -1)) (the-as uint 0))
(when (and (= (-> *game-text-line* data (+ sv-192 -5)) 126) (= (-> *game-text-line* data (+ sv-192 -2)) 72))
(set! (-> *game-text-line* data (+ sv-192 -5)) (the-as uint 0))
0
)
)
)
(when (and (= (-> *game-text-line* data (+ sv-192 -4)) 126) (= (-> *game-text-line* data (+ sv-192 -1)) 72))
(set! (-> *game-text-line* data (+ sv-192 -4)) (the-as uint 0))
0
)
(if (nonzero? (-> *game-text-line* data 0))
(set! sv-168 (+ sv-168 1))
)
(when (not opaque)
(let* ((s1-1 (-> *display* frames (-> *display* on-screen) frame global-buf))
(s2-1 (-> s1-1 base))
)
(set-font-color-alpha (-> font-ctxt color) alpha)
(draw-string *game-text-line* s1-1 gp-0)
(set-font-color-alpha (-> font-ctxt color) 128)
(set! (-> gp-0 color) (-> *font-work* last-color))
(let ((a3-3 (-> s1-1 base)))
(let ((v1-127 (the-as object (-> s1-1 base))))
(set! (-> (the-as dma-packet v1-127) dma) (new 'static 'dma-tag :id (dma-tag-id next)))
(set! (-> (the-as dma-packet v1-127) vif0) (new 'static 'vif-tag))
(set! (-> (the-as dma-packet v1-127) vif1) (new 'static 'vif-tag))
(set! (-> s1-1 base) (&+ (the-as pointer v1-127) 16))
)
(dma-bucket-insert-tag
(-> *display* frames (-> *display* on-screen) frame bucket-group)
(bucket-id subtitle)
s2-1
(the-as (pointer dma-tag) a3-3)
)
)
)
)
(set! (-> gp-0 origin y) f30-2)
)
)
(set! sv-200 (+ sv-200 1))
(set! (-> *game-text-line* data 0) (the-as uint 0))
(set! sv-192 0)
(set! sv-212 (the-as symbol #f))
)
(when (= sv-208 #t)
(copy-charp<-charp (&-> *game-text-line* data sv-192) (-> *game-text-word* data))
(set! sv-192 (+ sv-192 sv-184))
(set! sv-184 0)
(set! sv-208 (the-as symbol #f))
)
(when (nonzero? sv-176)
(set! sv-140 (&-> sv-140 1))
(set! sv-176 (the-as int (-> sv-140 0)))
)
)
(set! (-> gp-0 mat vector 0 x) sv-112)
(set! (-> gp-0 mat vector 1 y) sv-116)
(set! (-> *video-parms* relative-x-scale) sv-120)
(set! (-> *video-parms* relative-y-scale) sv-124)
(set! (-> *video-parms* relative-x-scale-reciprical) sv-128)
(set! (-> *video-parms* relative-y-scale-reciprical) sv-132)
(if (> sv-168 0)
(* sv-164 (the float sv-168))
0.0
)
)
)
)
(defmethod subtitle-format subtitle ((obj subtitle) (keyframe subtitle-keyframe))
"check settings and format subtitle accordingly."
(cond
((= 0 (length (-> keyframe speaker)))
;; there's no speaker so who cares.
(string-format "~S" (-> keyframe string))
)
((or (= #t (-> *pc-settings* subtitle-speaker?))
(and (= 'auto (-> *pc-settings* subtitle-speaker?)) (subtitle-flags? keyframe offscreen)))
;; there is a speaker and we do want it.
(string-format "~3L~S:~0L ~S" (-> keyframe speaker) (-> keyframe string))
)
(else
(string-format "~S" (-> keyframe string))
)
)
)
(defun subtitle? ((hinttitles? symbol))
"can a subtitle be displayed right now?"
(and (or (and (not hinttitles?) (-> *pc-settings* subtitles?)) ;; subtitles enabled
(and hinttitles? (-> *pc-settings* hinttitles?)))
(or *debug-segment* (= *master-mode* 'game)) ;; current mode is game, OR we are just debugging
(not *progress-process*) ;; no progress open
)
)
(defun subtitle-str-adjust ((pos int))
(if (< pos 0) -1 (the int (/ pos (/ 1024.0 60)))))
(defstate subtitle-process (subtitle)
:event (behavior ((from process) (argc int) (msg symbol) (block event-message-block))
(case msg
(('subtitle-start)
0
)
(('debug)
(go subtitle-debug)
)
)
)
:code (behavior ()
(loop
(suspend))
)
:trans (behavior ()
[game] pc port progress menu (#1281) * fix typo * more typo * shorten discord rpc text * allow expanding enums after the fact (untested) * make `game_text` work similar to subtitles * update progress decomp * update some types + `do-not-decompile` in bitfield * fixes and fall back to original progress code * update `progress` decomp with new enums * update config files * fix enums and debug menu * always allocate (but not use) a lot of particles * small rework to display mode options * revert resolution/aspect-ratio symbol mess * begin the override stuff * make `progress-draw` more readable * more fixes * codacy good boy points * first step overriding code * finish progress overrides, game options menu fully functional! * minor fixes * Update game.gp * Update sparticle-launcher.gc * clang * change camera controls text * oops * some cleanup * derp * nice job * implement menu scrolling lol * make scrollable menus less cramped, fix arrows * make some carousell things i guess * add msaa carousell to test * oops * Update progress-pc.gc * make `pc-get-screen-size` (untested) * resolution menu * input fixes * return when selecting resolution * scroll fixes * Update progress-pc.gc * add "fit to screen" button * bug * complete resolutions menu * aspect ratio menu * subtitles language * subtitle speaker * final adjustments * ref test * fix tests * fix ref! * reduce redundancy a bit * fix mem leaks? * save settings on progress exit * fix init reorder * remove unused code * rename goal project-like files to the project extension * sha display toggle * aspect ratio settings fixes * dont store text db's in compiler * properly save+load native aspect stuff
2022-04-11 18:38:54 -04:00
(load-level-subtitle-files 0)
;; reset params
(set! (-> self want-subtitle) (the subtitle-keyframe #f))
(set! (-> self hint-subtitle?) #f)
(set! (-> self spool-name) #f)
(set! (-> self cur-channel) (pc-subtitle-channel invalid))
;; check what kind of subtitles are running
(cond
((and (movie?) (-> *art-control* spool-lock) (-> *art-control* active-stream))
;; there's a cutscene happening and an active spool with a valid owner.
(set! (-> self spool-name) (-> *art-control* active-stream))
(set! (-> self cur-channel) (pc-subtitle-channel movie))
(with-proc ((handle->process (-> *art-control* spool-lock)))
2022-04-30 14:55:13 -04:00
(if *debug-segment*
(format *stdcon* "movie spool detected:~%~3L~A~0L~%current spool frame is ~3L~D~0L~%"
(-> *art-control* active-stream) (the int (ja-aframe-num 0)))
)
)
)
(*hint-semaphore*
;; there's a hint playing
(set! (-> self spool-name) (-> *hint-semaphore* 0 sound-to-play))
(unless (-> self spool-name)
(set! (-> self spool-name) *level-hint-spool-name*))
(set! (-> self text-id) (-> *hint-semaphore* 0 text-id-to-display))
(set! (-> self cur-channel) (if (-> self spool-name)
(pc-subtitle-channel hint-named)
(pc-subtitle-channel hint)))
2022-04-30 14:55:13 -04:00
(if *debug-segment*
(format *stdcon* "hint detected!~%~3L~A~0L/~3L#x~X~0L~%current str pos is ~D (~3L~D~0L)~%"
(-> self spool-name) (-> self text-id)
(current-str-pos (-> *hint-semaphore* 0 sound-id))
(subtitle-str-adjust (current-str-pos (-> *hint-semaphore* 0 sound-id))))
)
)
)
;; do subtitles
;; get a subtitle info that matches our current status
(let ((keyframe (the subtitle-keyframe #f)))
(when *subtitle-text*
(case (-> self cur-channel)
(((pc-subtitle-channel movie))
;; cutscenes. get our cutscene.
(set! (-> self hint-subtitle?) #f)
(awhen (get-scene-by-name *subtitle-text* (-> self cur-channel) (-> self spool-name))
;; find out position in the scene.
(let ((pos 0))
;; get frame num
(with-proc ((handle->process (-> *art-control* spool-lock)))
(set! pos (the int (ja-aframe-num 0)))
)
;; find closest keyframe
(dotimes (i (-> it length))
(when (>= pos (-> it keyframes i frame))
(set! keyframe (-> it keyframes i)))
)
)
)
)
(((pc-subtitle-channel hint) (pc-subtitle-channel hint-named))
;; hint! find it. or else.
(set! (-> self hint-subtitle?) #t)
(awhen (if (= (-> self cur-channel) (pc-subtitle-channel hint-named))
(get-scene-by-name *subtitle-text* (-> self cur-channel) (-> self spool-name))
(get-scene-by-text-id *subtitle-text* (-> self cur-channel) (-> self text-id))
)
(let ((pos (subtitle-str-adjust (current-str-pos (-> *hint-semaphore* 0 sound-id)))))
;; find closest keyframe
(dotimes (i (-> it length))
(when (>= pos (-> it keyframes i frame))
(set! keyframe (-> it keyframes i)))
)
)
)
)
))
;; save whatever subtitle we got.
(set! (-> self want-subtitle) keyframe))
(when (and (!= (-> self old-spool-name) (-> self spool-name))
(string= (-> self spool-name) "sage-intro-sequence-a"))
(set-state-time)
(set! (-> self notice-id) (game-text-id subtitle-hint))
)
;; keep this for later
(set! (-> self old-spool-name) (-> self spool-name))
;; during a cutscene, check if user toggled subtitles
(when (and (= (pc-subtitle-channel movie) (-> self cur-channel))
(= 'game *master-mode*)
(cpad-pressed? 0 square))
(not! (-> *pc-settings* subtitles?))
(set-state-time)
(if (-> *pc-settings* subtitles?)
(set! (-> self notice-id) (game-text-id subtitle-enabled))
(set! (-> self notice-id) (game-text-id subtitle-disabled))
)
)
(when *debug-segment*
(when (and (cpad-hold? 0 l3) (cpad-pressed? 0 start))
(cpad-clear! 0 start)
(send-event self 'debug)
)
)
(none))
:post (behavior ()
;; set font settings.
(set! (-> self font origin x) (* (- 1.0 (-> *SUBTITLE-bank* width)) 256))
(set! (-> self font origin y) (* (if (-> self hint-subtitle?)
(-> *SUBTITLE-bank* hint-height)
(-> *SUBTITLE-bank* height)
) 224))
(set-width! (-> self font) (the int (* (-> *SUBTITLE-bank* width) 512)))
(set-height! (-> self font) (the int (* (-> *SUBTITLE-bank* lines) 11)))
(set-scale! (-> self font) (-> *SUBTITLE-bank* scale))
(when (and (-> self want-subtitle) (subtitle? (-> self hint-subtitle?)))
;; we got a valid subtitle! render it.
(hide-bottom-hud)
(print-game-subtitle (subtitle-format self (-> self want-subtitle)) (-> self font) #f 128 22)
(#when PC_SUBTITLE_DEBUG
(draw-debug-text-box (-> self font))
)
)
(cond
((!= *master-mode* 'game)
)
((and (< (time-passed) (seconds 5))
(= (-> self notice-id) (game-text-id subtitle-hint)))
(when (not (-> *pc-settings* subtitles?))
(set-scale! (-> self font) (* (-> *SUBTITLE-bank* scale) 1.5))
(print-game-subtitle (lookup-text! *common-text* (-> self notice-id) #f) (-> self font) #f 128 22)
)
)
((and (= (-> self cur-channel) (pc-subtitle-channel movie))
(< (time-passed) (seconds 2))
(< (mod (time-passed) (seconds 1)) (seconds 0.8)))
(set! (-> self font origin y) (* (-> *SUBTITLE-bank* notice-height) 224))
(print-game-subtitle (lookup-text! *common-text* (-> self notice-id) #f) (-> self font) #f 128 22)
)
)
0)
)
(defstate subtitle-debug (subtitle)
:event (behavior ((from process) (argc int) (msg symbol) (block event-message-block))
(case msg
(('debug)
(go subtitle-process)
)
)
)
:enter (behavior ()
(mem-copy! (the pointer (-> self bank-backup)) (the pointer *SUBTITLE-bank*) (size-of subtitle-bank))
(set-master-mode 'pause)
)
:exit (behavior ()
(toggle-pause) (none)) ;; todo fuck
:trans (behavior ()
(with-dma-buffer-add-bucket ((buf (-> (current-frame) debug-buf))
(bucket-id debug))
(draw-string-xy "~3LSUBTITLE DEBUG!~0L" buf 16 40 (font-color default) (font-flags shadow kerning))
(draw-string-xy "Square: reset" buf 16 48 (font-color default) (font-flags shadow kerning))
(draw-string-xy "Up/down: Move vertically" buf 16 56 (font-color default) (font-flags shadow kerning))
(draw-string-xy "Triangle+R1/L1: width" buf 16 64 (font-color default) (font-flags shadow kerning))
(draw-string-xy "Triangle+R2/L2: height" buf 16 72 (font-color default) (font-flags shadow kerning))
(draw-string-xy "Circle+R1/L1: scale" buf 16 80 (font-color default) (font-flags shadow kerning))
(draw-string-xy "L3+Start: exit" buf 16 88 (font-color default) (font-flags shadow kerning))
)
(when (= 'pause *master-mode*)
(when (cpad-pressed? 0 square)
(mem-copy! (the pointer *SUBTITLE-bank*) (the pointer (-> self bank-backup)) (size-of subtitle-bank))
)
(when (cpad-hold? 0 up) (+! (-> *SUBTITLE-bank* height) -0.01))
(when (cpad-hold? 0 down) (+! (-> *SUBTITLE-bank* height) 0.01))
(cond
((cpad-hold? 0 triangle)
(when (cpad-hold? 0 r1) (-! (-> *SUBTITLE-bank* width) 0.01))
(when (cpad-hold? 0 l1) (+! (-> *SUBTITLE-bank* width) 0.01))
(when (cpad-hold? 0 r2) (-! (-> *SUBTITLE-bank* lines) 0.05))
(when (cpad-hold? 0 l2) (+! (-> *SUBTITLE-bank* lines) 0.05))
)
((cpad-hold? 0 circle)
(when (cpad-hold? 0 r1) (+! (-> *SUBTITLE-bank* scale) 0.01))
(when (cpad-hold? 0 l1) (-! (-> *SUBTITLE-bank* scale) 0.01))
)
)
)
(when (and (cpad-hold? 0 l3) (cpad-pressed? 0 start))
(cpad-clear! 0 start)
(send-event self 'debug)
)
(none))
:code (-> subtitle-process code)
:post (-> subtitle-process post)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; helper functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defmethod length subtitle-text-info ((obj subtitle-text-info))
"Get the length (number of subtitle scenes) in a subtitle-text-info."
(-> obj length)
)
(defmethod length subtitle-text ((obj subtitle-text))
"Get the length (number of subtitle lines) in a subtitle-text."
(-> obj length)
)
(defbehavior subtitle-init-by-other subtitle ()
"external initializer for subtitle process"
(set! (-> self font) (new 'process 'font-context *font-default-matrix*
0 0 0.0 (font-color default) (font-flags shadow kerning middle large)))
(go subtitle-process)
)
(defun subtitle-stop ()
"kill the subtitle process"
(kill-by-type subtitle *display-pool*)
(set! *subtitle* (the (pointer subtitle) #f)))
(defun subtitle-start ()
"start the subtitle process"
(when *subtitle*
(subtitle-stop)
)
(set! *subtitle* (process-spawn subtitle :from *pc-dead-pool* :to *display-pool*))
)
;; start the subtitle process when this file loads.
(subtitle-start)