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:
water111
2022-02-05 16:30:50 -05:00
committed by GitHub
parent 738db287b4
commit f142f46045
36 changed files with 545 additions and 493 deletions
+6 -2
View File
@@ -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()
+77
View File
@@ -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 -24
View File
@@ -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;
+4 -3
View File
@@ -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();
+12 -1
View File
@@ -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)
+68 -24
View File
@@ -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 -2
View File
@@ -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)
+1 -1
View File
@@ -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
+11 -6
View File
@@ -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)
+8 -9
View File
@@ -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
+3
View File
@@ -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)
+60 -2
View File
@@ -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
+2
View File
@@ -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)
+2
View File
@@ -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)
+16 -8
View File
@@ -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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-2
View File
@@ -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)
+4 -4
View File
@@ -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
+5 -3
View File
@@ -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)
+59 -37
View File
@@ -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
+6 -5
View File
@@ -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
+1
View File
@@ -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
+2 -4
View File
@@ -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)
)
+8 -1
View File
@@ -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
View File
@@ -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
)
+3
View File
@@ -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)
+64 -126
View File
@@ -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))
+3
View File
@@ -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)
+2
View File
@@ -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 ~%"
+24 -12
View File
@@ -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)))
+14 -3
View File
@@ -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)
+3
View File
@@ -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)
+4
View File
@@ -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)
+4
View File
@@ -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