mirror of
https://github.com/open-goal/jak-project
synced 2026-08-16 21:28:00 -04:00
80a002f8c0
* make birthing work * fix float representation on defskelgroup * test * update * debugger improvements & dont upload aux sprites * ? * fix progress * fixes * fixes * Create bea.gd * fix test * fix xmm reg clobbering in kernel (water) * cleanup cam-start * clear gamepad state every frame * allow controller connects and disconnects while running
1086 lines
29 KiB
Common Lisp
1086 lines
29 KiB
Common Lisp
;;-*-Lisp-*-
|
|
(in-package goal)
|
|
|
|
;; name: gsound.gc
|
|
;; name in dgo: gsound
|
|
;; dgos: GAME, ENGINE
|
|
|
|
;; use this constant to enable/disable the sound functions. debug purposes.
|
|
(defglobalconstant PC_DEBUG_SOUND_ENABLE #f)
|
|
|
|
;; The sound playback stuff is all on the IOP so we use IOP RPCs to control it.
|
|
;; Ther is a "player" that plays sound effects, and a "loader" that takes care of loading banks.
|
|
(define *sound-player-rpc* (new 'global 'rpc-buffer-pair (the uint (size-of sound-rpc-union)) (the-as uint 128) RPC-SOUND-PLAYER))
|
|
(define *sound-loader-rpc* (new 'global 'rpc-buffer-pair (the uint (size-of sound-rpc-union)) (the-as uint 1) RPC-SOUND-LOADER))
|
|
|
|
(defun sound-name= ((arg0 sound-name) (arg1 sound-name))
|
|
"Return #t if both are the same name"
|
|
(declare (inline))
|
|
|
|
(and (= (-> arg0 lo) (-> arg1 lo))
|
|
(= (-> arg0 hi) (-> arg1 hi)))
|
|
)
|
|
|
|
(deftype sound-iop-info (basic)
|
|
((frame uint32 :offset 16)
|
|
(strpos int32 :offset-assert 20)
|
|
(str-id sound-id :offset-assert 24)
|
|
(str-id-sign int32 :offset 24)
|
|
(freemem uint32 :offset-assert 28)
|
|
(chinfo uint8 48 :offset-assert 32)
|
|
(freemem2 uint32 :offset-assert 80)
|
|
(nocd uint32 :offset-assert 84)
|
|
(dirtycd uint32 :offset-assert 88)
|
|
(diskspeed uint32 2 :offset-assert 92)
|
|
(lastspeed uint32 :offset-assert 100)
|
|
(dupseg int32 :offset-assert 104)
|
|
(times uint32 41 :offset-assert 108)
|
|
(times-seq uint32 :offset-assert 272)
|
|
)
|
|
:method-count-assert 9
|
|
:size-assert #x114
|
|
:flag-assert #x900000114
|
|
)
|
|
|
|
(define *sound-iop-info* (new 'global 'sound-iop-info))
|
|
|
|
(defun str-is-playing? ()
|
|
"Return #t if an audio stream is playing"
|
|
|
|
(!= (-> *sound-iop-info* strpos) -1)
|
|
)
|
|
|
|
(defun current-str-id ()
|
|
"Return id of the current stream"
|
|
|
|
(the-as sound-id (-> *sound-iop-info* str-id-sign))
|
|
)
|
|
|
|
(defun current-str-pos ((str sound-id))
|
|
"Return position of the current stream. Return -1 if specified stream is not current"
|
|
|
|
(let ((ret -1))
|
|
|
|
(if (= str (-> *sound-iop-info* str-id))
|
|
(set! ret (-> *sound-iop-info* strpos))
|
|
)
|
|
|
|
ret
|
|
)
|
|
)
|
|
|
|
(defun is-cd-in? ()
|
|
|
|
(declare (inline))
|
|
(zero? (-> *sound-iop-info* nocd))
|
|
)
|
|
|
|
(defmacro is-cd-good? ()
|
|
`(zero? (-> *sound-iop-info* dirtycd))
|
|
)
|
|
|
|
(defun new-sound-id ()
|
|
(set! *current-sound-id* (the sound-id (1+ (the uint *current-sound-id*))))
|
|
(if (< (the-as int *current-sound-id*) #x10000)
|
|
(set! *current-sound-id* (the-as sound-id #x10000))
|
|
)
|
|
*current-sound-id*
|
|
)
|
|
|
|
(defun check-irx-version ()
|
|
(let ((cmd (the sound-rpc-get-irx-version (add-element *sound-loader-rpc*))))
|
|
(set! (-> cmd command) (sound-command get-irx-version))
|
|
(set! (-> cmd ee-addr) (&-> *sound-iop-info* frame))
|
|
(call *sound-loader-rpc* (the-as uint 0) (the-as pointer cmd) (the uint (size-of sound-rpc-union)))
|
|
(sync *sound-loader-rpc* #f)
|
|
|
|
(format 0 "IRX version ~D.~D~%" (-> cmd major) (-> cmd minor))
|
|
(when (or (!= (-> cmd major) 2) (nonzero? (-> cmd minor)))
|
|
(format 0 "ERROR: IRX is the wrong version - need ~D.~D~%" 2 0)
|
|
(format 0 "~%~%Please do (:mch) then mkee on linux-dog~%~%~%")
|
|
(crash!)
|
|
0
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
;; Note: we check the IRX version on load to make sure that the OVERLORD driver is the right version
|
|
;; and has loaded successfully.
|
|
(check-irx-version)
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; sound loading
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(defun sound-bank-load ((name sound-name))
|
|
(let ((id (new-sound-id)))
|
|
(let ((cmd (the sound-rpc-load-bank (add-element *sound-loader-rpc*))))
|
|
(set! (-> cmd command) (sound-command load-bank))
|
|
(set! (-> cmd bank-name) name)
|
|
)
|
|
(call *sound-loader-rpc* (the-as uint 0) (the-as pointer 0) (the-as uint 0))
|
|
id
|
|
)
|
|
)
|
|
|
|
(defun sound-bank-unload ((name sound-name))
|
|
(let ((cmd (the sound-rpc-unload-bank (add-element *sound-loader-rpc*))))
|
|
(set! (-> cmd command) (sound-command unload-bank))
|
|
(set! (-> cmd bank-name) name)
|
|
)
|
|
(call *sound-loader-rpc* (the-as uint 0) (the-as pointer 0) (the-as uint 0))
|
|
0
|
|
)
|
|
|
|
(defun sound-music-load ((name sound-name))
|
|
(let ((cmd (the sound-rpc-load-music (add-element *sound-loader-rpc*))))
|
|
(set! (-> cmd command) (sound-command load-music))
|
|
(set! (-> cmd bank-name) name)
|
|
)
|
|
(call *sound-loader-rpc* (the-as uint 0) (the-as pointer 0) (the-as uint 0))
|
|
0
|
|
)
|
|
|
|
(defun sound-music-unload ()
|
|
(let ((cmd (the sound-rpc-unload-music (add-element *sound-loader-rpc*))))
|
|
(set! (-> cmd command) (sound-command unload-music))
|
|
)
|
|
(call *sound-loader-rpc* (the-as uint 0) (the-as pointer 0) (the-as uint 0))
|
|
0
|
|
)
|
|
|
|
(sound-bank-load (static-sound-name "common"))
|
|
(sound-bank-load (static-sound-name "empty1"))
|
|
(sound-bank-load (static-sound-name "empty2"))
|
|
|
|
(define *sound-bank-1* 'empty1)
|
|
(define *sound-bank-2* 'empty2)
|
|
|
|
(defun sound-reload-info ()
|
|
(let ((cmd (the sound-rpc-reload-info (add-element *sound-loader-rpc*))))
|
|
(set! (-> cmd command) (sound-command reload-info))
|
|
)
|
|
(call *sound-loader-rpc* (the-as uint 0) (the-as pointer 0) (the-as uint 0))
|
|
0
|
|
)
|
|
|
|
(defun set-language ((lang language-enum))
|
|
(kset-language lang)
|
|
(let ((cmd (the sound-rpc-set-language (add-element *sound-loader-rpc*))))
|
|
(set! (-> cmd command) (sound-command set-language))
|
|
(set! (-> cmd lang) (the-as uint lang))
|
|
)
|
|
(call *sound-loader-rpc* (the-as uint 0) (the-as pointer 0) (the-as uint 0))
|
|
0
|
|
)
|
|
|
|
(defun list-sounds ()
|
|
(let ((cmd (the sound-rpc-list-sounds (add-element *sound-loader-rpc*))))
|
|
(set! (-> cmd command) (sound-command list-sounds))
|
|
)
|
|
(call *sound-loader-rpc* (the-as uint 0) (the-as pointer 0) (the-as uint 0))
|
|
0
|
|
)
|
|
|
|
(defun-debug sound-command->string ((cmd sound-command))
|
|
(enum->string sound-command cmd)
|
|
)
|
|
|
|
(defun sound-buffer-dump ()
|
|
(let ((elt-used (-> *sound-player-rpc* current elt-used))
|
|
(elt-size (-> *sound-player-rpc* current elt-size)))
|
|
(dotimes (i (the-as int elt-used))
|
|
(let* ((cmd (the sound-rpc-play (&+ (-> *sound-player-rpc* current base) (* elt-size (the-as uint i)))))
|
|
(a3-0 (sound-command->string (-> cmd command)))
|
|
(command (-> cmd command))
|
|
)
|
|
(if (= command (sound-command play))
|
|
(format #t "~D ~A ~G~%" i a3-0 (-> cmd name))
|
|
(format #t "~D ~A~%" i a3-0)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; sound playback
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(define *sound-player-enable* #t)
|
|
|
|
(defun swap-sound-buffers ((arg0 vector) (arg1 vector) (arg2 float))
|
|
(cond
|
|
((check-busy *sound-player-rpc*)
|
|
(set! *sound-player-enable* #f)
|
|
)
|
|
(else
|
|
(let ((a0-2 (-> *sound-player-rpc* current)))
|
|
(if (< (-> a0-2 elt-used) (-> a0-2 elt-count))
|
|
(sound-set-ear-trans arg0 arg1 arg2)
|
|
)
|
|
)
|
|
(call *sound-player-rpc* (the-as uint 0) (the-as pointer 0) (the-as uint 0))
|
|
(set! *sound-player-enable* #t)
|
|
)
|
|
)
|
|
(cond
|
|
((not (is-cd-in?))
|
|
(if (or (not *progress-process*)
|
|
(!= (-> *progress-process* 0 display-state) (progress-screen no-disc)))
|
|
|
|
(activate-progress *dproc* (progress-screen no-disc))
|
|
)
|
|
)
|
|
|
|
((not (is-cd-good?))
|
|
(if (or (not *progress-process*)
|
|
(!= (-> *progress-process* 0 display-state) (progress-screen bad-disc)))
|
|
|
|
(activate-progress *dproc* (progress-screen bad-disc))
|
|
)
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun get-sound-buffer-entry ()
|
|
(add-element *sound-player-rpc*)
|
|
)
|
|
|
|
(defun free-last-sound-buffer-entry ()
|
|
(decrement-elt-used *sound-player-rpc*)
|
|
0
|
|
)
|
|
|
|
(defun sound-basic-cb ((arg0 int) (arg1 (pointer int32)))
|
|
"This function is unused."
|
|
(set! (-> arg1 0) arg0)
|
|
(none)
|
|
)
|
|
|
|
(defun sound-trans-convert ((dest vector3w) (src vector))
|
|
(let ((vec (if src src (ear-trans))))
|
|
(set! (-> dest x) (the int (* (1/ 16) (-> vec x))))
|
|
(set! (-> dest y) (the int (* (1/ 16) (-> vec y))))
|
|
(set! (-> dest z) (the int (* (1/ 16) (-> vec z))))
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun sound-angle-convert ((deg float))
|
|
(let ((ret (the int (* (/ 360.0 65536.0) (the float (sar (shl (the int deg) 48) 48))))))
|
|
(if (< ret 0)
|
|
(+! ret 360)
|
|
)
|
|
(if (< 359 ret)
|
|
(+! ret -360)
|
|
)
|
|
ret
|
|
)
|
|
)
|
|
|
|
(defun string->sound-name ((str string))
|
|
(let ((snd-name (new 'stack-no-clear 'qword)))
|
|
(set! (-> snd-name quad) (the-as uint128 0))
|
|
(let ((out-ptr (the-as (pointer uint8) snd-name))
|
|
(in-ptr (-> str data))
|
|
)
|
|
(while (and (nonzero? (-> in-ptr 0))
|
|
(< (&- in-ptr (the-as uint (-> str data))) 15)
|
|
)
|
|
(set! (-> out-ptr 0) (-> in-ptr 0))
|
|
(set! out-ptr (&-> out-ptr 1))
|
|
(set! in-ptr (&-> in-ptr 1))
|
|
)
|
|
)
|
|
(the-as sound-name (-> snd-name quad))
|
|
)
|
|
)
|
|
|
|
(defun sound-set-volume ((group uint) (volume float))
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(let ((cmd (the sound-rpc-set-master-volume (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command set-master-volume))
|
|
(set! (-> cmd group) group)
|
|
(set! (-> cmd volume) (the int (* 10.24 volume)))
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun sound-set-reverb ((arg0 int) (arg1 float) (arg2 float) (arg3 uint))
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(let ((cmd (the-as sound-rpc-set-reverb (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command set-reverb))
|
|
(set! (-> cmd core) arg3)
|
|
(set! (-> cmd reverb) arg0)
|
|
(set! (-> cmd left) (the-as uint (the int (* 32767.0 arg1))))
|
|
(set! (-> cmd right) (the-as uint (the int (* 32767.0 arg2))))
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun sound-set-ear-trans ((ear-trans vector) (cam-trans vector) (cam-angle float))
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(let ((cmd (the sound-rpc-set-ear-trans (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command set-ear-trans))
|
|
(sound-trans-convert (-> cmd ear-trans) ear-trans)
|
|
(sound-trans-convert (-> cmd cam-trans) cam-trans)
|
|
(set! (-> cmd cam-angle) (sound-angle-convert cam-angle))
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defmacro sound-trans-from-process (cmd sound-trans)
|
|
"Macro for getting an appropriate sound-trans from a process-drawable, if possible"
|
|
|
|
`(with-pp
|
|
(let ((proc (the process-drawable pp)))
|
|
(format 0 "get proc~%")
|
|
(when (= ,sound-trans #t)
|
|
(format 0 "trans #t~%")
|
|
(if (and proc
|
|
(type-type? (-> proc type) process-drawable)
|
|
(nonzero? (-> proc root)))
|
|
(set! ,sound-trans (-> proc root trans))
|
|
(set! ,sound-trans (the vector #f))
|
|
)
|
|
(format 0 "trans is ~A~%" ,sound-trans)
|
|
)
|
|
)
|
|
|
|
(format 0 "convert~%" ,sound-trans)
|
|
(sound-trans-convert (-> ,cmd parms trans) ,sound-trans)
|
|
)
|
|
)
|
|
|
|
(defun sound-play-by-name ((name sound-name) (id sound-id) (vol int) (pitch int) (bend int) (group int) (trans symbol))
|
|
"Play a sound called name with the specified params"
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(local-vars (sv-16 int))
|
|
(with-pp
|
|
(set! sv-16 group)
|
|
(let ((sound-trans (the-as structure trans)))
|
|
(when *sound-player-enable*
|
|
(let ((cmd (the-as sound-rpc-play (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command play))
|
|
(set! (-> cmd id) id)
|
|
(set! (-> cmd name) name)
|
|
(set! (-> cmd parms mask) (the-as uint 0))
|
|
(set! (-> cmd parms group) (the-as uint sv-16))
|
|
(set! (-> cmd parms volume) vol)
|
|
(set! (-> cmd parms pitch-mod) pitch)
|
|
(set! (-> cmd parms bend) bend)
|
|
(let ((proc (the-as process-drawable pp)))
|
|
(when (= (the-as symbol sound-trans) #t)
|
|
(if
|
|
(and
|
|
proc
|
|
(type-type? (-> proc type) process-drawable)
|
|
(nonzero? (-> proc root))
|
|
)
|
|
(set! sound-trans (-> proc root trans))
|
|
(set! sound-trans #f)
|
|
)
|
|
)
|
|
)
|
|
(sound-trans-convert (-> cmd parms trans) (the-as vector sound-trans))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
id
|
|
)
|
|
|
|
(defun sound-play-by-spec ((spec sound-spec) (id sound-id) (sound-trans vector))
|
|
"Play a sound from the given spec"
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(when *sound-player-enable*
|
|
(let ((cmd (the sound-rpc-play (get-sound-buffer-entry))))
|
|
|
|
(set! (-> cmd command) (sound-command play))
|
|
(set! (-> cmd id) id)
|
|
(set! (-> cmd name) (-> spec sound-name))
|
|
(set! (-> cmd parms mask) (-> spec mask))
|
|
(set! (-> cmd parms group) (-> spec group))
|
|
(set! (-> cmd parms volume) (-> spec volume))
|
|
(set! (-> cmd parms pitch-mod) (-> spec pitch-mod))
|
|
(set! (-> cmd parms bend) (-> spec bend))
|
|
(set! (-> cmd parms fo-min) (-> spec fo-min))
|
|
(set! (-> cmd parms fo-max) (-> spec fo-max))
|
|
(set! (-> cmd parms fo-curve) (-> spec fo-curve))
|
|
(set! (-> cmd parms priority) (-> spec priority))
|
|
|
|
(sound-trans-from-process cmd sound-trans)
|
|
)
|
|
)
|
|
)
|
|
id
|
|
)
|
|
|
|
(defun sound-pause ((id sound-id))
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(let ((cmd (the sound-rpc-pause-sound (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command pause-sound))
|
|
(set! (-> cmd id) id)
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun sound-stop ((id sound-id))
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(let ((cmd (the sound-rpc-stop-sound (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command stop-sound))
|
|
(set! (-> cmd id) id)
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun sound-continue ((id sound-id))
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(let ((cmd (the sound-rpc-continue-sound (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command continue-sound))
|
|
(set! (-> cmd id) id)
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun sound-group-pause ((group uint))
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(let ((cmd (the sound-rpc-pause-group (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command pause-group))
|
|
(set! (-> cmd group) group)
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun sound-group-stop ((group uint))
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(let ((cmd (the sound-rpc-stop-group (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command stop-group))
|
|
(set! (-> cmd group) group)
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun sound-group-continue ((group uint))
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(let ((cmd (the sound-rpc-continue-group (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command continue-group))
|
|
(set! (-> cmd group) group)
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun sound-set-falloff-curve ((curve int) (falloff float) (ease float))
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(let ((cmd (the sound-rpc-set-falloff-curve (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command set-falloff-curve))
|
|
(set! (-> cmd curve) curve)
|
|
(set! (-> cmd falloff) (the int (* 4096.0 falloff)))
|
|
(set! (-> cmd ease) (the int (* 4096.0 ease)))
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun sound-set-sound-falloff ((name sound-name) (falloff-min int) (falloff-max int) (curve int))
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(let ((cmd (the sound-rpc-set-sound-falloff (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command set-sound-falloff))
|
|
(set! (-> cmd name) name)
|
|
(set! (-> cmd min) falloff-min)
|
|
(set! (-> cmd max) falloff-max)
|
|
(set! (-> cmd curve) curve)
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun sound-set-flava ((flava uint))
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(let ((cmd (the sound-rpc-set-flava (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command set-flava))
|
|
(set! (-> cmd flava) flava)
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun sound-set-fps ((arg0 uint))
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(let ((cmd (the-as sound-rpc-set-fps (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command set-fps))
|
|
(set! (-> cmd fps) arg0)
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun sound-volume-off ()
|
|
"Set all sound volume to zero"
|
|
|
|
(with-pp
|
|
(set-setting! *setting-control* pp 'music-volume 'abs 0.0 0)
|
|
(set-setting! *setting-control* pp 'sfx-volume 'abs 0.0 0)
|
|
(set-setting! *setting-control* pp 'ambient-volume 'abs 0.0 0)
|
|
)
|
|
0
|
|
)
|
|
|
|
(define *ambient-spec* (new 'static 'sound-spec))
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; ambient-sound stuff
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(defmethod new ambient-sound ((allocation symbol) (type-to-make type) (src basic) (sound-trans vector))
|
|
"Make a new ambient-sound. If failed, returns 0 and doesn't allocate anything.
|
|
|
|
src specifies the sound params source. This can be a string or symbol (the sound name), a sound-spec, or an entity-actor or entity-ambient (reads effect-name, cycle-speed and effect-param from the entity)."
|
|
|
|
(let ((spec (the sound-spec #f))
|
|
(name (new 'static 'sound-name))
|
|
(sound-times (the (pointer float) #f))
|
|
(params (the sound-play-parms #f))
|
|
(param-count 0)
|
|
)
|
|
(case (-> src type)
|
|
((entity-actor entity-ambient)
|
|
(swhen (res-lump-struct-exact (the entity src) 'effect-name symbol)
|
|
(set! name (string->sound-name (symbol->string bc)))
|
|
(set! sound-times (res-lump-data (the entity src) 'cycle-speed (pointer float)))
|
|
(set! spec *ambient-spec*)
|
|
(let ((tag (new 'static 'res-tag)))
|
|
(swhen (res-lump-data-exact (the entity src) 'effect-param sound-play-parms :tag-ptr (& tag))
|
|
(set! params bc)
|
|
(set! param-count (the int (-> tag elt-count)))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
((sound-spec)
|
|
(set! spec (the sound-spec src))
|
|
)
|
|
((symbol)
|
|
(set! name (string->sound-name (symbol->string (the symbol src))))
|
|
)
|
|
((string)
|
|
(set! name (string->sound-name (the string src)))
|
|
)
|
|
(else
|
|
(format 0 "ERROR: ambient sound was told to play an unknown ~A.~%" src)
|
|
)
|
|
)
|
|
|
|
(cond
|
|
((or spec (nonzero? name))
|
|
(let ((obj (object-new allocation type-to-make (the-as int (-> type-to-make size)))))
|
|
(set! (-> obj spec) spec)
|
|
(set! (-> obj name) name)
|
|
(set! (-> obj playing-id) (new-sound-id))
|
|
(set! (-> obj params) (the-as (pointer float) params))
|
|
(set! (-> obj param-count) param-count)
|
|
(set! (-> obj entity) #f)
|
|
(set! (-> obj sound-count) 1)
|
|
(set! (-> obj volume) 1024)
|
|
(set! (-> obj pitch) 0)
|
|
(when (and spec (!= spec *ambient-spec*))
|
|
(if (nonzero? (logand (-> spec mask) 1))
|
|
(set! (-> obj volume) (-> spec volume)))
|
|
(if (nonzero? (logand (-> spec mask) 2))
|
|
(set! (-> obj pitch) (-> spec pitch-mod)))
|
|
)
|
|
(cond
|
|
(sound-times
|
|
(set! (-> obj time-base) (the int (* 300.0 (-> sound-times 0))))
|
|
(set! (-> obj time-random) (the int (* 300.0 (-> sound-times 1))))
|
|
)
|
|
(else
|
|
(set! (-> obj time-base) -1)
|
|
)
|
|
)
|
|
(set! (-> obj trans quad) (-> sound-trans quad))
|
|
obj
|
|
)
|
|
)
|
|
(else
|
|
(the ambient-sound 0)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
|
|
(define-extern *debug-effect-control* symbol)
|
|
(defmethod update! ambient-sound ((obj ambient-sound))
|
|
"Called once per frame to update the sound playback"
|
|
|
|
(if (not *ambient-sound-class*)
|
|
(return (the int #f))
|
|
)
|
|
(cond
|
|
((-> obj spec)
|
|
(when (or (< (-> obj time-base) 0)
|
|
(>= (-> *display* base-frame-counter) (-> obj play-time))
|
|
)
|
|
(when (>= (-> obj time-base) 0)
|
|
(set! (-> obj play-time) (+ (-> *display* base-frame-counter)
|
|
(-> obj time-base)
|
|
(rand-vu-int-count (-> obj time-random))
|
|
))
|
|
(set! (-> obj playing-id) (new-sound-id))
|
|
)
|
|
(let ((spec (-> obj spec)))
|
|
(when (= spec *ambient-spec*)
|
|
(set! (-> spec volume) (-> obj volume))
|
|
(set! (-> spec pitch-mod) (-> obj pitch))
|
|
(set! (-> spec bend) 0)
|
|
(set! (-> spec sound-name) (-> obj name))
|
|
(set! (-> spec fo-max) (-> obj falloff-far))
|
|
(set! (-> spec mask) (the-as uint 0))
|
|
(if (-> obj params)
|
|
(effect-param->sound-spec
|
|
spec
|
|
(the-as (pointer float) (-> obj params))
|
|
(-> obj param-count)
|
|
)
|
|
)
|
|
)
|
|
(if (and (nonzero? (-> spec fo-max))
|
|
(< (* 4096.0 (the float (-> spec fo-max)))
|
|
(vector-vector-distance (ear-trans) (-> obj trans))))
|
|
(return 0)
|
|
)
|
|
(when (and *debug-effect-control* (>= (-> obj time-base) 0))
|
|
(with-pp
|
|
(format #t "(~5D) effect sound ~A ~G "
|
|
(-> *display* base-frame-counter)
|
|
(-> pp name)
|
|
(-> spec sound-name-char))
|
|
(format #t "volume: ~f pitch-mod: ~f~%"
|
|
(* (1/ 10.24) (the float (-> spec volume)))
|
|
(* 0.000656168 (the float (-> spec pitch-mod))))
|
|
)
|
|
)
|
|
(let ((spec-volume (-> spec volume)))
|
|
(set! (-> spec volume) (-> obj volume))
|
|
(set! (-> obj playing-id) (sound-play-by-spec spec (-> obj playing-id) (-> obj trans)))
|
|
(set! (-> spec volume) spec-volume)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
(else
|
|
(cond
|
|
((< (-> obj time-base) 0)
|
|
(set! (-> obj playing-id) (sound-play-by-name
|
|
(-> obj name)
|
|
(-> obj playing-id)
|
|
(-> obj volume)
|
|
(-> obj pitch)
|
|
0
|
|
1
|
|
(the-as symbol (-> obj trans))))
|
|
)
|
|
(else
|
|
(when (>= (-> *display* base-frame-counter) (-> obj play-time))
|
|
(set! (-> obj playing-id) (sound-play-by-name
|
|
(-> obj name)
|
|
(new-sound-id)
|
|
(-> obj volume)
|
|
(-> obj pitch)
|
|
0
|
|
1
|
|
(the-as symbol (-> obj trans))))
|
|
(set! (-> obj play-time) (+ (-> *display* base-frame-counter)
|
|
(-> obj time-base)
|
|
(rand-vu-int-count (-> obj time-random))
|
|
))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defmethod stop! ambient-sound ((obj ambient-sound))
|
|
"Halt playback of this ambient-sound"
|
|
|
|
(sound-stop (-> obj playing-id))
|
|
0
|
|
)
|
|
|
|
(defmethod update-trans! ambient-sound ((obj ambient-sound) (sound-trans vector))
|
|
"Update the position of the thing playing the sound"
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(set! (-> obj trans quad) (-> sound-trans quad))
|
|
(when (nonzero? (-> obj playing-id))
|
|
(let ((cmd (the sound-rpc-set-param (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command set-param))
|
|
(set! (-> cmd id) (-> obj playing-id))
|
|
|
|
(sound-trans-from-process cmd sound-trans)
|
|
|
|
(set! (-> cmd parms mask) (the-as uint #x20))
|
|
(-> cmd id)
|
|
)
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
(defmethod update-vol! ambient-sound ((obj ambient-sound) (arg0 int))
|
|
"Update the volume of the sound"
|
|
|
|
(#when PC_DEBUG_SOUND_ENABLE
|
|
(when (nonzero? (-> obj playing-id))
|
|
(let ((cmd (the-as sound-rpc-set-param (get-sound-buffer-entry))))
|
|
(set! (-> cmd command) (sound-command set-param))
|
|
(set! (-> cmd id) (-> obj playing-id))
|
|
(set! (-> cmd parms volume) (the int (* 10.24 (the float arg0))))
|
|
(set! (-> cmd parms mask) (the-as uint 1))
|
|
(-> cmd id)
|
|
)
|
|
)
|
|
(set! (-> obj volume) (the int (* 10.24 (the float arg0))))
|
|
)
|
|
0
|
|
)
|
|
|
|
(defmethod change-sound! ambient-sound ((obj ambient-sound) (name sound-name))
|
|
"Change the sound being played"
|
|
(when (not (sound-name= (-> obj name) name))
|
|
(stop! obj)
|
|
(set! (-> obj playing-id) (new-sound-id))
|
|
(set! (-> obj name) name)
|
|
)
|
|
0
|
|
)
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; sound iop debugging
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(defun show-iop-info ((buf dma-buffer))
|
|
"Display sound channel status in the top left corner"
|
|
|
|
(dotimes (ch 24)
|
|
(draw-string-xy
|
|
(if (zero? (-> *sound-iop-info* chinfo ch)) "." "X")
|
|
buf (+ (* ch 16) 16) 48 (font-color default) (font-flags shadow))
|
|
)
|
|
(dotimes (ch 24)
|
|
(draw-string-xy
|
|
(if (zero? (-> *sound-iop-info* chinfo (+ ch 24))) "." "X")
|
|
buf (+ (* ch 16) 16) 64 (font-color default) (font-flags shadow))
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun show-iop-memory ((buf dma-buffer))
|
|
(draw-string-xy
|
|
(string-format "~8D [~4D]" (-> *sound-iop-info* freemem)
|
|
(shr (-> *sound-iop-info* freemem) 10))
|
|
buf 32 96 (font-color default) (font-flags shadow))
|
|
(draw-string-xy
|
|
(string-format "~8D [~4D]" (-> *sound-iop-info* freemem2)
|
|
(shr (-> *sound-iop-info* freemem2) 10))
|
|
buf 32 64 (font-color default) (font-flags shadow))
|
|
0
|
|
)
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; sound utils
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(defun-extern math-camera-pos vector)
|
|
(defun-extern target-pos int vector)
|
|
(defun-extern camera-pos vector)
|
|
(defun ear-trans ()
|
|
"Return the trans for the game ear"
|
|
|
|
(cond
|
|
((or (movie?) *external-cam-mode*)
|
|
(math-camera-pos)
|
|
)
|
|
(*target*
|
|
(target-pos 0)
|
|
)
|
|
(else
|
|
(camera-pos)
|
|
)
|
|
)
|
|
)
|
|
|
|
(defun-debug make-sqrt-table ()
|
|
"Write the C code for the ??? square root table"
|
|
|
|
(format #t "static int sqrt_table[256] =~%{~%")
|
|
(dotimes (i 256)
|
|
(let* ((angle (sqrtf (* 16777216.0 (the float i))))
|
|
(angle-rounded (the int (+ 0.5 angle))))
|
|
(format #t "~D,~%" angle-rounded)
|
|
)
|
|
)
|
|
(format #t "};~%")
|
|
0
|
|
)
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; flava system
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(deftype flava-table-row (structure)
|
|
((music symbol :offset-assert 0)
|
|
(flava uint8 50 :offset-assert 4) ;; index is some flava event, value is music variation
|
|
)
|
|
:allow-misaligned :method-count-assert 9
|
|
:size-assert #x36
|
|
:flag-assert #x900000036
|
|
)
|
|
|
|
(deftype flava-table (basic)
|
|
((row flava-table-row 20 :inline :offset-assert 4)
|
|
(count int32 :offset-assert 1284)
|
|
)
|
|
:method-count-assert 9
|
|
:size-assert #x508
|
|
:flag-assert #x900000508
|
|
)
|
|
|
|
;; make a new flava table with nothing defined
|
|
(define *flava-table* (new 'global 'flava-table))
|
|
(set! (-> *flava-table* count) 0)
|
|
|
|
(defun flava-lookup ((music symbol) (n int))
|
|
"Return the n'th flava for the specified music"
|
|
|
|
(dotimes (i (-> *flava-table* count))
|
|
(if (= (-> *flava-table* row i music) music)
|
|
(return (the-as int (-> *flava-table* row i flava n)))
|
|
)
|
|
)
|
|
0
|
|
)
|
|
|
|
|
|
(defmacro flava-table-add (name &rest flavas)
|
|
"Add a new music and its flavas to the table"
|
|
|
|
`(begin
|
|
;; append a new music to the flava table
|
|
(set! (-> *flava-table* row (-> *flava-table* count) music) ,name)
|
|
|
|
;; reset this music's flavas
|
|
(dotimes (n 50)
|
|
(set! (-> *flava-table* row (-> *flava-table* count) flava n) 0)
|
|
)
|
|
|
|
;; increase the music count
|
|
;; (this should probably be done after...)
|
|
(1+! (-> *flava-table* count))
|
|
|
|
;; set the flavas or whatever they're called
|
|
,@(apply (lambda (x) `(set! (-> *flava-table* row (1- (-> *flava-table* count)) flava ,(first x)) ,(second x))) flavas)
|
|
)
|
|
)
|
|
|
|
#| flava events (guesses):
|
|
0 :
|
|
1 : racer
|
|
2 : flutflut
|
|
3 : to-maincave
|
|
4 : to-snow
|
|
5 : sage
|
|
6 : assistant
|
|
7 : birdlady
|
|
8 : mayor
|
|
9 : sculptor
|
|
10: uncle
|
|
11: sage-yellow
|
|
12: sage-red
|
|
13: sage-blue
|
|
14: miners
|
|
15: warrior
|
|
16: geologist
|
|
17: gambler
|
|
18: sage-hut
|
|
19: dock
|
|
20: farmer
|
|
21: jungleb-eggtop
|
|
22: misty-boat
|
|
23: misty-ambush (?)
|
|
24: beach-sentinel
|
|
25: beach-cannon
|
|
26: beach-logs
|
|
27: citadel-center
|
|
28: robocave
|
|
29: robocave-top
|
|
30: maincave
|
|
31: darkcave
|
|
32: snow-ambush (?)
|
|
33: snow-cave
|
|
34: snow-fort
|
|
35: snow-balls
|
|
36: levitator
|
|
37: swamp-launcher
|
|
38: swamp-ambush (?)
|
|
39: jungle-temple-exit
|
|
40: jungle-lurkerm
|
|
41: jungle-temple-top
|
|
42: rolling-race
|
|
43: ogre-middle
|
|
44: ogre-end
|
|
45: lavatube-middle
|
|
46: lavatube-end
|
|
47: finalboss-middle
|
|
48: finalboss-end
|
|
49: default
|
|
|#
|
|
|
|
;; TODO make enum
|
|
(flava-table-add 'village1
|
|
(5 2)
|
|
(6 6)
|
|
(7 4)
|
|
(20 5)
|
|
(8 7)
|
|
(9 8)
|
|
(10 9)
|
|
(19 10)
|
|
(18 3)
|
|
)
|
|
|
|
(flava-table-add 'jungle
|
|
(39 1)
|
|
(40 2)
|
|
(41 3)
|
|
)
|
|
|
|
(flava-table-add 'firecanyon
|
|
(1 1)
|
|
)
|
|
|
|
(flava-table-add 'jungleb
|
|
(21 1)
|
|
)
|
|
|
|
(flava-table-add 'beach
|
|
(7 4)
|
|
(24 1)
|
|
(25 2)
|
|
(26 3)
|
|
)
|
|
|
|
(flava-table-add 'misty
|
|
(1 3)
|
|
(22 2)
|
|
(23 1)
|
|
)
|
|
|
|
(flava-table-add 'village2
|
|
(5 1)
|
|
(6 2)
|
|
(15 3)
|
|
(16 4)
|
|
(17 5)
|
|
(36 6)
|
|
)
|
|
|
|
(flava-table-add 'swamp
|
|
(2 4)
|
|
(37 2)
|
|
(38 3)
|
|
)
|
|
|
|
(flava-table-add 'rolling
|
|
(42 1)
|
|
)
|
|
|
|
(flava-table-add 'ogre
|
|
(43 1)
|
|
(44 2)
|
|
)
|
|
|
|
(flava-table-add 'village3
|
|
(3 4)
|
|
(4 5)
|
|
(5 2)
|
|
(6 3)
|
|
(14 1)
|
|
)
|
|
|
|
(flava-table-add 'maincave
|
|
(28 1)
|
|
(29 2)
|
|
(30 3)
|
|
(31 4)
|
|
)
|
|
|
|
(flava-table-add 'snow
|
|
(2 2)
|
|
(32 1)
|
|
(33 3)
|
|
(34 4)
|
|
(35 5)
|
|
)
|
|
|
|
(flava-table-add 'lavatube
|
|
(45 2)
|
|
(46 3)
|
|
(49 1)
|
|
)
|
|
|
|
(flava-table-add 'citadel
|
|
(5 1)
|
|
(6 2)
|
|
(11 3)
|
|
(12 4)
|
|
(13 5)
|
|
(27 6)
|
|
)
|
|
|
|
(flava-table-add 'finalboss
|
|
(47 1)
|
|
(48 2)
|
|
)
|
|
|
|
(flava-table-add 'credits
|
|
(49 2)
|
|
)
|