mirror of
https://github.com/open-goal/jak-project
synced 2026-07-07 14:13:45 -04:00
add more comments/docstrings on first 58 files, try new windows-specific framelimiting (#1134)
* cleanup * type * link against a library
This commit is contained in:
@@ -38,12 +38,16 @@ add_library(common
|
||||
util/os.cpp
|
||||
util/print_float.cpp
|
||||
util/FontUtils.cpp
|
||||
util/image_loading.cpp "goos/Printer.cpp" "goos/Printer.h" "goos/PrettyPrinter2.cpp" "goos/PrettyPrinter2.h")
|
||||
util/FrameLimiter.cpp
|
||||
util/image_loading.cpp
|
||||
goos/Printer.cpp
|
||||
goos/PrettyPrinter2.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(common fmt lzokay replxx libzstd_static)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(common wsock32 ws2_32)
|
||||
target_link_libraries(common wsock32 ws2_32 windowsapp)
|
||||
else()
|
||||
target_link_libraries(common stdc++fs)
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#include "FrameLimiter.h"
|
||||
#include <thread>
|
||||
|
||||
double FrameLimiter::round_to_nearest_60fps(double current) {
|
||||
double one_frame = 1.f / 60.f;
|
||||
int frames_missed = (current / one_frame); // rounds down
|
||||
if (frames_missed > 4) {
|
||||
frames_missed = 4;
|
||||
}
|
||||
return (frames_missed + 1) * one_frame;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
FrameLimiter::FrameLimiter() {}
|
||||
|
||||
FrameLimiter::~FrameLimiter() {}
|
||||
|
||||
void FrameLimiter::run(double target_fps,
|
||||
bool experimental_accurate_lag,
|
||||
bool do_sleeps,
|
||||
double engine_time) {
|
||||
double target_seconds;
|
||||
if (experimental_accurate_lag) {
|
||||
target_seconds = round_to_nearest_60fps(engine_time);
|
||||
} else {
|
||||
target_seconds = 1.f / target_fps;
|
||||
}
|
||||
double remaining_time = target_seconds - m_timer.getSeconds();
|
||||
|
||||
if (do_sleeps && remaining_time > 0.001) {
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(int((remaining_time - 0.001) * 1e6)));
|
||||
}
|
||||
|
||||
while (remaining_time > 0) {
|
||||
remaining_time = target_seconds - m_timer.getSeconds();
|
||||
}
|
||||
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
FrameLimiter::FrameLimiter() {
|
||||
timeBeginPeriod(1);
|
||||
}
|
||||
|
||||
FrameLimiter::~FrameLimiter() {
|
||||
timeEndPeriod(0);
|
||||
}
|
||||
|
||||
void FrameLimiter::run(double target_fps,
|
||||
bool experimental_accurate_lag,
|
||||
bool do_sleeps,
|
||||
double engine_time) {
|
||||
double target_seconds;
|
||||
if (experimental_accurate_lag) {
|
||||
target_seconds = round_to_nearest_60fps(engine_time);
|
||||
} else {
|
||||
target_seconds = 1.f / target_fps;
|
||||
}
|
||||
double remaining_time = target_seconds - m_timer.getSeconds();
|
||||
|
||||
if (do_sleeps && remaining_time > 0.001) {
|
||||
Sleep((remaining_time * 1000) - 1);
|
||||
}
|
||||
|
||||
while (remaining_time > 0) {
|
||||
remaining_time = target_seconds - m_timer.getSeconds();
|
||||
}
|
||||
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -4,33 +4,13 @@
|
||||
|
||||
class FrameLimiter {
|
||||
public:
|
||||
void run(double target_fps, bool experimental_accurate_lag, double engine_time) {
|
||||
double target_seconds;
|
||||
if (experimental_accurate_lag) {
|
||||
target_seconds = round_to_nearest_60fps(engine_time);
|
||||
} else {
|
||||
target_seconds = 1.f / target_fps;
|
||||
}
|
||||
double remaining_time = target_seconds - m_timer.getSeconds();
|
||||
while (remaining_time > 0) {
|
||||
if (remaining_time > 0.003) {
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(int(remaining_time * 1e6 * 0.5)));
|
||||
}
|
||||
remaining_time = target_seconds - m_timer.getSeconds();
|
||||
}
|
||||
FrameLimiter();
|
||||
~FrameLimiter();
|
||||
|
||||
m_timer.start();
|
||||
}
|
||||
void run(double target_fps, bool experimental_accurate_lag, bool do_sleeps, double engine_time);
|
||||
|
||||
private:
|
||||
double round_to_nearest_60fps(double current) {
|
||||
double one_frame = 1.f / 60.f;
|
||||
int frames_missed = (current / one_frame); // rounds down
|
||||
if (frames_missed > 4) {
|
||||
frames_missed = 4;
|
||||
}
|
||||
return (frames_missed + 1) * one_frame;
|
||||
}
|
||||
double round_to_nearest_60fps(double current);
|
||||
|
||||
Timer m_timer;
|
||||
};
|
||||
@@ -122,6 +122,7 @@ void OpenGlDebugGui::draw(const DmaStats& dma_stats) {
|
||||
}
|
||||
ImGui::Separator();
|
||||
ImGui::Checkbox("Accurate Lag Mode", &experimental_accurate_lag);
|
||||
ImGui::Checkbox("Sleep in Frame Limiter", &sleep_in_frame_limiter);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ class OpenGlDebugGui {
|
||||
bool framelimiter = false;
|
||||
float target_fps = 60.f;
|
||||
bool experimental_accurate_lag = false;
|
||||
bool sleep_in_frame_limiter = true;
|
||||
|
||||
private:
|
||||
FrameTimeRecorder m_frame_timer;
|
||||
|
||||
@@ -140,6 +140,7 @@ static std::shared_ptr<GfxDisplay> gl_make_main_display(int width,
|
||||
int height,
|
||||
const char* title,
|
||||
GfxSettings& settings) {
|
||||
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE);
|
||||
GLFWwindow* window = glfwCreateWindow(width, height, title, NULL, NULL);
|
||||
|
||||
if (!window) {
|
||||
@@ -430,9 +431,9 @@ static void gl_render_display(GfxDisplay* display) {
|
||||
g_gfx_data->debug_gui.finish_frame();
|
||||
glfwSwapBuffers(window);
|
||||
if (g_gfx_data->debug_gui.framelimiter) {
|
||||
g_gfx_data->frame_limiter.run(g_gfx_data->debug_gui.target_fps,
|
||||
g_gfx_data->debug_gui.experimental_accurate_lag,
|
||||
g_gfx_data->last_engine_time);
|
||||
g_gfx_data->frame_limiter.run(
|
||||
g_gfx_data->debug_gui.target_fps, g_gfx_data->debug_gui.experimental_accurate_lag,
|
||||
g_gfx_data->debug_gui.sleep_in_frame_limiter, g_gfx_data->last_engine_time);
|
||||
}
|
||||
g_gfx_data->debug_gui.start_frame();
|
||||
|
||||
|
||||
@@ -7,8 +7,13 @@
|
||||
|
||||
|
||||
;; The math-camera is a global that contains camera projection and culling matrices.
|
||||
;; Note that it doesn't take into account the position/rotation of the game camera, but
|
||||
;; just computes the projection matrix/culling stuff and the camera stuff will have to
|
||||
;; rotate and translate it as needed.
|
||||
|
||||
;; It also contains some GIF stuff, but these seem to be wrong/unused.
|
||||
;; Some of the code here may be extremely old and unused.
|
||||
;; Some of the code here may be extremely old and unused, but this does compute the camera projection
|
||||
;; matrix used almost everywhere.
|
||||
|
||||
(deftype vis-gif-tag (structure)
|
||||
((fog0 uint32 :offset-assert 0)
|
||||
@@ -50,6 +55,8 @@
|
||||
((d meters :offset-assert 4) ;; camera near plane
|
||||
(f meters :offset-assert 8) ;; camera far plane
|
||||
(fov degrees :offset-assert 12) ;; field of view angle
|
||||
|
||||
;; view frustum
|
||||
(x-ratio float :offset-assert 16)
|
||||
(y-ratio float :offset-assert 20)
|
||||
(x-pix float :offset-assert 24)
|
||||
@@ -76,6 +83,10 @@
|
||||
(inv-camera-rot matrix :inline :offset-assert 432)
|
||||
(inv-camera-rot-smooth matrix :inline :offset-assert 496)
|
||||
(inv-camera-rot-smooth-from quaternion :inline :offset-assert 560)
|
||||
;; this camera-temp is the main matrix used for renderers.
|
||||
;; the camera code will set this.
|
||||
;; it's designed so the renderers can do a single matrix-vector multiply
|
||||
;; and then get fog, clipping, and final vertex position from the result.
|
||||
(camera-temp matrix :inline :offset-assert 576)
|
||||
(prev-camera-temp matrix :inline :offset-assert 640)
|
||||
(hmge-scale vector :inline :offset-assert 704)
|
||||
|
||||
@@ -122,30 +122,45 @@
|
||||
;; reset camera rotation
|
||||
(matrix-identity! (-> math-cam camera-rot))
|
||||
|
||||
(let ((fog-constant-1 100.0)
|
||||
(fog-constant-2 16760631.0)
|
||||
;;;;;;;;;;;;;; Perspective matrix setup
|
||||
|
||||
;; these min/max depths are the values we'd want to write to the 24-bit integer depth buffer
|
||||
(let ((min-depth 100.0)
|
||||
(max-depth 16760631.0) ;; almost 2^24.
|
||||
)
|
||||
(let ((f0-21 16777115.0)))
|
||||
(let ((fog-at-near-plane
|
||||
(let ((f0-21 16777115.0))) ;; unused. this is actually float closest to 2^24
|
||||
|
||||
;; next, compute the fog slope d(8bit_integer_fog_value)/d(game_world_distance).
|
||||
;; the final fog values we want are an 8-bit integer.
|
||||
;; note that this is the fog at the near plane too.
|
||||
(let ((fog-slope
|
||||
(/ (* (-> math-cam d) (- (-> math-cam fog-min) (-> math-cam fog-max)))
|
||||
(- (-> *math-camera-fog-correction* fog-end)
|
||||
(-> *math-camera-fog-correction* fog-start)
|
||||
)
|
||||
)
|
||||
)
|
||||
(fog-factor-2 (* -0.5 (- fog-constant-2 fog-constant-1)))
|
||||
;; this is half the range of the depth buffer.
|
||||
(depth-buffer-half-range (* -0.5 (- max-depth min-depth)))
|
||||
)
|
||||
(let ((corrected-fog (/ fog-factor-2 (* (-> math-cam d) (- (-> math-cam f) (-> math-cam d)))))
|
||||
;; this is the slope to convert game world depths to depth buffer depths
|
||||
(let ((half-depth-buffer-slope (/ depth-buffer-half-range (* (-> math-cam d) (- (-> math-cam f) (-> math-cam d)))))
|
||||
(cam-fov-mult (-> math-cam fov-correction-factor))
|
||||
)
|
||||
|
||||
;; finally, build the actual matrix.
|
||||
;; x/y are just the usual scaling
|
||||
(set! (-> math-cam perspective vector 0 x) (* cam-fov-mult (- (/ (-> math-cam x-pix) (* (-> math-cam x-ratio) (-> math-cam d))))))
|
||||
(set! (-> math-cam perspective vector 1 y) (* cam-fov-mult (- (/ (-> math-cam y-pix) (* (-> math-cam y-ratio) (-> math-cam d))))))
|
||||
(set! (-> math-cam perspective vector 2 z) (* cam-fov-mult (+ (-> math-cam f) (-> math-cam d)) corrected-fog))
|
||||
(set! (-> math-cam perspective vector 2 w) (* (/ cam-fov-mult (-> math-cam d)) fog-at-near-plane))
|
||||
(set! (-> math-cam perspective vector 3 z) (* -2.0 corrected-fog (-> math-cam f) (-> math-cam d) cam-fov-mult))
|
||||
;; depth scaling
|
||||
(set! (-> math-cam perspective vector 2 z) (* cam-fov-mult (+ (-> math-cam f) (-> math-cam d)) half-depth-buffer-slope))
|
||||
;; depth to fog
|
||||
(set! (-> math-cam perspective vector 2 w) (* (/ cam-fov-mult (-> math-cam d)) fog-slope))
|
||||
|
||||
(set! (-> math-cam perspective vector 3 z) (* -2.0 half-depth-buffer-slope (-> math-cam f) (-> math-cam d) cam-fov-mult))
|
||||
)
|
||||
|
||||
;; hvdf/hmge, no idea what these are
|
||||
;; hvdf = horizontal, vertical, depth, fog offsets to be applied after transform.
|
||||
(let ((hvdf-x 2048.0)
|
||||
(hvdf-y 2048.0)
|
||||
(hvdf-w
|
||||
@@ -160,15 +175,15 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
(let ((hvdf-z (* 0.5 (+ fog-constant-2 fog-constant-1))))
|
||||
(let ((hvdf-z (* 0.5 (+ max-depth min-depth))))
|
||||
(set! (-> math-cam hmge-scale x) (/ 1.0 (-> math-cam x-clip)))
|
||||
(set! (-> math-cam hmge-scale y) (/ 1.0 (-> math-cam y-clip)))
|
||||
(set! (-> math-cam hmge-scale z) (/ 1.0 fog-factor-2))
|
||||
(set! (-> math-cam hmge-scale w) (/ 1.0 fog-at-near-plane))
|
||||
(set! (-> math-cam hmge-scale z) (/ 1.0 depth-buffer-half-range))
|
||||
(set! (-> math-cam hmge-scale w) (/ 1.0 fog-slope))
|
||||
(set! (-> math-cam inv-hmge-scale x) (-> math-cam x-clip))
|
||||
(set! (-> math-cam inv-hmge-scale y) (-> math-cam y-clip))
|
||||
(set! (-> math-cam inv-hmge-scale z) fog-factor-2)
|
||||
(set! (-> math-cam inv-hmge-scale w) fog-at-near-plane)
|
||||
(set! (-> math-cam inv-hmge-scale z) depth-buffer-half-range)
|
||||
(set! (-> math-cam inv-hmge-scale w) fog-slope)
|
||||
(set! (-> math-cam hvdf-off x) hvdf-x)
|
||||
(set! (-> math-cam hvdf-off y) hvdf-y)
|
||||
(set! (-> math-cam hvdf-off z) hvdf-z)
|
||||
@@ -188,7 +203,7 @@
|
||||
)
|
||||
|
||||
)
|
||||
(set! (-> math-cam isometric vector 3 w) fog-at-near-plane)
|
||||
(set! (-> math-cam isometric vector 3 w) fog-slope)
|
||||
|
||||
;; perspective matrix
|
||||
(let ((persp-xx (-> math-cam perspective vector 0 x))
|
||||
@@ -215,7 +230,7 @@
|
||||
(set! (-> math-cam sprite-2d-hvdf x) 2048.0)
|
||||
(set! (-> math-cam sprite-2d-hvdf y) 2048.0)
|
||||
(set! (-> math-cam sprite-2d-hvdf z) (-> math-cam hvdf-off z))
|
||||
(set! (-> math-cam pfog0) fog-at-near-plane)
|
||||
(set! (-> math-cam pfog0) fog-slope)
|
||||
(set! (-> math-cam pfog1) hvdf-w)
|
||||
)
|
||||
)
|
||||
@@ -266,6 +281,7 @@
|
||||
|
||||
|
||||
(defmethod new math-camera ((allocation symbol) (type-to-make type))
|
||||
"Set up a new math-camera in NTSC mode."
|
||||
(let ((gp-0 (object-new allocation type-to-make (the-as int (-> type-to-make size)))))
|
||||
(set! (-> gp-0 d) 1024.0)
|
||||
(set! (-> gp-0 f) 40960000.0)
|
||||
@@ -382,7 +398,9 @@
|
||||
)
|
||||
|
||||
(defun transform-point-vector! ((arg0 vector) (arg1 vector))
|
||||
"Apply camera transformation to a point."
|
||||
"Apply camera transformation to a point. Return true if it is visible or not.
|
||||
This returns the point in GS coords, but as float instead of int, so it's
|
||||
not really useful. See transform-point-qword! for more details"
|
||||
(rlet ((acc :class vf)
|
||||
(Q :class vf)
|
||||
(vf0 :class vf)
|
||||
@@ -428,7 +446,8 @@
|
||||
)
|
||||
|
||||
(defun transform-point-qword! ((arg0 vector4w) (arg1 vector))
|
||||
"Apply camera transformation to point, returning fixed point 28.4 position"
|
||||
"Apply camera transformation to point, returning fixed point 28.4 position
|
||||
that can be given to the GS directly."
|
||||
(rlet ((acc :class vf)
|
||||
(Q :class vf)
|
||||
(vf0 :class vf)
|
||||
@@ -445,37 +464,60 @@
|
||||
(init-vf0-vector)
|
||||
(let ((v1-0 0))
|
||||
)
|
||||
|
||||
;; this camera matrix has both the projection and camera translation/rotation
|
||||
(.lvf vf24 (&-> *math-camera* camera-temp vector 0 quad))
|
||||
(.lvf vf25 (&-> *math-camera* camera-temp vector 1 quad))
|
||||
(.lvf vf26 (&-> *math-camera* camera-temp vector 2 quad))
|
||||
(.lvf vf27 (&-> *math-camera* camera-temp vector 3 quad))
|
||||
|
||||
;; scaling
|
||||
(.lvf vf29 (&-> *math-camera* hmge-scale quad))
|
||||
|
||||
;; offset
|
||||
(.lvf vf30 (&-> *math-camera* hvdf-off quad))
|
||||
|
||||
;; input point
|
||||
(.lvf vf28 (&-> arg1 quad))
|
||||
|
||||
;; matrix multiply, result in vf28
|
||||
(.mul.x.vf acc vf24 vf28)
|
||||
(.add.mul.y.vf acc vf25 vf28 acc)
|
||||
(.add.mul.z.vf acc vf26 vf28 acc)
|
||||
(.add.mul.w.vf vf28 vf27 vf0 acc) ;; matrix mult.
|
||||
(.add.w.vf vf23 vf0 vf0) ;; clear w.
|
||||
(.add.mul.w.vf vf28 vf27 vf0 acc)
|
||||
|
||||
|
||||
(.add.w.vf vf23 vf0 vf0) ;; set w = 1.0
|
||||
|
||||
;; apply hmge scaling. the result of this multiply sets clipping flags appropriately
|
||||
(.mul.vf vf31 vf28 vf29) ;; scale.
|
||||
;;(TODO.VCLIP vf31 vf31)
|
||||
(let ((clip (vu-clip vf31 0)))
|
||||
(let ((clip (vu-clip vf31 0))) ;; clip!
|
||||
|
||||
;; perspective divide
|
||||
(.div.vf Q vf0 vf31 :fsf #b11 :ftf #b11)
|
||||
(.wait.vf)
|
||||
;;(.cfc2.i v1-7 Clipping)
|
||||
;; perspective
|
||||
(.mul.vf vf28 vf28 Q :mask #b111)
|
||||
;; compute scale factor (w was 1.0)
|
||||
(.mul.vf vf23 vf23 Q)
|
||||
;; apply hvdf offsets
|
||||
(.add.vf vf28 vf28 vf30)
|
||||
;; saturate fog
|
||||
(.max.x.vf vf28 vf28 vf0 :mask #b1000)
|
||||
;;(TODO.VFTOI4 vf28 vf28)
|
||||
;; convert to GS fixed point
|
||||
(vftoi4.xyzw vf28 vf28)
|
||||
;; store result!
|
||||
(.svf (&-> arg0 quad) vf28)
|
||||
;; return result of clipping.
|
||||
(zero? (logand clip 63))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(defun transform-point-vector-scale! ((arg0 vector) (arg1 vector))
|
||||
"Similar to transform-point-qword! but returns the scale factor instead."
|
||||
(local-vars (v0-0 float))
|
||||
(rlet ((acc :class vf)
|
||||
(Q :class vf)
|
||||
@@ -523,7 +565,9 @@
|
||||
)
|
||||
|
||||
(defun init-for-transform ((arg0 matrix))
|
||||
"Sets up VU0 registers with camera info. Most rendering stuff doesn't use this."
|
||||
"Sets up VU0 registers with camera info.
|
||||
This is probably a very old function and it's only used by jungle mirrors.
|
||||
It stashes some data in vector float registers that must be there before calling transform-float-point."
|
||||
(rlet ((vf1 :class vf)
|
||||
(vf17 :class vf)
|
||||
(vf18 :class vf)
|
||||
|
||||
@@ -5,11 +5,14 @@
|
||||
;; name in dgo: memory-usage-h
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
;; The memory-usage system is used to track how memory is arranged.
|
||||
;; The memory-usage system is used to track how much memory is used by tracking statistics for categories.
|
||||
;; It can be used in different ways for different objects.
|
||||
;; - DMA memory usage per renderer
|
||||
;; - static level data memory usage
|
||||
;; - actor heap memory usage
|
||||
;; All basics have a mem-usage method that will add its memory usage to
|
||||
;; a memory-usage-block. It also takes some flags that are currently unknown.
|
||||
|
||||
|
||||
;; Information for a single category.
|
||||
(deftype memory-usage-info (structure)
|
||||
((name string :offset-assert 0)
|
||||
|
||||
@@ -295,7 +295,7 @@
|
||||
(debug-draw1 68)
|
||||
)
|
||||
|
||||
;; A DMA bucket is a way of organizing data within a dma buffer.
|
||||
;; A DMA bucket is a way of sorting data within a dma buffer.
|
||||
;; The buckets themselves live inside in the dma buffer.
|
||||
;; the addr field of their tag should point to the next bucket.
|
||||
;; This is not a PS2 hardware thing
|
||||
|
||||
@@ -6,10 +6,17 @@
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
;; This extremely confusing "connection system" allows the connection between
|
||||
;; "engines" and "processes". Basically, a process may add connections to an engine.
|
||||
;; A "connection" is really just a function that gets called when the engine runs.
|
||||
;; Another way to use the system is as a queue of messages from processes to the engine,
|
||||
;; without using a function.
|
||||
;; "engines" and "processes". Basically, a process can "register" itself with any number of "engines".
|
||||
;; The "engines" can then iterate through all the connected processes. If a process is destroyed, it will
|
||||
;; be removed from all engines. It is okay to connect a process to multiple engines, or even to the same engine
|
||||
;; multiple times.
|
||||
|
||||
;; Some example uses:
|
||||
;; - a "foreground-engine" has connections to all foreground objects that need to be drawn on each frame.
|
||||
;; - when a process wants to change a game setting, it opens a connection to the settings engine to request a change.
|
||||
;; when the process is killed, the setting change is reverted.
|
||||
|
||||
;; A "connection" is really just a function that gets called when the engine runs, or a set of parameters that the engine can iterate through.
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -556,8 +563,6 @@
|
||||
0
|
||||
)
|
||||
|
||||
|
||||
|
||||
(defmethod remove-by-param2 engine ((obj engine) (p2-value int))
|
||||
"Remove all connections with param2 matching p2-value"
|
||||
(let* ((current (-> obj alive-list next0))
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
)
|
||||
|
||||
;; bounding both that has both a box and box4w.
|
||||
;; these are used in the collision system where it is useful to have both float/int versions.
|
||||
(deftype bounding-box-both (structure)
|
||||
((box bounding-box :inline :offset-assert 0)
|
||||
(box4w bounding-box4w :inline :offset-assert 32)
|
||||
|
||||
@@ -29,9 +29,7 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for method 11 of type bounding-box
|
||||
(defmethod set-from-point-offset! bounding-box
|
||||
((obj bounding-box) (arg0 vector3s) (arg1 vector3s))
|
||||
(defmethod set-from-point-offset! bounding-box ((obj bounding-box) (arg0 vector3s) (arg1 vector3s))
|
||||
"Set box to smallest containing the points arg0, (arg0 + arg1)"
|
||||
(rlet ((vf0 :class vf)
|
||||
(vf1 :class vf)
|
||||
@@ -54,7 +52,6 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for method 10 of type bounding-box
|
||||
(defmethod add-point! bounding-box ((obj bounding-box) (arg0 vector3s))
|
||||
"Expand the box if needed to contain the given point"
|
||||
(rlet ((vf1 :class vf)
|
||||
@@ -72,7 +69,6 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for method 15 of type bounding-box
|
||||
(defmethod add-box! bounding-box ((obj bounding-box) (arg0 bounding-box))
|
||||
"Expand the box if needed to contain the given box"
|
||||
(rlet ((vf1 :class vf)
|
||||
@@ -92,9 +88,7 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for method 12 of type bounding-box
|
||||
(defmethod set-from-point-offset-pad! bounding-box
|
||||
((obj bounding-box) (arg0 vector3s) (arg1 vector3s) (arg2 float))
|
||||
(defmethod set-from-point-offset-pad! bounding-box ((obj bounding-box) (arg0 vector3s) (arg1 vector3s) (arg2 float))
|
||||
"Set the box size to contain pt, pt + offset, with some padding"
|
||||
(rlet ((vf0 :class vf)
|
||||
(vf1 :class vf)
|
||||
@@ -121,7 +115,6 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for method 13 of type bounding-box
|
||||
(defmethod set-from-sphere! bounding-box ((obj bounding-box) (arg0 sphere))
|
||||
"Set the box size to contain the given sphere"
|
||||
(rlet ((vf0 :class vf)
|
||||
@@ -141,6 +134,12 @@
|
||||
)
|
||||
)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; multi-sphere methods
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; these are used in the collision system to build bounding boxes around collision geometries, so they are quite optimized.
|
||||
|
||||
(defmethod add-spheres! bounding-box ((obj bounding-box) (spheres (inline-array sphere)) (count int))
|
||||
"Add count spheres."
|
||||
;; the PS2 implementation is very optimized
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
(defconstant MAX_CURVE_CONTROL_POINTS 256)
|
||||
|
||||
;; A 3 dimensional polynomial spline with arbitrarily placed knot points
|
||||
;; It's used for camera paths and similar and can be generated by offline tools.
|
||||
(deftype curve (structure)
|
||||
((cverts pointer :offset-assert 0)
|
||||
(num-cverts int32 :offset-assert 4)
|
||||
@@ -19,6 +21,7 @@
|
||||
:flag-assert #x900000014
|
||||
)
|
||||
|
||||
;; unused plane type that would likely trigger some action on crossing.
|
||||
(deftype border-plane (basic)
|
||||
((name symbol :offset-assert 4)
|
||||
(action basic :offset-assert 8)
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
;; Geometry functions are common vector/plane utilities + the "curve" stuff
|
||||
;; The curves are likely bezier splines, but not 100% sure yet.
|
||||
|
||||
(defun vector-flatten! ((dst vector) (src vector) (plane-normal vector))
|
||||
"Get the projection of src onto a plane with the given normal
|
||||
@@ -143,6 +142,9 @@
|
||||
)
|
||||
|
||||
(defun vector-segment-distance-point! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 vector))
|
||||
"Compute the distance from a point to the closest point on the line segment.
|
||||
arg0 is the point. arg1/arg2 are the endpoints of the line segment.
|
||||
arg3 is an optional output closest point."
|
||||
(local-vars (v0-0 float) (v1-0 float) (v1-1 float))
|
||||
(rlet ((acc :class vf)
|
||||
(Q :class vf)
|
||||
@@ -212,6 +214,8 @@
|
||||
)
|
||||
|
||||
(defun vector-line-distance ((arg0 vector) (arg1 vector) (arg2 vector))
|
||||
"Weird function: given a point arg1, and an infinite line connecting arg2 and arg1, compute the distance
|
||||
from arg0 to that line."
|
||||
(let* ((a1-3 (vector-normalize! (vector-! (new-stack-vector0) arg2 arg1) 1.0))
|
||||
(gp-1 (vector-! (new-stack-vector0) arg0 arg1))
|
||||
(f0-1 (vector-dot a1-3 gp-1))
|
||||
@@ -222,6 +226,7 @@
|
||||
)
|
||||
|
||||
(defun vector-line-distance-point! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 vector))
|
||||
"Same as above function, but returns the point on arg2/arg1 in arg3 (ignored if #f)"
|
||||
(let* ((a1-3 (vector-normalize! (vector-! (new-stack-vector0) arg2 arg1) 1.0))
|
||||
(s4-1 (vector-! (new-stack-vector0) arg0 arg1))
|
||||
(f0-1 (vector-dot a1-3 s4-1))
|
||||
@@ -235,6 +240,7 @@
|
||||
)
|
||||
|
||||
(defun vector-orient-by-quat! ((arg0 vector) (arg1 vector) (arg2 quaternion))
|
||||
"Rotate a vector by a quaternion."
|
||||
(rlet ((acc :class vf)
|
||||
(vf0 :class vf)
|
||||
(vf1 :class vf)
|
||||
@@ -285,6 +291,7 @@
|
||||
;; consistent and provide orthogonal forward/down, they do the same thing.
|
||||
|
||||
(defun forward-down->inv-matrix ((arg0 matrix) (arg1 vector) (arg2 vector))
|
||||
"Create a matrix representing an inverse transform where arg1 is forward (+z) and arg2 is down (-y). Will have the pitch of forward"
|
||||
(vector-normalize-copy! (-> arg0 vector 2) arg1 1.0)
|
||||
(vector-cross! (the-as vector (-> arg0 vector)) (-> arg0 vector 2) arg2)
|
||||
(vector-normalize! (the-as vector (-> arg0 vector)) 1.0)
|
||||
@@ -299,6 +306,7 @@
|
||||
)
|
||||
|
||||
(defun forward-down-nopitch->inv-matrix ((arg0 matrix) (arg1 vector) (arg2 vector))
|
||||
"Create a matrix representing an inverse transform where arg1 is forward (+z) and arg2 is down (-y). Will not use the pitch of forward"
|
||||
(vector-normalize-copy! (-> arg0 vector 1) arg2 1.0)
|
||||
(vector-negate! (-> arg0 vector 1) (-> arg0 vector 1))
|
||||
(vector-cross! (the-as vector (-> arg0 vector)) (-> arg0 vector 1) arg1)
|
||||
@@ -318,14 +326,17 @@
|
||||
)
|
||||
|
||||
(defun forward-up-nopitch->inv-matrix ((arg0 matrix) (arg1 vector) (arg2 vector))
|
||||
"Create a matrix representing an inverse transform where arg1 is forward (+z) and arg2 is up (+y). Will not use the pitch of forward"
|
||||
(forward-down-nopitch->inv-matrix arg0 arg1 (vector-negate! (new-stack-vector0) arg2))
|
||||
)
|
||||
|
||||
(defun forward-up-nopitch->quaternion ((arg0 quaternion) (arg1 vector) (arg2 vector))
|
||||
"Create a quaternion representing a transform where arg1 is forward (+z) and arg2 is up (+y). Will not use the pitch of forward"
|
||||
(matrix->quaternion arg0 (forward-up-nopitch->inv-matrix (new-stack-matrix0) arg1 arg2))
|
||||
)
|
||||
|
||||
(defun forward-up->quaternion ((arg0 quaternion) (arg1 vector) (arg2 vector))
|
||||
"Create a quaternion representing a transform where arg1 is forward (+z) and arg2 is up (+y). Will use the pitch of forward"
|
||||
(matrix->quaternion arg0
|
||||
(forward-down->inv-matrix
|
||||
(new-stack-matrix0)
|
||||
@@ -336,6 +347,7 @@
|
||||
)
|
||||
|
||||
(defun quaternion-from-two-vectors! ((arg0 quaternion) (arg1 vector) (arg2 vector))
|
||||
"Create a quaternion representing the rotation between two vectors"
|
||||
(let* ((s5-0 (vector-cross! (new-stack-vector0) arg1 arg2))
|
||||
(f0-0 (vector-length s5-0))
|
||||
(f1-1 (vector-dot arg1 arg2))
|
||||
@@ -351,6 +363,7 @@
|
||||
)
|
||||
|
||||
(defun quaternion-from-two-vectors-max-angle! ((arg0 quaternion) (arg1 vector) (arg2 vector) (arg3 float))
|
||||
"Create a quaternion representing the rotation between two vectors, allowing at most a rotation of arg3 degrees"
|
||||
(let* ((s5-0 (vector-cross! (new-stack-vector0) arg1 arg2))
|
||||
(f30-0 (vector-length s5-0))
|
||||
(f26-0 (vector-dot arg1 arg2))
|
||||
@@ -377,6 +390,7 @@
|
||||
)
|
||||
|
||||
(defun matrix-from-two-vectors! ((arg0 matrix) (arg1 vector) (arg2 vector))
|
||||
"Create a rotation matrix representing the rotation between two vectors"
|
||||
(let* ((a1-3 (vector-normalize! (vector-cross! (new-stack-vector0) arg2 arg1) 1.0))
|
||||
(f0-1 (vector-dot arg1 arg2))
|
||||
(f1-0 1.0)
|
||||
@@ -388,6 +402,7 @@
|
||||
)
|
||||
|
||||
(defun matrix-from-two-vectors-max-angle! ((arg0 matrix) (arg1 vector) (arg2 vector) (arg3 float))
|
||||
"Create a rotation matrix representing the rotation between two vectors, allowing at most a rotation of arg3 degrees"
|
||||
(let
|
||||
((s4-1 (vector-normalize! (vector-cross! (new-stack-vector0) arg2 arg1) 1.0))
|
||||
(f30-0 (vector-dot arg1 arg2))
|
||||
@@ -412,7 +427,13 @@
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
;;
|
||||
;; note: these two interpolation functions may be equivalent to slerp.
|
||||
|
||||
(defun matrix-from-two-vectors-max-angle-partial! ((arg0 matrix) (arg1 vector) (arg2 vector) (arg3 float) (arg4 float))
|
||||
"Create a rotation matrix representing the rotation between two vectors, allowing at most a rotation of arg3 degrees,
|
||||
doing arg4 fraction of the rotation."
|
||||
(let* ((s4-1 (vector-normalize! (vector-cross! (new-stack-vector0) arg2 arg1) 1.0))
|
||||
(f28-0 (vector-dot arg1 arg2))
|
||||
(f30-0 (cos arg3))
|
||||
@@ -438,6 +459,7 @@
|
||||
)
|
||||
|
||||
(defun matrix-from-two-vectors-partial-linear! ((arg0 matrix) (arg1 vector) (arg2 vector) (arg3 float))
|
||||
"Create a rotation matrix representing doing arg3 fraction of the rotation between two vectors"
|
||||
(let ((gp-1 (vector-normalize! (vector-cross! (new-stack-vector0) arg2 arg1) 1.0))
|
||||
(f0-1 (vector-dot arg1 arg2))
|
||||
)
|
||||
@@ -460,6 +482,7 @@
|
||||
)
|
||||
|
||||
(defun matrix-remove-z-rot ((arg0 matrix) (arg1 matrix))
|
||||
"Remove the z rotation component of a rotation."
|
||||
(let ((s4-0 (new-stack-vector0)))
|
||||
0.0
|
||||
0.0
|
||||
@@ -485,6 +508,7 @@
|
||||
)
|
||||
|
||||
(defun matrix-rot-diff! ((arg0 vector) (arg1 matrix) (arg2 matrix))
|
||||
"Get the difference of rotation between two matrices, expressed as a quaternion."
|
||||
(let ((s3-0 (new-stack-quaternion0))
|
||||
(s2-0 (new-stack-quaternion0))
|
||||
(s5-0 (new-stack-quaternion0))
|
||||
@@ -511,6 +535,7 @@
|
||||
|
||||
|
||||
(defun quaternion-seek ((arg0 quaternion) (arg1 quaternion) (arg2 quaternion) (arg3 float) (arg4 float))
|
||||
"Strange quaternion rotate toward function. Arg3 is ignored. Arg4 is the max seek amount."
|
||||
(let ((s5-0 (new-stack-matrix0))
|
||||
(s4-0 (new-stack-matrix0))
|
||||
)
|
||||
@@ -529,6 +554,7 @@
|
||||
)
|
||||
|
||||
(defun vector-deg-seek ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float))
|
||||
"Make one vector closer to another, doing at most a rotation by arg3 degrees."
|
||||
(let ((s4-0 (new-stack-matrix0)))
|
||||
(matrix-from-two-vectors-max-angle! s4-0 arg1 arg2 arg3)
|
||||
(vector-matrix*! arg0 arg1 s4-0)
|
||||
@@ -536,6 +562,7 @@
|
||||
)
|
||||
|
||||
(defun vector-deg-slerp ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float))
|
||||
"Slerp for vectors. (imagine that they are the z axis of two frames)"
|
||||
(cond
|
||||
((>= 0.0 arg3)
|
||||
(set! (-> arg0 quad) (-> arg1 quad))
|
||||
@@ -560,6 +587,7 @@
|
||||
)
|
||||
|
||||
(defun vector-vector-deg-slerp! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float) (arg4 vector))
|
||||
"unused. no clue what this does."
|
||||
(local-vars (sv-112 (function float float float float)))
|
||||
(cond
|
||||
((>= 0.0 arg3)
|
||||
@@ -592,6 +620,7 @@
|
||||
)
|
||||
|
||||
(defun normal-of-plane ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 vector))
|
||||
"Given three points on a plane, compute the plane's normal"
|
||||
(rlet ((acc :class vf)
|
||||
(Q :class vf)
|
||||
(vf0 :class vf)
|
||||
@@ -624,6 +653,7 @@
|
||||
)
|
||||
|
||||
(defun vector-3pt-cross! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 vector))
|
||||
"Cross product of 2 - 1 and 3 - 1. (will give a normal to the plane, but not of magnitude 1)"
|
||||
(rlet ((acc :class vf)
|
||||
(vf0 :class vf)
|
||||
(vf1 :class vf)
|
||||
@@ -646,7 +676,7 @@
|
||||
)
|
||||
|
||||
(defun closest-pt-in-triangle ((arg0 vector) (arg1 vector) (arg2 matrix) (arg3 vector))
|
||||
"arg2 is probably the triangle"
|
||||
"arg2 is the vertices of the triangle, arg3 is the normal, arg1 is the input point, arg0 is the output."
|
||||
;; (declare (print-asm))
|
||||
(local-vars
|
||||
(v1-0 uint)
|
||||
@@ -832,6 +862,7 @@
|
||||
)
|
||||
|
||||
(defun point-in-triangle-cross ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 vector) (arg4 vector))
|
||||
"Check if point is in the triangle using cross product check (so you have to get the order of points right)"
|
||||
(local-vars (v1-0 int) (a0-1 int) (a1-1 int))
|
||||
(rlet ((acc :class vf)
|
||||
(vf1 :class vf)
|
||||
@@ -881,6 +912,7 @@
|
||||
)
|
||||
|
||||
(defun point-in-plane-<-point+normal! ((arg0 vector) (arg1 vector) (arg2 vector))
|
||||
"This function looks wrong and is unused."
|
||||
(let
|
||||
((f0-3
|
||||
(+
|
||||
@@ -1039,6 +1071,15 @@
|
||||
(none)
|
||||
)
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;
|
||||
;; curve
|
||||
;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; the curves take a floating point input and produce a floating point output.
|
||||
;; the curve is a piecewise polynomial. The first step of evaluation is to figure out which
|
||||
;; knots the input point lies in between. The second step is to evaluate the appropriate polynomial.
|
||||
|
||||
(defun find-knot-span ((arg0 int) (arg1 int) (arg2 float) (arg3 (inline-array vector)))
|
||||
"Binary serach over knots to find which contains the value float in (arg0 arg1). Unused."
|
||||
(local-vars (v0-0 int))
|
||||
@@ -1092,6 +1133,7 @@
|
||||
)
|
||||
|
||||
(defun calculate-basis-functions-vector! ((arg0 (pointer float)) (arg1 int) (arg2 float) (arg3 (pointer float)))
|
||||
"Calculate polynomial basis for a given control point."
|
||||
(local-vars (v1-0 int) (v1-1 object))
|
||||
;;(.sll v1-0 arg1 2)
|
||||
(set! v1-0 (* 4 arg1)) ;; originally used 32-bit asm
|
||||
@@ -1151,6 +1193,14 @@
|
||||
)
|
||||
|
||||
(defun curve-evaluate! ((arg0 vector) (arg1 float) (arg2 pointer) (arg3 int) (arg4 (inline-array vector)) (arg5 int))
|
||||
"Evaluate a curve.
|
||||
arg0 is the output
|
||||
arg1 is the input.
|
||||
arg2 is control vertices
|
||||
arg3 is the number of control vertices
|
||||
arg4 is the knot points
|
||||
arg5 is the number of knots
|
||||
"
|
||||
(local-vars (v1-7 int) (v1-8 int) (v1-10 float) (s3-0 int))
|
||||
(rlet ((acc :class vf)
|
||||
(vf0 :class vf)
|
||||
@@ -1164,6 +1214,7 @@
|
||||
(init-vf0-vector)
|
||||
(let ((s4-0 (new 'static 'array float 4 0.0 0.0 0.0 0.0)))
|
||||
0
|
||||
;; lookup knot
|
||||
(let* ((f0-0 (-> arg4 0 x))
|
||||
(f1-0 (-> (&-> arg4 0 data (+ arg5 -1)) 0))
|
||||
(a2-1 (fmax (fmin (* arg1 f1-0) f1-0) f0-0))
|
||||
@@ -1211,6 +1262,7 @@
|
||||
(nop!)
|
||||
(nop!)
|
||||
(label cfg-11)
|
||||
;; calculate coefficients for this knot's polynomial, store in s4-0
|
||||
(calculate-basis-functions-vector!
|
||||
s4-0
|
||||
s3-0
|
||||
@@ -1222,6 +1274,7 @@
|
||||
(set! v1-7 (- s3-0 3))
|
||||
(.lvf vf6 s4-0)
|
||||
)
|
||||
;; evaluate polynomial!
|
||||
;;(.sll v1-8 v1-7 4)
|
||||
(set! v1-8 (* v1-7 16))
|
||||
(.add.x.vf vf1 vf0 vf0 :mask #b1000)
|
||||
@@ -1258,6 +1311,7 @@
|
||||
)
|
||||
|
||||
(defun curve-get-pos! ((arg0 vector) (arg1 float) (arg2 curve))
|
||||
"Get the position on the curve at the given input."
|
||||
(curve-evaluate!
|
||||
arg0
|
||||
arg1
|
||||
@@ -1269,6 +1323,7 @@
|
||||
)
|
||||
|
||||
(defun curve-length ((arg0 curve))
|
||||
"Compute the approximate curve length as the sum of distances between knots."
|
||||
(let ((s5-0 (new-stack-vector0))
|
||||
(s4-0 (new-stack-vector0))
|
||||
(s3-0 (* 3 (-> arg0 num-cverts)))
|
||||
@@ -1299,6 +1354,7 @@
|
||||
)
|
||||
|
||||
(defun curve-copy! ((arg0 curve) (arg1 curve))
|
||||
"Shallow copy a curve."
|
||||
(set! (-> arg0 cverts) (-> arg1 cverts))
|
||||
(set! (-> arg0 num-cverts) (-> arg1 num-cverts))
|
||||
(set! (-> arg0 knots) (-> arg1 knots))
|
||||
@@ -1308,6 +1364,7 @@
|
||||
)
|
||||
|
||||
(defun curve-closest-point ((arg0 curve) (arg1 vector) (arg2 float) (arg3 float) (arg4 int) (arg5 float))
|
||||
"Get the input value for the point on the curve. Approximate! And is O(n_knots)"
|
||||
(local-vars (sv-48 float))
|
||||
(set! sv-48 arg3)
|
||||
(let ((s3-0 arg4)
|
||||
@@ -1369,6 +1426,7 @@
|
||||
)
|
||||
|
||||
(defun vector-plane-distance ((arg0 vector) (arg1 plane) (arg2 vector))
|
||||
"Unused."
|
||||
(vector-dot
|
||||
(vector-! (new 'stack-no-clear 'vector) arg0 (the-as vector (&-> arg1 x)))
|
||||
arg2
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
;; name in dgo: decomp-h
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
;; temporary storage for visibility data decompression.
|
||||
;; this is stored on the scratchpad.
|
||||
(deftype decomp-work (structure)
|
||||
((buffer0 uint8 2048 :offset-assert 0)
|
||||
(buffer1 uint8 2048 :offset-assert 2048)
|
||||
|
||||
@@ -96,6 +96,7 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; font settings that can be passed to draw-string
|
||||
(deftype font-context (basic)
|
||||
((origin vector :inline :offset-assert 16)
|
||||
(strip-gif vector :inline :offset-assert 32)
|
||||
@@ -258,6 +259,7 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; Data used by the font-renderer.
|
||||
(deftype font-work (structure)
|
||||
((font-tmpl dma-gif-packet :inline :offset-assert 0)
|
||||
(char-tmpl dma-gif-packet :inline :offset-assert 32)
|
||||
|
||||
@@ -13,12 +13,15 @@
|
||||
;; for some reason, the display also tracks some timing stuff.
|
||||
|
||||
(defun get-current-time ()
|
||||
"Possibly the wall-clock time"
|
||||
"Get the in game time. This advances when the game is unpaused.
|
||||
This increase at the same rate for PAL/NTSC and if the game is lagging."
|
||||
(-> *display* base-frame-counter)
|
||||
)
|
||||
|
||||
(defun get-integral-current-time ()
|
||||
"The integral of game frame time (this slows down as we lag)"
|
||||
"Get the game time as a number of frames. This advances at different rates for PAL/NTSC.
|
||||
This counts the number of actual vsyncs done by the PS2, including ones that are missed due to lag.
|
||||
"
|
||||
(-> *display* integral-frame-counter)
|
||||
)
|
||||
|
||||
@@ -250,7 +253,7 @@
|
||||
)
|
||||
|
||||
(defun set-display2 ((disp display) (psm int) (w int) (h int) (ztest int) (zpsm int))
|
||||
"Set the display and draw envs only. This assumes you have already done a set-display."
|
||||
"Set the display and draw envs only. This assumes you have already done a set-display and you just need to update the video mode."
|
||||
(set-display-env (-> disp display-env0) psm w h (-> *video-parms* display-dx) (-> *video-parms* display-dy) 320)
|
||||
(set-display-env (-> disp display-env1) psm w h (-> *video-parms* display-dx) (-> *video-parms* display-dy) 384)
|
||||
(set-draw-env (-> disp draw0) psm w h ztest zpsm 384)
|
||||
@@ -262,10 +265,14 @@
|
||||
(defun allocate-dma-buffers ((arg0 display))
|
||||
"Allocate the main DMA buffers!"
|
||||
(when (zero? (-> arg0 frames 0 frame calc-buf))
|
||||
;; not sure what these "calc-buf"s are. Maybe VU0 DMA or other small stuff that is used in the same frame?
|
||||
;; allocate a small calc-buf for each frame.
|
||||
;; these smaller buffers are used by the engine to patch buckets and get sent directly to VU1.
|
||||
(set! (-> arg0 frames 0 frame calc-buf) (new 'global 'dma-buffer 10000))
|
||||
(set! (-> arg0 frames 1 frame calc-buf) (new 'global 'dma-buffer 10000))
|
||||
;; the main DMA buffers for each frame's drawing.
|
||||
|
||||
;; the main DMA buffers for each frame's drawing. The buckets in the calc buf will reference data in here.
|
||||
;; the individual renderers use these buffers.
|
||||
;; the reason for separate calc/global buf is unknown.
|
||||
(set! (-> arg0 frames 0 frame global-buf) (new 'global 'dma-buffer #x1ac000))
|
||||
(set! (-> arg0 frames 1 frame global-buf) (new 'global 'dma-buffer #x1ac000))
|
||||
|
||||
@@ -279,12 +286,13 @@
|
||||
arg0
|
||||
)
|
||||
|
||||
|
||||
;; set up the main font contexts.
|
||||
;; used for debug prints
|
||||
(define *font-context* (new 'global 'font-context *font-default-matrix* 0 24 0.0 (font-color default) (font-flags shadow kerning)))
|
||||
|
||||
;; not used, but looks like it would work for the "PAUSE" text.
|
||||
(define *pause-context* (new 'global 'font-context *font-default-matrix* 256 170 0.0 (font-color orange-red) (font-flags shadow kerning)))
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; PROFILE BAR
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
|
||||
;; The game is interlaced, meaning each framebuffer is half height.
|
||||
|
||||
;; There are two
|
||||
|
||||
(deftype video-parms (structure)
|
||||
((set-video-mode basic :offset-assert 0)
|
||||
(reset-video-mode basic :offset-assert 4)
|
||||
|
||||
@@ -60,10 +60,10 @@
|
||||
|
||||
;; a dma "sink" is somewhere where a renderer can put stuff.
|
||||
(deftype dma-foreground-sink (basic)
|
||||
((bucket bucket-id :offset-assert 4)
|
||||
(foreground-texture-page int8 :offset-assert 8) ;; ?
|
||||
(foreground-texture-level int8 :offset-assert 9) ;; ?
|
||||
(foreground-output-bucket int8 :offset-assert 10) ;; ?
|
||||
((bucket bucket-id :offset-assert 4) ;; the DMA bucket
|
||||
(foreground-texture-page int8 :offset-assert 8) ;; the tpage we need (in the level)
|
||||
(foreground-texture-level int8 :offset-assert 9) ;; the level we belong to
|
||||
(foreground-output-bucket int8 :offset-assert 10) ;; ?
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #xb
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
;; There are a lot more details, see texture.gc for more info
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Texture Control
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -156,7 +155,7 @@
|
||||
)
|
||||
|
||||
(defun texture-mip->segment ((arg0 int) (arg1 int))
|
||||
"Unknown, not used."
|
||||
"Convert a mip level to the segment that it is stored in."
|
||||
(if (>= 2 arg1) (+ (- -1 arg0) arg1) (max 0 (- 2 arg0)))
|
||||
)
|
||||
|
||||
@@ -172,6 +171,8 @@
|
||||
(size uint32 :offset-assert 24) ;; VRAM words
|
||||
(segment texture-page-segment 3 :inline :offset-assert 28)
|
||||
(pad uint32 16 :offset-assert 64)
|
||||
|
||||
;; array of texture descriptions.
|
||||
(data texture :dynamic :offset-assert 128)
|
||||
)
|
||||
:method-count-assert 15
|
||||
@@ -197,7 +198,8 @@
|
||||
;; There is a linked-list of these per texture that uses the shader-ptr type below
|
||||
|
||||
;; A shader-ptr is a reference to an adgif shader.
|
||||
;; The trick here is that it can fit into unused space in the GS packet.
|
||||
;; The trick here is that it can fit into unused space in the GS packet, allowing each
|
||||
;; adgif shader to be part of a linked list of adgif shaders for their texture-page.
|
||||
;; the A+D format only uses bits 0-72, this fits in 72-96. The use of 96-128 is unknown
|
||||
;; the shader value must be multiplied by 16 first.
|
||||
(deftype shader-ptr (uint32)
|
||||
|
||||
@@ -5,37 +5,64 @@
|
||||
;; name in dgo: level-h
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
;; The level system is responsible for loading and managning the two levels.
|
||||
;; The level system is responsible for loading and managning the two levels,
|
||||
;; including the visible data.
|
||||
|
||||
;; The "level" type contains runtime information about a level (possibly one that is loading)
|
||||
;; and the "level-group" type contains two levels.
|
||||
|
||||
(defconstant LEVEL_COUNT 2) ;; there are two levels in memory!
|
||||
|
||||
(declare-type bsp-header basic)
|
||||
(declare-type drawable basic)
|
||||
(declare-type engine basic)
|
||||
(declare-type entity-links-array basic)
|
||||
(declare-type entity-ambient-data-array basic)
|
||||
(declare-type mood-context basic)
|
||||
(declare-type entity-links structure)
|
||||
|
||||
;;;;;;;;;;;;;;;
|
||||
;; VIS
|
||||
;;;;;;;;;;;;;;;
|
||||
|
||||
;; each game "level" has some precomputed visibility.
|
||||
;; There's a binary space partition (bsp)
|
||||
;; Each leaf node corresponds to a bit string with (up to) 16384 bits
|
||||
;; These bits tell you if a certain "drawable" is visible or not.
|
||||
;; The drawable's index is the index of its visibilty bit.
|
||||
;; Note that not all drawables have a visibility bit - drawable groups sometimes don't and shrub's don't.
|
||||
|
||||
;; One challenge of the visibility system is that you can't actually load the visibility for two levels
|
||||
;; at the same time. Each level has a large .VIS file that must be loaded.
|
||||
;; The actual level files contain a small amount of VIS file for areas on their borders.
|
||||
;; While the .VIS is loading (or you are on the border of two levels), the engine will look in these
|
||||
;; small visibility infos.
|
||||
|
||||
;; The large .VIS files are stored on the IOP. As a result, there's a small delay to actually
|
||||
;; fetch a visibility string.
|
||||
|
||||
(defenum vis-info-flag
|
||||
:bitfield #t
|
||||
:type uint32
|
||||
(twenty-nine 29) ;; is .VIS file vis?
|
||||
(waiting-for-iop-to-ee 30)
|
||||
(thirty-one 31) ;; single vis?
|
||||
(from-vis-file 29) ;; is .VIS file vis?
|
||||
(waiting-for-iop-to-ee 30) ;; not here yet
|
||||
(using-this-as-only-vis 31) ;; using this as the only visibility data
|
||||
)
|
||||
|
||||
;; Information related to visibility data for a level.
|
||||
;; This is just metadata that describes the actual VIS file.
|
||||
;; This is just metadata that describes the actual visibiltiy data.
|
||||
;; The typical use is to do (-> info vis-string idx) to get the offset (in the .VIS file) of the
|
||||
;; compressed visibility string for a given bsp leaf.
|
||||
|
||||
;; Each level may have multiple level-vis-infos.
|
||||
;; Each .VIS file can have visibility data for multiple levels.
|
||||
;; Each level that is present in a .VIS has a level-vis-info to go with is.
|
||||
;; One level-vis-info (the first) is always for the
|
||||
;; actual level, and there is typically one for each neighboring level.
|
||||
;; actual level (stored in .VIS file), and there is typically one for each neighboring level.
|
||||
;; The final level-vis-info (7) should always be empty (set to 0 in the bsp-header)
|
||||
|
||||
;; When travelling between two levels, the game will only have one .VIS file loaded,
|
||||
;; and it does two lookups in this .VIS file - one for the current level, and one for the nearby
|
||||
;; levels. This means that visibility for "beach" near the border of "village1" is stored in
|
||||
;; both BEA.VIS and VI1.VIS.
|
||||
(declare-type bsp-header basic)
|
||||
(deftype level-vis-info (basic)
|
||||
((level symbol :offset-assert 4)
|
||||
(from-level symbol :offset-assert 8)
|
||||
@@ -63,34 +90,35 @@
|
||||
)
|
||||
|
||||
;; Per level information related to how to load the level.
|
||||
;; These are stored in level-info.gc
|
||||
;; These are stored in level-info.gc which is always loaded, so this should have all the information required
|
||||
;; to do a level load.
|
||||
(deftype level-load-info (basic)
|
||||
((name-list symbol 3 :offset-assert 4)
|
||||
(index int32 :offset-assert 16) ;; the level number (starting with 1?)
|
||||
(index int32 :offset-assert 16) ;; the level number (starting with 1?)
|
||||
(name symbol :offset 4) ;; symbol with full name, like "misty"
|
||||
(visname symbol :offset 8) ;; symbol with vis file name, like "misty-vis"
|
||||
(nickname symbol :offset 12) ;; 3 letter name for DGO, like "mis"
|
||||
(packages pair :offset-assert 20) ;; list of symbols, usually empty or the level name
|
||||
(sound-banks pair :offset-assert 24) ;; require sound bank files (list of symbols)
|
||||
(packages pair :offset-assert 20) ;; list of symbols, usually empty or the level name
|
||||
(sound-banks pair :offset-assert 24) ;; require sound bank files (list of symbols)
|
||||
(music-bank symbol :offset-assert 28) ;; name of level music
|
||||
(ambient-sounds pair :offset-assert 32) ;; always empty list.
|
||||
(ambient-sounds pair :offset-assert 32) ;; always empty list.
|
||||
(mood symbol :offset-assert 36) ;; mood object name
|
||||
(mood-func symbol :offset-assert 40) ;; mood update function name
|
||||
(ocean symbol :offset-assert 44) ;; ocean map object
|
||||
(sky symbol :offset-assert 48) ;; boolean to enable sky
|
||||
(sun-fade float :offset-assert 52) ;; sun/sky setting
|
||||
(continues pair :offset-assert 56) ;; list of checkpoints
|
||||
(tasks pair :offset-assert 60) ;; list of boxed integers for tasks
|
||||
(priority int32 :offset-assert 64) ;; either 100 or 200
|
||||
(load-commands pair :offset-assert 68) ;; ??
|
||||
(alt-load-commands pair :offset-assert 72) ;; ??
|
||||
(bsp-mask uint64 :offset-assert 80) ;; ??
|
||||
(bsphere sphere :offset-assert 88) ;; boundings sphere of level?
|
||||
(buzzer int32 :offset-assert 92) ;; which task is the scout fly?
|
||||
(sun-fade float :offset-assert 52) ;; sun/sky setting
|
||||
(continues pair :offset-assert 56) ;; list of checkpoints
|
||||
(tasks pair :offset-assert 60) ;; list of boxed integers for tasks
|
||||
(priority int32 :offset-assert 64) ;; either 100 or 200
|
||||
(load-commands pair :offset-assert 68) ;; ??
|
||||
(alt-load-commands pair :offset-assert 72) ;; ??
|
||||
(bsp-mask uint64 :offset-assert 80) ;; ??
|
||||
(bsphere sphere :offset-assert 88) ;; boundings sphere of level?
|
||||
(buzzer int32 :offset-assert 92) ;; which task is the scout fly?
|
||||
(bottom-height meters :offset-assert 96)
|
||||
(run-packages pair :offset-assert 100) ;; possibly unused?
|
||||
(prev-level basic :offset-assert 104)
|
||||
(next-level basic :offset-assert 108)
|
||||
(run-packages pair :offset-assert 100) ;; possibly unused?
|
||||
(prev-level basic :offset-assert 104)
|
||||
(next-level basic :offset-assert 108)
|
||||
(wait-for-load symbol :offset-assert 112)
|
||||
)
|
||||
:method-count-assert 9
|
||||
@@ -100,7 +128,6 @@
|
||||
|
||||
;; The levels are initialized (called "login") over multiple frames.
|
||||
;; The state of this process is stored in a login-state.
|
||||
(declare-type drawable basic)
|
||||
(deftype login-state (basic)
|
||||
((state int32 :offset-assert 4)
|
||||
(pos uint32 :offset-assert 8)
|
||||
@@ -112,20 +139,17 @@
|
||||
:flag-assert #x900000050
|
||||
)
|
||||
|
||||
(declare-type engine basic)
|
||||
(declare-type entity-links-array basic)
|
||||
(declare-type entity-ambient-data-array basic)
|
||||
(declare-type mood-context basic)
|
||||
;; The actual "level". This manages loading and running a game level.
|
||||
(deftype level (basic)
|
||||
((name symbol :offset-assert 4)
|
||||
(load-name symbol :offset-assert 8)
|
||||
(nickname symbol :offset-assert 12)
|
||||
(index int32 :offset-assert 16)
|
||||
(status symbol :offset-assert 20)
|
||||
(other level :offset-assert 24)
|
||||
(heap kheap :inline :offset-assert 32)
|
||||
(bsp bsp-header :offset-assert 48)
|
||||
(art-group load-dir-art-group :offset-assert 52)
|
||||
(other level :offset-assert 24) ;; the other level object
|
||||
(heap kheap :inline :offset-assert 32) ;; level's ~10 MB heap
|
||||
(bsp bsp-header :offset-assert 48) ;; the main level object in the DGO
|
||||
(art-group load-dir-art-group :offset-assert 52) ;; the art (foreground models/anims) for the level
|
||||
(info level-load-info :offset-assert 56)
|
||||
(texture-page texture-page 9 :offset-assert 60)
|
||||
(loaded-texture-page texture-page 16 :offset-assert 96)
|
||||
@@ -190,13 +214,11 @@
|
||||
)
|
||||
)
|
||||
|
||||
(declare-type entity-links structure)
|
||||
|
||||
;; Main *level* object.
|
||||
;; There are actually three levels. level0 and level1 correspond to the actual buffered levels
|
||||
;; The level-default seems to be a fake level that can possibly be used by renderers that
|
||||
;; don't belong to any level, for example to render Jak.
|
||||
(declare-type entity-links structure)
|
||||
(deftype level-group (basic)
|
||||
((length int32 :offset-assert 4)
|
||||
(log-in-level-bsp bsp-header :offset-assert 8) ;; level currently logging in
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
;; name in dgo: loader-h
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
;; This is not well-understood yet, but it is definitely related to streaming animation loading,
|
||||
;; and possibly art-group stuff.
|
||||
;; The loader is responsible for managing streaming loads.
|
||||
|
||||
;; note: lower values are more important.
|
||||
;; negative values will preload.
|
||||
@@ -80,6 +79,7 @@
|
||||
)
|
||||
|
||||
;; An external-art-buffer owns some memory for loading files.
|
||||
;; the "external" means it's not part of the level's (or common, always loaded) static data
|
||||
;; status:
|
||||
;; - 'active: file is loaded and art group is linked to level's art group.
|
||||
;; - 'reserved: buffer is reserved for other purpose
|
||||
@@ -145,8 +145,7 @@
|
||||
)
|
||||
|
||||
|
||||
;; A spool-anim tracks the buffers for spooled animations.
|
||||
;; ?? what are the bufs here.
|
||||
;; A spool-anim tracks the buffers holding chunks of a spooled animation.
|
||||
(deftype spool-anim (basic)
|
||||
((name string :offset 16) ;; why?
|
||||
(buf1 external-art-buffer :offset 16) ;; custom
|
||||
@@ -163,7 +162,9 @@
|
||||
:flag-assert #x90000002c
|
||||
)
|
||||
|
||||
;; This is the main controller for the loader.
|
||||
;; This is the main controller for the streaming loader.
|
||||
;; It has two buffers for holding chunks of a spooling animation
|
||||
;; The buffer can also be reused to hold other things.
|
||||
(deftype external-art-control (basic)
|
||||
((buffer external-art-buffer 2 :offset-assert 4) ;; actual data buffers
|
||||
(rec spool-anim 3 :inline :offset-assert 16) ;; things we would consider loading
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
;; just uses the same xyzw and data array as vector.
|
||||
;; the w stores a float that should be an integer that seems to have
|
||||
;; bitfields for... something? Like maybe the order?
|
||||
;; Euler angles are mostly unused
|
||||
(deftype euler-angles (vector)
|
||||
()
|
||||
:method-count-assert 9
|
||||
|
||||
@@ -5,10 +5,7 @@
|
||||
;; name in dgo: math
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
;; contains various math helpers
|
||||
|
||||
|
||||
|
||||
;; various math helpers
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; float utility
|
||||
@@ -285,6 +282,7 @@
|
||||
(set! (-> *random-generator* seed) #x666EDD1E)
|
||||
|
||||
(defmacro sext32-64 (x)
|
||||
"Sign extend a 32-bit value to 64-bits"
|
||||
`(sar (shl ,x 32) 32)
|
||||
)
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
;; A 4x4 matrix, stored in row-major order
|
||||
;; some, but not all, functions assume that a matrix is an affine transform.
|
||||
;; others assume that the rotation has no scale or shear (and that its inverse is its transpose)
|
||||
(deftype matrix (structure)
|
||||
((vector vector 4 :inline :offset-assert 0)
|
||||
(quad uint128 4 :offset 0)
|
||||
@@ -22,6 +24,7 @@
|
||||
;; A 3x3 matrix, stored in row-major order.
|
||||
;; NOTE: the rows each have an extra 4-bytes of padding
|
||||
;; so this is really a 3x4 matrix.
|
||||
;; this type is rarely used
|
||||
(deftype matrix3 (structure)
|
||||
((data float 12 :offset-assert 0)
|
||||
(vector vector 3 :inline :offset 0)
|
||||
@@ -32,7 +35,11 @@
|
||||
:flag-assert #x900000030
|
||||
)
|
||||
|
||||
;; guess on signs here
|
||||
;; a matrix stored using 16-bit integers.
|
||||
;; note that these usually have different scaling for the 4th row which
|
||||
;; contains the translation in an affine transform.
|
||||
;; so you generally should not unpack these to floats without knowing where they came from
|
||||
;; and how they were originally packed (for example, in tie/shrub)
|
||||
(deftype matrix4h (structure)
|
||||
((data int16 16 :offset-assert 0)
|
||||
(vector4h vector4h 4 :inline :offset 0)
|
||||
|
||||
+57
-214
@@ -25,6 +25,9 @@
|
||||
|
||||
;; which is probably the transpose of what you're used to.
|
||||
|
||||
;; note that they also used row-major storage, so the 3rd qword of a matrix is the translation
|
||||
;; part of the affine transform.
|
||||
|
||||
;; In general, be careful with using these functions as they often have strange
|
||||
;; requirements for the form of the input matrix or if the input/output matrix are
|
||||
;; allowed to be the same memory.
|
||||
@@ -315,12 +318,8 @@
|
||||
(vf5 :class vf)
|
||||
)
|
||||
;; this implementation is better than vector-matrix*!
|
||||
;; (nop!)
|
||||
;; (nop!)
|
||||
(.lvf vf5 (&-> vec quad))
|
||||
;; (nop!)
|
||||
(.lvf vf1 (&-> mat vector 0 quad))
|
||||
;; (nop!)
|
||||
(.lvf vf2 (&-> mat vector 1 quad))
|
||||
;; the mul's assume the right-most column of the input matrix are 0,0,0,X
|
||||
(.mul.x.vf acc vf1 vf5)
|
||||
@@ -329,8 +328,6 @@
|
||||
;; this load doesn't need to be here!
|
||||
(.lvf vf4 (&-> mat vector 3 quad))
|
||||
(.add.mul.z.vf vf5 vf3 vf5 acc)
|
||||
;; (nop!)
|
||||
;; (nop!)
|
||||
(.svf (&-> dst quad) vf5)
|
||||
dst
|
||||
)
|
||||
@@ -374,12 +371,8 @@
|
||||
(a3-2 uint128)
|
||||
(t0-1 uint128)
|
||||
)
|
||||
;; (nop!)
|
||||
;; (nop!)
|
||||
(let ((t0-0 (-> src vector 0 quad)))
|
||||
;; (nop!)
|
||||
(let ((t1-0 (-> src vector 1 quad)))
|
||||
;; (nop!)
|
||||
(let ((a2-0 (-> src vector 2 quad)))
|
||||
(.pextlw v1-0 t1-0 t0-0)
|
||||
(let ((a3-0 (-> src vector 3 quad)))
|
||||
@@ -402,7 +395,6 @@
|
||||
(set! (-> dst vector 1 quad) v1-1)
|
||||
(.pcpyud v1-2 a1-1 a2-1)
|
||||
(set! (-> dst vector 2 quad) a3-2)
|
||||
;; (nop!)
|
||||
(set! (-> dst vector 3 quad) v1-2)
|
||||
dst
|
||||
)
|
||||
@@ -508,119 +500,66 @@
|
||||
(.xor.vf vf19 vf19 vf19)
|
||||
|
||||
(init-vf0-vector)
|
||||
;; (nop!)
|
||||
;; (nop!)
|
||||
(.lvf vf23 (&-> src vector 0 quad))
|
||||
;; (nop!)
|
||||
(.lvf vf24 (&-> src vector 1 quad))
|
||||
;; (nop!)
|
||||
(.lvf vf25 (&-> src vector 2 quad))
|
||||
;; (nop!)
|
||||
(.lvf vf1 (&-> src vector 3 quad))
|
||||
(.mul.x.vf vf7 vf24 vf23)
|
||||
;; (nop!)
|
||||
(.mul.y.vf vf8 vf24 vf23)
|
||||
;; (nop!)
|
||||
(.mul.z.vf vf9 vf24 vf23)
|
||||
;; (nop!)
|
||||
(.mul.x.vf vf10 vf25 vf23)
|
||||
;; (nop!)
|
||||
(.mul.y.vf vf11 vf25 vf23)
|
||||
;; (nop!)
|
||||
(.mul.z.vf vf12 vf25 vf23)
|
||||
;; (nop!)
|
||||
(.mul.x.vf vf13 vf25 vf24)
|
||||
;; (nop!)
|
||||
(.mul.y.vf vf14 vf25 vf24)
|
||||
;; (nop!)
|
||||
(.mul.z.vf vf15 vf25 vf24)
|
||||
;; (nop!)
|
||||
(.mul.z.vf vf26 vf7 vf25 :mask #b10)
|
||||
;; (nop!)
|
||||
(.mul.z.vf vf27 vf11 vf24 :mask #b1)
|
||||
;; (nop!)
|
||||
(.mul.y.vf vf28 vf9 vf25 :mask #b1)
|
||||
;; (nop!)
|
||||
(.mul.z.vf vf29 vf14 vf23 :mask #b1)
|
||||
;; (nop!)
|
||||
(.mul.z.vf vf30 vf8 vf25 :mask #b1)
|
||||
;; (nop!)
|
||||
(.mul.y.vf vf31 vf7 vf25 :mask #b100)
|
||||
;; (nop!)
|
||||
(.add.y.vf vf16 vf27 vf26 :mask #b1)
|
||||
;; (nop!)
|
||||
(.sub.vf vf1 vf0 vf1)
|
||||
;; (nop!)
|
||||
(.add.x.vf vf17 vf29 vf30 :mask #b1)
|
||||
;; (nop!)
|
||||
(.sub.z.vf vf18 vf28 vf31 :mask #b1)
|
||||
;; (nop!)
|
||||
(.sub.y.vf vf23 vf14 vf15 :mask #b100)
|
||||
;; (nop!)
|
||||
(.sub.z.vf vf26 vf15 vf13 :mask #b1)
|
||||
;; (nop!)
|
||||
(.sub.x.vf vf29 vf13 vf14 :mask #b10)
|
||||
;; (nop!)
|
||||
(.sub.vf vf19 vf16 vf17 :mask #b1)
|
||||
;; (nop!)
|
||||
(.sub.z.vf vf24 vf12 vf11 :mask #b10)
|
||||
;; (nop!)
|
||||
(.sub.x.vf vf27 vf10 vf12 :mask #b100)
|
||||
;; (nop!)
|
||||
(.sub.y.vf vf30 vf11 vf10 :mask #b1)
|
||||
;; (nop!)
|
||||
(.add.vf vf20 vf19 vf18 :mask #b1)
|
||||
;; (nop!)
|
||||
(.sub.y.vf vf25 vf8 vf9 :mask #b100)
|
||||
;; (nop!)
|
||||
(.sub.z.vf vf28 vf9 vf7 :mask #b1)
|
||||
;; (nop!)
|
||||
(.sub.x.vf vf31 vf7 vf8 :mask #b10)
|
||||
;; (nop!)
|
||||
(.div.vf Q vf0 vf20 :fsf #b11 :ftf #b0)
|
||||
;; (nop!)
|
||||
;;(.sub.w.vf vf3 vf3 vf3 :mask #b1000)
|
||||
(.xor.vf vf3 vf3 vf3)
|
||||
;; (nop!)
|
||||
;;(.sub.w.vf vf4 vf4 vf4 :mask #b1000)
|
||||
(.xor.vf vf4 vf4 vf4)
|
||||
;; (nop!)
|
||||
;;(.sub.w.vf vf5 vf5 vf5 :mask #b1000)
|
||||
(.xor.vf vf5 vf5 vf5)
|
||||
;; (nop!)
|
||||
(.mov.vf vf6 vf0 :mask #b1000)
|
||||
;; (nop!)
|
||||
(.wait.vf)
|
||||
;; (nop!)
|
||||
(.add.vf vf2 vf0 Q :mask #b1)
|
||||
;; (nop!)
|
||||
(.add.x.vf vf2 vf0 vf2 :mask #b111)
|
||||
;; (nop!)
|
||||
(.mul.z.vf vf3 vf2 vf23 :mask #b1)
|
||||
;; (nop!)
|
||||
(.mul.x.vf vf4 vf2 vf26 :mask #b1)
|
||||
;; (nop!)
|
||||
(.mul.y.vf vf5 vf2 vf29 :mask #b1)
|
||||
;; (nop!)
|
||||
(.mul.y.vf vf3 vf2 vf24 :mask #b10)
|
||||
;; (nop!)
|
||||
(.mul.z.vf vf4 vf2 vf27 :mask #b10)
|
||||
;; (nop!)
|
||||
(.mul.x.vf vf5 vf2 vf30 :mask #b10)
|
||||
;; (nop!)
|
||||
(.mul.z.vf vf3 vf2 vf25 :mask #b100)
|
||||
;; (nop!)
|
||||
(.mul.x.vf vf4 vf2 vf28 :mask #b100)
|
||||
;; (nop!)
|
||||
(.mul.y.vf vf5 vf2 vf31 :mask #b100)
|
||||
;; (nop!)
|
||||
(.mul.x.vf acc vf3 vf1)
|
||||
(.svf (&-> dst vector 0 quad) vf3)
|
||||
(.add.mul.y.vf acc vf4 vf1 acc)
|
||||
(.svf (&-> dst vector 1 quad) vf4)
|
||||
(.add.mul.z.vf vf6 vf5 vf1 acc :mask #b111)
|
||||
(.svf (&-> dst vector 2 quad) vf5)
|
||||
;; (nop!)
|
||||
(.svf (&-> dst vector 3 quad) vf6)
|
||||
dst
|
||||
)
|
||||
@@ -1180,81 +1119,33 @@
|
||||
"Compute the inverse of a 3x3 matrix. Not very efficient.
|
||||
Requires src != dst."
|
||||
(let ((f0-0 (matrix-3x3-determinant src)))
|
||||
(set!
|
||||
(-> dst data 0)
|
||||
(/
|
||||
(-
|
||||
(* (-> src data 5) (-> src data 10))
|
||||
(* (-> src data 6) (-> src data 9))
|
||||
)
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 4)
|
||||
(/
|
||||
(-
|
||||
(* (-> src data 6) (-> src data 8))
|
||||
(* (-> src data 4) (-> src data 10))
|
||||
)
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 8)
|
||||
(/
|
||||
(- (* (-> src data 4) (-> src data 9)) (* (-> src data 5) (-> src data 8)))
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 1)
|
||||
(/
|
||||
(-
|
||||
(* (-> src data 9) (-> src data 2))
|
||||
(* (-> src data 10) (-> src data 1))
|
||||
)
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 5)
|
||||
(/
|
||||
(-
|
||||
(* (-> src data 10) (-> src data 0))
|
||||
(* (-> src data 8) (-> src data 2))
|
||||
)
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 9)
|
||||
(/
|
||||
(- (* (-> src data 8) (-> src data 1)) (* (-> src data 9) (-> src data 0)))
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 2)
|
||||
(/
|
||||
(- (* (-> src data 1) (-> src data 6)) (* (-> src data 2) (-> src data 5)))
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 6)
|
||||
(/
|
||||
(- (* (-> src data 2) (-> src data 4)) (* (-> src data 0) (-> src data 6)))
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 10)
|
||||
(/
|
||||
(- (* (-> src data 0) (-> src data 5)) (* (-> src data 1) (-> src data 4)))
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set! (-> dst vector 0 x)
|
||||
(/ (- (* (-> src vector 1 y) (-> src vector 2 z)) (* (-> src vector 1 z) (-> src vector 2 y))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 1 x)
|
||||
(/ (- (* (-> src vector 1 z) (-> src vector 2 x)) (* (-> src vector 1 x) (-> src vector 2 z))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 2 x)
|
||||
(/ (- (* (-> src vector 1 x) (-> src vector 2 y)) (* (-> src vector 1 y) (-> src vector 2 x))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 0 y)
|
||||
(/ (- (* (-> src vector 2 y) (-> src vector 0 z)) (* (-> src vector 2 z) (-> src vector 0 y))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 1 y)
|
||||
(/ (- (* (-> src vector 2 z) (-> src vector 0 x)) (* (-> src vector 2 x) (-> src vector 0 z))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 2 y)
|
||||
(/ (- (* (-> src vector 2 x) (-> src vector 0 y)) (* (-> src vector 2 y) (-> src vector 0 x))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 0 z)
|
||||
(/ (- (* (-> src vector 0 y) (-> src vector 1 z)) (* (-> src vector 0 z) (-> src vector 1 y))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 1 z)
|
||||
(/ (- (* (-> src vector 0 z) (-> src vector 1 x)) (* (-> src vector 0 x) (-> src vector 1 z))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 2 z)
|
||||
(/ (- (* (-> src vector 0 x) (-> src vector 1 y)) (* (-> src vector 0 y) (-> src vector 1 x))) f0-0)
|
||||
)
|
||||
)
|
||||
dst
|
||||
)
|
||||
@@ -1263,81 +1154,33 @@
|
||||
"Invert and transpose.
|
||||
Requires dst != src."
|
||||
(let ((f0-0 (matrix-3x3-determinant src)))
|
||||
(set!
|
||||
(-> dst data 0)
|
||||
(/
|
||||
(-
|
||||
(* (-> src data 5) (-> src data 10))
|
||||
(* (-> src data 6) (-> src data 9))
|
||||
)
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 1)
|
||||
(/
|
||||
(-
|
||||
(* (-> src data 6) (-> src data 8))
|
||||
(* (-> src data 4) (-> src data 10))
|
||||
)
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 2)
|
||||
(/
|
||||
(- (* (-> src data 4) (-> src data 9)) (* (-> src data 5) (-> src data 8)))
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 4)
|
||||
(/
|
||||
(-
|
||||
(* (-> src data 9) (-> src data 2))
|
||||
(* (-> src data 10) (-> src data 1))
|
||||
)
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 5)
|
||||
(/
|
||||
(-
|
||||
(* (-> src data 10) (-> src data 0))
|
||||
(* (-> src data 8) (-> src data 2))
|
||||
)
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 6)
|
||||
(/
|
||||
(- (* (-> src data 8) (-> src data 1)) (* (-> src data 9) (-> src data 0)))
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 8)
|
||||
(/
|
||||
(- (* (-> src data 1) (-> src data 6)) (* (-> src data 2) (-> src data 5)))
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 9)
|
||||
(/
|
||||
(- (* (-> src data 2) (-> src data 4)) (* (-> src data 0) (-> src data 6)))
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> dst data 10)
|
||||
(/
|
||||
(- (* (-> src data 0) (-> src data 5)) (* (-> src data 1) (-> src data 4)))
|
||||
f0-0
|
||||
)
|
||||
)
|
||||
(set! (-> dst vector 0 x)
|
||||
(/ (- (* (-> src vector 1 y) (-> src vector 2 z)) (* (-> src vector 1 z) (-> src vector 2 y))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 0 y)
|
||||
(/ (- (* (-> src vector 1 z) (-> src vector 2 x)) (* (-> src vector 1 x) (-> src vector 2 z))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 0 z)
|
||||
(/ (- (* (-> src vector 1 x) (-> src vector 2 y)) (* (-> src vector 1 y) (-> src vector 2 x))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 1 x)
|
||||
(/ (- (* (-> src vector 2 y) (-> src vector 0 z)) (* (-> src vector 2 z) (-> src vector 0 y))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 1 y)
|
||||
(/ (- (* (-> src vector 2 z) (-> src vector 0 x)) (* (-> src vector 2 x) (-> src vector 0 z))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 1 z)
|
||||
(/ (- (* (-> src vector 2 x) (-> src vector 0 y)) (* (-> src vector 2 y) (-> src vector 0 x))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 2 x)
|
||||
(/ (- (* (-> src vector 0 y) (-> src vector 1 z)) (* (-> src vector 0 z) (-> src vector 1 y))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 2 y)
|
||||
(/ (- (* (-> src vector 0 z) (-> src vector 1 x)) (* (-> src vector 0 x) (-> src vector 1 z))) f0-0)
|
||||
)
|
||||
(set! (-> dst vector 2 z)
|
||||
(/ (- (* (-> src vector 0 x) (-> src vector 1 y)) (* (-> src vector 0 y) (-> src vector 1 x))) f0-0)
|
||||
)
|
||||
)
|
||||
dst
|
||||
)
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
;; name in dgo: quaternion-h
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
;; general quaternion type used to represent an orientation in a way that's compact (4 floats),
|
||||
;; avoids singularities of euler angles, and reasonably efficient to transform.
|
||||
;; the w component is stored last.
|
||||
(deftype quaternion (structure)
|
||||
((x float :offset-assert 0)
|
||||
(y float :offset-assert 4)
|
||||
|
||||
@@ -447,156 +447,80 @@
|
||||
)
|
||||
|
||||
(defun matrix->quaternion ((arg0 quaternion) (arg1 matrix))
|
||||
(let ((f0-2 (+ (+ (-> arg1 data 0) (-> arg1 data 5)) (-> arg1 data 10))))
|
||||
(if (< 0.0 f0-2)
|
||||
(let ((f0-4 (sqrtf (+ 1.0 f0-2))))
|
||||
(set! (-> arg0 w) (* 0.5 f0-4))
|
||||
(let ((f0-5 (/ 0.5 f0-4)))
|
||||
(set! (-> arg0 x) (* f0-5 (- (-> arg1 data 6) (-> arg1 data 9))))
|
||||
(set! (-> arg0 y) (* f0-5 (- (-> arg1 data 8) (-> arg1 data 2))))
|
||||
(let ((f0-6 (* f0-5 (- (-> arg1 data 1) (-> arg1 data 4)))))
|
||||
(set! (-> arg0 z) f0-6)
|
||||
(let ((v1-0 f0-6))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
"Convert a rotation matrix to a quaternion."
|
||||
(let ((f0-2 (+ (-> arg1 vector 0 x) (-> arg1 vector 1 y) (-> arg1 vector 2 z))))
|
||||
(cond
|
||||
((< 0.0 f0-2)
|
||||
(let ((f0-4 (sqrtf (+ 1.0 f0-2))))
|
||||
(set! (-> arg0 w) (* 0.5 f0-4))
|
||||
(let ((f0-5 (/ 0.5 f0-4)))
|
||||
(set! (-> arg0 x) (* f0-5 (- (-> arg1 vector 1 z) (-> arg1 vector 2 y))))
|
||||
(set! (-> arg0 y) (* f0-5 (- (-> arg1 vector 2 x) (-> arg1 vector 0 z))))
|
||||
(set! (-> arg0 z) (* f0-5 (- (-> arg1 vector 0 y) (-> arg1 vector 1 x))))
|
||||
)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(let ((a2-0 0)
|
||||
(a3-0 1)
|
||||
(v1-1 2)
|
||||
)
|
||||
(when (< (-> arg1 data 0) (-> arg1 data 5))
|
||||
(when (< (-> arg1 vector 0 x) (-> arg1 vector 1 y))
|
||||
(set! a2-0 1)
|
||||
(set! a3-0 2)
|
||||
(set! v1-1 0)
|
||||
(let ((t0-1 v1-1))
|
||||
)
|
||||
)
|
||||
(when
|
||||
(<
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a2-0 2) (shl a2-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
(-> arg1 data 10)
|
||||
)
|
||||
(when (< (-> (the-as (pointer float) (+ (+ (* a2-0 4) (* a2-0 16)) (the-as int arg1)))) (-> arg1 vector 2 z))
|
||||
(set! a2-0 2)
|
||||
(set! a3-0 0)
|
||||
(set! v1-1 1)
|
||||
(let ((t0-6 v1-1))
|
||||
)
|
||||
)
|
||||
(let
|
||||
((f0-12
|
||||
(sqrtf
|
||||
(+
|
||||
(-
|
||||
1.0
|
||||
(+
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a3-0 2) (shl a3-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl v1-1 2) (shl v1-1 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
(let ((f0-12
|
||||
(sqrtf
|
||||
(+ (- 1.0
|
||||
(+ (-> (the-as (pointer float) (+ (+ (* a3-0 4) (* a3-0 16)) (the-as int arg1))))
|
||||
(-> (the-as (pointer float) (+ (+ (* v1-1 4) (* v1-1 16)) (the-as int arg1))))
|
||||
)
|
||||
)
|
||||
(-> (the-as (pointer float) (+ (+ (* a2-0 4) (* a2-0 16)) (the-as int arg1))))
|
||||
)
|
||||
)
|
||||
)
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a2-0 2) (shl a2-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 data a2-0) (* 0.5 f0-12))
|
||||
(when (!= f0-12 0.0)
|
||||
(set! f0-12 (/ 0.5 f0-12))
|
||||
(let ((t0-19 f0-12))
|
||||
(if (!= f0-12 0.0)
|
||||
(set! f0-12 (/ 0.5 f0-12))
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> arg0 w)
|
||||
(*
|
||||
(-
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl v1-1 2) (shl a3-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a3-0 2) (shl v1-1 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
f0-12
|
||||
)
|
||||
)
|
||||
(set!
|
||||
(-> arg0 data a3-0)
|
||||
(*
|
||||
(+
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a3-0 2) (shl a2-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a2-0 2) (shl a3-0 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
)
|
||||
f0-12
|
||||
)
|
||||
)
|
||||
(let
|
||||
((f0-13
|
||||
(*
|
||||
(+
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl v1-1 2) (shl a2-0 4)) (the-as int arg1))
|
||||
)
|
||||
(set! (-> arg0 w)
|
||||
(* (- (-> (the-as (pointer float) (+ (+ (* v1-1 4) (* a3-0 16)) (the-as int arg1))))
|
||||
(-> (the-as (pointer float) (+ (+ (* a3-0 4) (* v1-1 16)) (the-as int arg1))))
|
||||
)
|
||||
f0-12
|
||||
)
|
||||
(->
|
||||
(the-as
|
||||
(pointer float)
|
||||
(+ (+ (shl a2-0 2) (shl v1-1 4)) (the-as int arg1))
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 data a3-0)
|
||||
(* (+ (-> (the-as (pointer float) (+ (+ (* a3-0 4) (* a2-0 16)) (the-as int arg1))))
|
||||
(-> (the-as (pointer float) (+ (+ (* a2-0 4) (* a3-0 16)) (the-as int arg1))))
|
||||
)
|
||||
f0-12
|
||||
)
|
||||
)
|
||||
f0-12
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 data v1-1) f0-13)
|
||||
(let ((v1-4 f0-13))
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> arg0 data v1-1)
|
||||
(* (+ (-> (the-as (pointer float) (+ (+ (* v1-1 4) (* a2-0 16)) (the-as int arg1))))
|
||||
(-> (the-as (pointer float) (+ (+ (* a2-0 4) (* v1-1 16)) (the-as int arg1))))
|
||||
)
|
||||
f0-12
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
arg0
|
||||
)
|
||||
|
||||
|
||||
(defun matrix-with-scale->quaternion ((arg0 quaternion) (arg1 matrix))
|
||||
"Convert a matrix with a rotation and scale into a quaternion (just the rotation)"
|
||||
(rlet ((vf1 :class vf)
|
||||
@@ -686,6 +610,7 @@
|
||||
)
|
||||
|
||||
(defun quaternion-exp! ((arg0 quaternion) (arg1 quaternion))
|
||||
"Quaternion exponentiation. Unused"
|
||||
(let ((f30-0 (vector-length (the-as vector arg1))))
|
||||
(cond
|
||||
((= f30-0 0.0)
|
||||
@@ -827,6 +752,7 @@
|
||||
)
|
||||
|
||||
(defun quaternion-zxy! ((arg0 quaternion) (arg1 vector))
|
||||
"Make a quaternion from a sequence of z, x, y axis rotations."
|
||||
(rlet ((acc :class vf)
|
||||
(vf0 :class vf)
|
||||
(vf1 :class vf)
|
||||
@@ -893,7 +819,7 @@
|
||||
)
|
||||
|
||||
(defun quaternion-y-angle ((arg0 quaternion))
|
||||
"Not 100% sure, but get the y rotation angle?"
|
||||
"Get the y rotation angle. Not very efficient"
|
||||
(let ((v1-1 (vector-z-quaternion! (new 'stack-no-clear 'vector) arg0)))
|
||||
(atan (-> v1-1 data 0) (-> v1-1 data 2))
|
||||
)
|
||||
@@ -988,6 +914,7 @@
|
||||
)
|
||||
|
||||
(defun quaternion-delta-y ((arg0 quaternion) (arg1 quaternion))
|
||||
"Difference in yaw between two quaternions"
|
||||
(acos (vector-dot (vector-z-quaternion! (new 'stack-no-clear 'vector) arg0)
|
||||
(vector-z-quaternion! (new 'stack-no-clear 'vector) arg1)
|
||||
)
|
||||
@@ -995,6 +922,7 @@
|
||||
)
|
||||
|
||||
(defun quaternion-rotate-y-to-vector! ((arg0 quaternion) (arg1 quaternion) (arg2 quaternion) (arg3 float))
|
||||
"Rotate along y so z-axis points to match another. Use arg3 as the max rotation amount."
|
||||
(let ((s5-0 (new 'stack-no-clear 'quaternion)))
|
||||
(let ((t9-0 vector-xz-normalize!)
|
||||
(a0-1 (new 'stack-no-clear 'vector))
|
||||
@@ -1018,6 +946,7 @@
|
||||
|
||||
|
||||
(defun vector-rotate-y! ((arg0 vector) (arg1 vector) (arg2 float))
|
||||
"Rotate vector along y axis. Not very efficient."
|
||||
(let ((a1-2 (quaternion-vector-angle!
|
||||
(new 'stack-no-clear 'quaternion)
|
||||
(new 'static 'vector :y 1.0 :w 1.0)
|
||||
@@ -1031,15 +960,22 @@
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
;; note that these kind of assume a rotation ordering where you can yaw as much as you want,
|
||||
;; but if you pitch 180 degrees everything is bad.
|
||||
|
||||
(defun vector-y-angle ((arg0 vector))
|
||||
"Get the yaw angle of a vector."
|
||||
(atan (-> arg0 data 0) (-> arg0 data 2))
|
||||
)
|
||||
|
||||
(defun vector-x-angle ((arg0 vector))
|
||||
"Get the pitch angle of a vector."
|
||||
(atan (-> arg0 data 1) (vector-xz-length arg0))
|
||||
)
|
||||
|
||||
(defun quaterion<-rotate-y-vector ((arg0 quaternion) (arg1 vector))
|
||||
"Create a quaternion representing only the yaw of the given vector"
|
||||
(quaternion-vector-angle!
|
||||
arg0
|
||||
(new 'static 'vector :y 1.0 :w 1.0)
|
||||
@@ -1048,6 +984,7 @@
|
||||
)
|
||||
|
||||
(defun quaternion-xz-angle ((arg0 quaternion))
|
||||
"yet another function to compute the yaw of a quaternion. This is a particularly inefficient version."
|
||||
(let ((gp-0 (new 'stack-no-clear 'matrix))
|
||||
(s5-0 (new 'stack-no-clear 'vector))
|
||||
)
|
||||
@@ -1059,6 +996,7 @@
|
||||
)
|
||||
|
||||
(defun-debug quaternion-validate ((arg0 quaternion))
|
||||
"Verify that a quaternion is valid, print an error if not."
|
||||
(with-pp
|
||||
(let ((f0-0 (quaternion-norm arg0)))
|
||||
(when (or (< 1.01 f0-0) (< f0-0 0.99))
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
;; Transformation. w components of vectors should be 1.0
|
||||
;; This can represent any rotation, translation, and scaling.
|
||||
;; Note that the scaling is applied before rotation (meaning it scales along the axes of the pre-transformed frame).
|
||||
(deftype transform (structure)
|
||||
((trans vector :inline :offset-assert 0) ;; translation
|
||||
(rot vector :inline :offset-assert 16) ;; rotation (rotation vector)
|
||||
@@ -18,6 +20,7 @@
|
||||
|
||||
|
||||
;; Like transform, but it's a basic.
|
||||
;; some in-game objects have trs as their parent type to represent their location in the game world.
|
||||
(deftype trs (basic)
|
||||
((trans vector :inline :offset-assert 16)
|
||||
(rot vector :inline :offset-assert 32)
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
;; name in dgo: transform
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
;; note: transformq and trsq is mostly used instead of transform.
|
||||
|
||||
(defmethod print transform ((obj transform))
|
||||
(format #t "#<transform @ #x~X~%" obj)
|
||||
(format #t "~T~Ttrans:~F ~F ~F ~F ~%"
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
;; name in dgo: transformq-h
|
||||
;; dgos: GAME, ENGINE
|
||||
|
||||
;; transforms, but using quaternions to represent rotations.
|
||||
|
||||
;; the transformq is a transform, but _replaces_ the rotation field with a quaternion.
|
||||
;; it is much more commonly used than transform.
|
||||
(deftype transformq (transform)
|
||||
;; this overlays the rot field of transform.
|
||||
((quat quaternion :inline :offset 16)
|
||||
@@ -16,6 +16,7 @@
|
||||
:flag-assert #x900000030
|
||||
)
|
||||
|
||||
;; trsq is the quaternion version of trs (trs is like a transform, but is basic.)
|
||||
(deftype trsq (trs)
|
||||
;; this overlays the rot field of trs.
|
||||
((quat quaternion :inline :offset 32)
|
||||
@@ -26,15 +27,23 @@
|
||||
)
|
||||
|
||||
;; Representing a translate/rotate/scale with a quaternion and a velocity.
|
||||
;; This is often used as the base type for the position of a game object that can move around
|
||||
;; so it has methods to do common control functions.
|
||||
;; many of these functions assume that y is up and assume that roll/pitch is small
|
||||
;; (a reasonable assumption for most in-game objects that don't do flips)
|
||||
;; note: Jak's control uses this as a base class.
|
||||
(deftype trsqv (trsq)
|
||||
((pause-adjust-distance meters :offset 4)
|
||||
(nav-radius meters :offset 8)
|
||||
(transv vector :inline :offset-assert 64)
|
||||
(rotv vector :inline :offset-assert 80)
|
||||
(scalev vector :inline :offset-assert 96)
|
||||
(dir-targ quaternion :inline :offset-assert 112)
|
||||
(angle-change-time int64 :offset-assert 128)
|
||||
(old-y-angle-diff float :offset-assert 136)
|
||||
((pause-adjust-distance meters :offset 4) ;; hack: adjusts the distance where actor logic is paused, if this is an actor
|
||||
(nav-radius meters :offset 8) ;; hack: the radius of the bounding sphere used by the navigate system.
|
||||
(transv vector :inline :offset-assert 64) ;; velocity (meters/second)
|
||||
(rotv vector :inline :offset-assert 80) ;; angular velocity (deg/second)
|
||||
(scalev vector :inline :offset-assert 96) ;; scale velocity (unused?)
|
||||
|
||||
;; there's a hacky ~first-order orientation yaw control with hysteresis
|
||||
;; it makes the yaw change smoothly and attempts to cancel out oscillations from the collision system
|
||||
(dir-targ quaternion :inline :offset-assert 112) ;; direction target
|
||||
(angle-change-time int64 :offset-assert 128) ;; the time when we change rotation directions
|
||||
(old-y-angle-diff float :offset-assert 136) ;; the amount we moved last time
|
||||
)
|
||||
:method-count-assert 28
|
||||
:size-assert #x8c
|
||||
@@ -58,17 +67,20 @@
|
||||
(relative-y-angle-to-point (_type_ vector) float 24)
|
||||
(roll-relative-to-gravity (_type_) float 25)
|
||||
(TODO-RENAME-26 (_type_ int vector float) trsqv 26)
|
||||
|
||||
;; note: child classes can override this method to use a different quaternion
|
||||
;; to represent the "current" orientation for the above methods.
|
||||
(get-quaternion (_type_) quaternion 27)
|
||||
)
|
||||
)
|
||||
|
||||
(defmethod global-y-angle-to-point trsqv ((obj trsqv) (arg0 vector))
|
||||
"Get the angle from the position of this trsqv to the point arg0."
|
||||
"Get the angle in the xy plane from the position of this trsqv to the point arg0."
|
||||
(vector-y-angle (vector-! (new 'stack-no-clear 'vector) arg0 (-> obj trans)))
|
||||
)
|
||||
|
||||
(defmethod relative-y-angle-to-point trsqv ((obj trsqv) (arg0 vector))
|
||||
"Get the y angle between here and arg0, starting at whatever angle we're currently at."
|
||||
"Get the y angle between the current orientation and arg0."
|
||||
(deg-diff
|
||||
(y-angle obj)
|
||||
(vector-y-angle (vector-! (new 'stack-no-clear 'vector) arg0 (-> obj trans)))
|
||||
|
||||
@@ -293,7 +293,7 @@
|
||||
;; vector types (floating point)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Vector of 4 floats. Shortened to "vector" because it is commonly used.
|
||||
;; Vector of 4 floats. Shortened to "vector" because it is the most commonly used.
|
||||
(deftype vector (structure)
|
||||
((x float :offset 0)
|
||||
(y float :offset 4)
|
||||
@@ -331,6 +331,8 @@
|
||||
(define *x-vector* (new 'static 'vector :x 1. :y 0. :z 0. :w 1.))
|
||||
(define *y-vector* (new 'static 'vector :x 0. :y 1. :z 0. :w 1.))
|
||||
(define *z-vector* (new 'static 'vector :x 0. :y 0. :z 1. :w 1.))
|
||||
|
||||
;; note: y is up.
|
||||
(define *up-vector* (new 'static 'vector :x 0. :y 1. :z 0. :w 1.))
|
||||
|
||||
|
||||
@@ -366,6 +368,10 @@
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; other geometric things
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; ax + by + cz = d form
|
||||
(deftype plane (vector)
|
||||
((a float :offset 0)
|
||||
@@ -405,6 +411,8 @@
|
||||
`(new 'static 'sphere :x (meters ,x) :y (meters ,y) :z (meters ,z) :w (meters ,r))
|
||||
)
|
||||
|
||||
;; this type represents a bounding-box, stored as minimum/maximum points
|
||||
;; note that the types in bounding-box are mostly used, this is used very rarely.
|
||||
(deftype box8s (structure)
|
||||
((data float 8 :offset-assert 0)
|
||||
(quad uint128 2 :offset 0)
|
||||
@@ -424,10 +432,9 @@
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
(set! (-> box8s-array heap-base) 32)
|
||||
|
||||
;; This is really a capsule - a cylinder with spheres at both end
|
||||
;; This is really a capsule - a cylinder with spheres at both ends
|
||||
(deftype cylinder (structure)
|
||||
((origin vector :inline :offset-assert 0)
|
||||
(axis vector :inline :offset-assert 16)
|
||||
@@ -459,6 +466,7 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; these vertical plane types are basically unused
|
||||
(deftype vertical-planes (structure)
|
||||
((data uint128 4 :offset-assert 0) ;; probably wrong
|
||||
)
|
||||
@@ -476,6 +484,8 @@
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
;; common 16-byte "quadword" structure.
|
||||
;; allows access to unsigned arrays of integers of all sizes and floats
|
||||
(deftype qword (structure)
|
||||
((data uint32 4 :offset-assert 0)
|
||||
(byte uint8 16 :offset 0)
|
||||
@@ -491,6 +501,7 @@
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
;; 12-byte vector with only 3 components. It's not used very much.
|
||||
(deftype vector3s (structure)
|
||||
((data float 3 :offset-assert 0)
|
||||
(x float :offset 0)
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
;; Types related to VIF: the PS2's Vector Interface.
|
||||
;; Each of VU0 and VU1 has a VIF which is used to sent/receive data.
|
||||
;; The VIFs are controller by registers and fed data using DMA
|
||||
;; the vif registers defined here are used extremely rarely, usually they are sent DMA
|
||||
;; (during gameplay, everything is synchronized by DMA, so code generally does not know when
|
||||
;; it is safe to mess with VIF registers.)
|
||||
|
||||
;;VIF0_STAT or VIF1_STAT bitfields
|
||||
(deftype vif-stat (uint32)
|
||||
|
||||
@@ -438,8 +438,10 @@
|
||||
:flag-assert #x90000004c
|
||||
)
|
||||
|
||||
;; each sound command gets a unique ID.
|
||||
(define *current-sound-id* (the sound-id #x10000))
|
||||
|
||||
;; a in-game background sound.
|
||||
(deftype ambient-sound (basic)
|
||||
((spec sound-spec :offset-assert 4)
|
||||
(playing-id sound-id :offset-assert 8)
|
||||
@@ -471,6 +473,8 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; currently loaded sound effect banks.
|
||||
;; there is an always-loaded common bank and two level-specific banks.
|
||||
(define *sound-bank-1* #f)
|
||||
(define *sound-bank-2* #f)
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
;; This file contains types related to game text.
|
||||
;; Each game string is assigned an ID number.
|
||||
;; This ID is used to lookup the string for the currently selected language.
|
||||
;; These ID's are shared with short spoken audio clips (daxter hints)
|
||||
;; most (all?) of the daxter clips don't have text strings.
|
||||
|
||||
;; GAME-TEXT-ID ENUM BEGINS
|
||||
(defenum game-text-id
|
||||
@@ -482,6 +484,8 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; all text is stored in the COMMON text files (one file per language).
|
||||
;; in theory, you could have multiple text files that are only loaded when needed, but they didn't do this.
|
||||
(define *text-group-names* (new 'static 'boxed-array :type string :length 1 "common"))
|
||||
|
||||
;; The heap for storing text
|
||||
|
||||
Reference in New Issue
Block a user