More Optimizations (#792)

* Initial work on optimizations.

* Requested Changes Part 1

* Requested Changes Part 2

* Requested Changes Part 3

* Requested Changes Part 4

* Requested Changes Part 5

* Requested Changes Part 6

* Update deprecated.lua

---------

Co-authored-by: PeachyPeach <72323920+PeachyPeachSM64@users.noreply.github.com>
This commit is contained in:
Prince Frizzy 2025-05-16 20:27:49 -04:00 committed by GitHub
parent 8779070d4b
commit 02c9a4146b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
91 changed files with 3329 additions and 3127 deletions

View file

@ -94,7 +94,7 @@ override_field_invisible = {
"Mod": [ "files", "showedScriptWarning" ],
"MarioState": [ "visibleToEnemies" ],
"NetworkPlayer": [ "gag", "moderator", "discordId" ],
"GraphNode": [ "_guard1", "_guard2" ],
"GraphNode": [ "_guard1", "_guard2", "padding" ],
"GraphNodeRoot": ["unk15", "views"],
"FnGraphNode": [ "luaTokenIndex" ],
"Object": [ "firstSurface" ],

View file

@ -13,6 +13,9 @@ replacements = {
'BAD_RETURN(u64)': 'void',
'BAD_RETURN(f32)': 'void',
'BAD_RETURN(f64)': 'void',
'INLINE': '',
'NOINLINE': '',
'OPTIMIZE_O3': '',
}
def extract_functions(filename):

View file

@ -21,178 +21,6 @@ _ReadOnlyTable = {
end
}
--------------------
-- math functions --
--------------------
--- @param dest Vec3f
--- @param src Vec3f
--- @return Vec3f
function vec3f_copy(dest, src)
dest.x = src.x
dest.y = src.y
dest.z = src.z
return dest
end
--- @param dest Vec3f
--- @param x number
--- @param y number
--- @param z number
--- @return Vec3f
function vec3f_set(dest, x, y, z)
dest.x = x
dest.y = y
dest.z = z
return dest
end
--- @param dest Vec3f
--- @param a Vec3f
--- @return Vec3f
function vec3f_add(dest, a)
dest.x = dest.x + a.x
dest.y = dest.y + a.y
dest.z = dest.z + a.z
return dest
end
--- @param dest Vec3f
--- @param a Vec3f
--- @param b Vec3f
--- @return Vec3f
function vec3f_sum(dest, a, b)
dest.x = a.x + b.x
dest.y = a.y + b.y
dest.z = a.z + b.z
return dest
end
--- @param dest Vec3f
--- @param a number
--- @return Vec3f
function vec3f_mul(dest, a)
dest.x = dest.x * a
dest.y = dest.y * a
dest.z = dest.z * a
return dest
end
--- @param dest Vec3f
--- @return Vec3f
function vec3f_normalize(dest)
local divisor = math.sqrt(dest.x * dest.x + dest.y * dest.y + dest.z * dest.z)
if divisor == 0 then
return dest
end
local invsqrt = 1.0 / divisor
dest.x = dest.x * invsqrt
dest.y = dest.y * invsqrt
dest.z = dest.z * invsqrt
return dest
end
--- @param a Vec3f
--- @return number
function vec3f_length(a)
return math.sqrt(a.x * a.x + a.y * a.y + a.z * a.z)
end
--- @param a Vec3f
--- @param b Vec3f
--- @return number
function vec3f_dot(a, b)
return a.x * b.x + a.y * b.y + a.z * b.z
end
--- @param vec Vec3f
--- @param onto Vec3f
--- @return Vec3f
function vec3f_project(vec, onto)
local numerator = vec3f_dot(vec, onto)
local denominator = vec3f_dot(onto, onto)
local out = {}
vec3f_copy(out, onto)
vec3f_mul(out, numerator / denominator)
return out
end
--- @param v1 Vec3f
--- @param v2 Vec3f
--- @return number
function vec3f_dist(v1, v2)
dx = v1.x - v2.x
dy = v1.y - v2.y
dz = v1.z - v2.z
return math.sqrt(dx * dx + dy * dy + dz * dz)
end
--- @param dest Vec3s
--- @param src Vec3s
--- @return Vec3s
function vec3s_copy(dest, src)
dest.x = src.x
dest.y = src.y
dest.z = src.z
return dest
end
--- @param dest Vec3s
--- @param x number
--- @param y number
--- @param z number
--- @return Vec3s
function vec3s_set(dest, x, y, z)
dest.x = x
dest.y = y
dest.z = z
return dest
end
--- @param dest Vec3s
--- @param a Vec3s
--- @return Vec3s
function vec3s_add(dest, a)
dest.x = dest.x + a.x
dest.y = dest.y + a.y
dest.z = dest.z + a.z
return dest
end
--- @param dest Vec3s
--- @param a Vec3s
--- @param b Vec3s
--- @return Vec3s
function vec3s_sum(dest, a, b)
dest.x = a.x + b.x
dest.y = a.y + b.y
dest.z = a.z + b.z
return dest
end
--- @param dest Vec3s
--- @param a number
--- @return Vec3s
function vec3s_mul(dest, a)
dest.x = dest.x * a
dest.y = dest.y * a
dest.z = dest.z * a
return dest
end
--- @param v1 Vec3s
--- @param v2 Vec3s
--- @return number
function vec3s_dist(v1, v2)
dx = v1.x - v2.x
dy = v1.y - v2.y
dz = v1.z - v2.z
return math.sqrt(dx * dx + dy * dy + dz * dz)
end
-----------
-- sound --
-----------

View file

@ -23,178 +23,6 @@ _ReadOnlyTable = {
end
}
--------------------
-- math functions --
--------------------
--- @param dest Vec3f
--- @param src Vec3f
--- @return Vec3f
function vec3f_copy(dest, src)
dest.x = src.x
dest.y = src.y
dest.z = src.z
return dest
end
--- @param dest Vec3f
--- @param x number
--- @param y number
--- @param z number
--- @return Vec3f
function vec3f_set(dest, x, y, z)
dest.x = x
dest.y = y
dest.z = z
return dest
end
--- @param dest Vec3f
--- @param a Vec3f
--- @return Vec3f
function vec3f_add(dest, a)
dest.x = dest.x + a.x
dest.y = dest.y + a.y
dest.z = dest.z + a.z
return dest
end
--- @param dest Vec3f
--- @param a Vec3f
--- @param b Vec3f
--- @return Vec3f
function vec3f_sum(dest, a, b)
dest.x = a.x + b.x
dest.y = a.y + b.y
dest.z = a.z + b.z
return dest
end
--- @param dest Vec3f
--- @param a number
--- @return Vec3f
function vec3f_mul(dest, a)
dest.x = dest.x * a
dest.y = dest.y * a
dest.z = dest.z * a
return dest
end
--- @param dest Vec3f
--- @return Vec3f
function vec3f_normalize(dest)
local divisor = math.sqrt(dest.x * dest.x + dest.y * dest.y + dest.z * dest.z)
if divisor == 0 then
return dest
end
local invsqrt = 1.0 / divisor
dest.x = dest.x * invsqrt
dest.y = dest.y * invsqrt
dest.z = dest.z * invsqrt
return dest
end
--- @param a Vec3f
--- @return number
function vec3f_length(a)
return math.sqrt(a.x * a.x + a.y * a.y + a.z * a.z)
end
--- @param a Vec3f
--- @param b Vec3f
--- @return number
function vec3f_dot(a, b)
return a.x * b.x + a.y * b.y + a.z * b.z
end
--- @param vec Vec3f
--- @param onto Vec3f
--- @return Vec3f
function vec3f_project(vec, onto)
local numerator = vec3f_dot(vec, onto)
local denominator = vec3f_dot(onto, onto)
local out = {}
vec3f_copy(out, onto)
vec3f_mul(out, numerator / denominator)
return out
end
--- @param v1 Vec3f
--- @param v2 Vec3f
--- @return number
function vec3f_dist(v1, v2)
dx = v1.x - v2.x
dy = v1.y - v2.y
dz = v1.z - v2.z
return math.sqrt(dx * dx + dy * dy + dz * dz)
end
--- @param dest Vec3s
--- @param src Vec3s
--- @return Vec3s
function vec3s_copy(dest, src)
dest.x = src.x
dest.y = src.y
dest.z = src.z
return dest
end
--- @param dest Vec3s
--- @param x number
--- @param y number
--- @param z number
--- @return Vec3s
function vec3s_set(dest, x, y, z)
dest.x = x
dest.y = y
dest.z = z
return dest
end
--- @param dest Vec3s
--- @param a Vec3s
--- @return Vec3s
function vec3s_add(dest, a)
dest.x = dest.x + a.x
dest.y = dest.y + a.y
dest.z = dest.z + a.z
return dest
end
--- @param dest Vec3s
--- @param a Vec3s
--- @param b Vec3s
--- @return Vec3s
function vec3s_sum(dest, a, b)
dest.x = a.x + b.x
dest.y = a.y + b.y
dest.z = a.z + b.z
return dest
end
--- @param dest Vec3s
--- @param a number
--- @return Vec3s
function vec3s_mul(dest, a)
dest.x = dest.x * a
dest.y = dest.y * a
dest.z = dest.z * a
return dest
end
--- @param v1 Vec3s
--- @param v2 Vec3s
--- @return number
function vec3s_dist(v1, v2)
dx = v1.x - v2.x
dy = v1.y - v2.y
dz = v1.z - v2.z
return math.sqrt(dx * dx + dy * dy + dz * dz)
end
-----------
-- sound --
-----------

View file

@ -3130,13 +3130,6 @@ function select_mario_cam_mode()
-- ...
end
--- @param dst Vec3f
--- @param src Vec3f
--- Subtracts one 3D vector (`src`) from another (`dst`). Stores the result in the destination vector
function vec3f_sub(dst, src)
-- ...
end
--- @param dst Vec3f
--- @param o Object
--- Converts an object's position to a `Vec3f` format. Useful for aligning object behaviors or interactions with the camera system
@ -6299,9 +6292,17 @@ function coss(sm64Angle)
-- ...
end
--- @param y number
--- @param x number
--- @return integer
--- Computes the arctangent of y/x and returns the angle as a signed 16-bit integer, typically representing a direction in the SM64 fixed-point angle format. This can be used to find an angle between x and y coordinates
function atan2s(y, x)
-- ...
end
--- @param dest Vec3f
--- @param src Vec3f
--- @return void*
--- @return Pointer_number
--- Copies the contents of a 3D floating-point vector (`src`) into another 3D floating-point vector (`dest`). After this operation, `dest` will have the same x, y, and z values as `src`
function vec3f_copy(dest, src)
-- ...
@ -6311,7 +6312,7 @@ end
--- @param x number
--- @param y number
--- @param z number
--- @return void*
--- @return Pointer_number
--- Sets the values of the 3D floating-point vector `dest` to the given x, y, and z values. After this function, `dest` will have values (x, y, z)
function vec3f_set(dest, x, y, z)
-- ...
@ -6319,7 +6320,7 @@ end
--- @param dest Vec3f
--- @param a Vec3f
--- @return void*
--- @return Pointer_number
--- Adds the components of the 3D floating-point vector `a` to `dest`. After this operation, `dest.x` will be `dest.x + a.x`, and similarly for the y and z components
function vec3f_add(dest, a)
-- ...
@ -6328,16 +6329,24 @@ end
--- @param dest Vec3f
--- @param a Vec3f
--- @param b Vec3f
--- @return void*
--- @return Pointer_number
--- Adds the corresponding components of two 3D floating-point vectors `a` and `b`, and stores the result in `dest`. For example, `dest.x = a.x + b.x`, `dest.y = a.y + b.y`, and `dest.z = a.z + b.z`
function vec3f_sum(dest, a, b)
-- ...
end
--- @param dest Vec3f
--- @param a Vec3f
--- @return Pointer_number
--- Subtracts the components of the 3D floating-point vector `a` from `dest`. After this operation, `dest.x` will be `dest.x - a.x`, and similarly for the y and z components
function vec3f_sub(dest, a)
-- ...
end
--- @param dest Vec3f
--- @param a Vec3f
--- @param b Vec3f
--- @return void*
--- @return Pointer_number
--- Subtracts the components of the 3D floating-point vector `b` from the components of `a` and stores the result in `dest`. For example, `dest.x = a.x - b.x` This results in a vector that represents the difference between `a` and `b`.
function vec3f_dif(dest, a, b)
-- ...
@ -6345,89 +6354,43 @@ end
--- @param dest Vec3f
--- @param a number
--- @return void*
--- @return Pointer_number
--- Multiplies each component of the 3D floating-point vector `dest` by the scalar value `a`. For instance, `dest.x = dest.x * a`, and similarly for y and z. This scales the vector `dest` by `a`
function vec3f_mul(dest, a)
-- ...
end
--- @param dest Vec3s
--- @param src Vec3s
--- @return void*
--- Copies the components of one 3D signed-integer vector (`src`) to another (`dest`). After this function, `dest` will have the same x, y, and z integer values as `src`
function vec3s_copy(dest, src)
-- ...
end
--- @param dest Vec3s
--- @param x integer
--- @param y integer
--- @param z integer
--- @return void*
--- Sets the 3D signed-integer vector `dest` to the specified integer values (x, y, z), so that `dest` becomes (x, y, z).
function vec3s_set(dest, x, y, z)
-- ...
end
--- @param dest Vec3s
--- @param a Vec3s
--- @return void*
--- Adds the components of a 3D signed-integer vector `a` to the corresponding components of `dest`. After this operation, each component of `dest` is increased by the corresponding component in `a`
function vec3s_add(dest, a)
-- ...
end
--- @param dest Vec3s
--- @param a Vec3s
--- @param b Vec3s
--- @return void*
--- Adds the components of two 3D signed-integer vectors `a` and `b` together and stores the resulting vector in `dest`. For example, `dest.x = a.x + b.x`, and similarly for y and z
function vec3s_sum(dest, a, b)
-- ...
end
--- @param dest Vec3f
--- @param a Vec3s
--- @return void*
--- Converts a 3D signed-integer vector `a` (vec3s) into a 3D floating-point vector and stores it in `dest`. After this operation, `dest` will contain the floating-point equivalents of `a`'s integer components
function vec3s_to_vec3f(dest, a)
-- ...
end
--- @param dest Vec3s
--- @param a Vec3f
--- @return void*
--- Converts a 3D floating-point vector `a` (Vec3f) into a 3D signed-integer vector and stores it in `dest`. After this operation, `dest` will contain the integer versions of `a`'s floating-point components
function vec3f_to_vec3s(dest, a)
--- @param a number
--- @return Pointer_number
--- Divides each component of the 3D floating-point vector `dest` by the scalar value `a`. For instance, `dest.x = dest.x / a`, and similarly for y and z. This scales the vector `dest` by `a`
function vec3f_div(dest, a)
-- ...
end
--- @param dest Vec3f
--- @param a Vec3f
--- @param b Vec3f
--- @param c Vec3f
--- @return void*
--- Determines a vector that is perpendicular (normal) to the plane defined by three given 3D floating-point points `a`, `b`, and `c`. The resulting perpendicular vector is stored in `dest`
function find_vector_perpendicular_to_plane(dest, a, b, c)
-- ...
end
--- @param dest Vec3f
--- @param a Vec3f
--- @param b Vec3f
--- @return void*
--- @return Pointer_number
--- Computes the cross product of two 3D floating-point vectors `a` and `b`. The cross product is a vector perpendicular to both `a` and `b`. The result is stored in `dest`
function vec3f_cross(dest, a, b)
-- ...
end
--- @param dest Vec3f
--- @return void*
--- @return Pointer_number
--- Normalizes the 3D floating-point vector `dest` so that its length (magnitude) becomes 1, while retaining its direction. This effectively scales `dest` so that it lies on the unit sphere
function vec3f_normalize(dest)
-- ...
end
--- @param v Vec3f
--- @return Pointer_number
--- Normalizes each component of the 3D floating-point vector 'v'.
function vec3f_normalize2(v)
-- ...
end
--- @param a Vec3f
--- @return number
--- Calculates the length (magnitude) of the 3D floating-point vector `a`. The length is defined as sqrt(x² + y² + z²) for the vector components (x, y, z)
@ -6448,6 +6411,7 @@ end
--- @param vecB Vec3f
--- @param sclA number
--- @param sclB number
--- @return Pointer_number
--- Takes two 3D floating-point vectors `vecA` and `vecB`, multiplies them by `sclA` and `sclB` respectively, and then adds the scaled vectors together. The final combined vector is stored in `dest`
function vec3f_combine(dest, vecA, vecB, sclA, sclB)
-- ...
@ -6455,12 +6419,164 @@ end
--- @param v Vec3f
--- @param rotate Vec3s
--- @return void*
--- @return Pointer_number
--- Rotates the 3D floating-point vector `v` by the angles specified in the 3D signed-integer vector `rotate`, applying the rotations in the order Z, then X, then Y. The rotated vector replaces `v`
function vec3f_rotate_zxy(v, rotate)
-- ...
end
--- @param vec Vec3f
--- @param onto Vec3f
--- @param out Vec3f
--- @return Pointer_number
--- Projects the 3D floating-point vector `vec` onto another 3D floating-point vector `onto`. The resulting projection, stored in `out`, represents how much of `vec` lies along the direction of `onto`
function vec3f_project(vec, onto, out)
-- ...
end
--- @param v1 Vec3f
--- @param v2 Vec3f
--- @return number
--- Calculates the distance between two 3D floating-point points `v1` and `v2`. The distance is the length of the vector `v2 - v1`, i.e., sqrt((v2.x - v1.x)² + (v2.y - v1.y)² + (v2.z - v1.z)²)
function vec3f_dist(v1, v2)
-- ...
end
--- @param from Vec3f
--- @param to Vec3f
--- @param dist Pointer_number
--- @param pitch Pointer_integer
--- @param yaw Pointer_integer
--- Calculates the distance between two points in 3D space (`from` and `to`), as well as the pitch and yaw angles that describe the direction from `from` to `to`. The results are stored in `dist`, `pitch`, and `yaw`
function vec3f_get_dist_and_angle(from, to, dist, pitch, yaw)
-- ...
end
--- @param from Vec3f
--- @param to Vec3f
--- @param dist number
--- @param pitch integer
--- @param yaw integer
--- Positions the point `to` at a given `dist`, `pitch`, and `yaw` relative to the point `from`. This can be used to place objects around a reference point at specific angles and distances
function vec3f_set_dist_and_angle(from, to, dist, pitch, yaw)
-- ...
end
--- @param v Vec3f
--- @return Pointer_number
--- Sets the values of the 3D floating-point vector `v` to 0. After this function, `v` will have values of 0.
function vec3f_zero(v)
-- ...
end
--- @param dest Vec3s
--- @param a Vec3f
--- @return Pointer_integer
--- Converts a 3D floating-point vector `a` (Vec3f) into a 3D signed-integer vector and stores it in `dest`. After this operation, `dest` will contain the integer versions of `a`'s floating-point components
function vec3f_to_vec3s(dest, a)
-- ...
end
--- @param dest Vec3s
--- @param src Vec3s
--- @return Pointer_integer
--- Copies the components of one 3D signed-integer vector (`src`) to another (`dest`). After this function, `dest` will have the same x, y, and z integer values as `src`
function vec3s_copy(dest, src)
-- ...
end
--- @param dest Vec3s
--- @param x integer
--- @param y integer
--- @param z integer
--- @return Pointer_integer
--- Sets the 3D signed-integer vector `dest` to the specified integer values (x, y, z), so that `dest` becomes (x, y, z).
function vec3s_set(dest, x, y, z)
-- ...
end
--- @param dest Vec3s
--- @param a Vec3s
--- @return Pointer_integer
--- Adds the components of a 3D signed-integer vector `a` to the corresponding components of `dest`. After this operation, each component of `dest` is increased by the corresponding component in `a`
function vec3s_add(dest, a)
-- ...
end
--- @param dest Vec3s
--- @param a Vec3s
--- @param b Vec3s
--- @return Pointer_integer
--- Adds the components of two 3D signed-integer vectors `a` and `b` together and stores the resulting vector in `dest`. For example, `dest.x = a.x + b.x`, and similarly for y and z
function vec3s_sum(dest, a, b)
-- ...
end
--- @param dest Vec3s
--- @param a Vec3s
--- @param b Vec3s
--- @return Pointer_integer
--- Subtracts the components of the 3D signed-integer vector `b` from the components of `a` and stores the result in `dest`. For example, `dest.x = a.x - b.x` This results in a vector that represents the difference between `a` and `b`.
function vec3s_dif(dest, a, b)
-- ...
end
--- @param dest Vec3s
--- @param a integer
--- @return Pointer_integer
--- Multiplies each component of the 3D signed-integer vector `dest` by the scalar value `a`. For instance, `dest.x = dest.x * a`, and similarly for y and z. This scales the vector `dest` by `a`
function vec3s_mul(dest, a)
-- ...
end
--- @param dest Vec3s
--- @param a integer
--- @return Pointer_integer
--- Divides each component of the 3D signed-integer vector `dest` by the scalar value `a`. For instance, `dest.x = dest.x / a`, and similarly for y and z. This scales the vector `dest` by `a`
function vec3s_div(dest, a)
-- ...
end
--- @param a Vec3s
--- @return number
--- Calculates the length (magnitude) of the 3D signed-integer vector `a`. The length is defined as sqrt(x² + y² + z²) for the vector components (x, y, z)
function vec3s_length(a)
-- ...
end
--- @param v1 Vec3s
--- @param v2 Vec3s
--- @return number
--- Calculates the distance between two 3D signed-integer points `v1` and `v2`. The distance is the length of the vector `v2 - v1`, i.e., sqrt((v2.x - v1.x)² + (v2.y - v1.y)² + (v2.z - v1.z)²)
function vec3s_dist(v1, v2)
-- ...
end
--- @param v Vec3s
--- @return Pointer_integer
--- Sets the values of the 3D signed-integer vector `v` to 0. After this function, `v` will have values of 0.
function vec3s_zero(v)
-- ...
end
--- @param dest Vec3f
--- @param a Vec3s
--- @return Pointer_number
--- Converts a 3D signed-integer vector `a` (vec3s) into a 3D floating-point vector and stores it in `dest`. After this operation, `dest` will contain the floating-point equivalents of `a`'s integer components
function vec3s_to_vec3f(dest, a)
-- ...
end
--- @param dest Vec3f
--- @param a Vec3f
--- @param b Vec3f
--- @param c Vec3f
--- @return Pointer_number
--- Determines a vector that is perpendicular (normal) to the plane defined by three given 3D floating-point points `a`, `b`, and `c`. The resulting perpendicular vector is stored in `dest`
function find_vector_perpendicular_to_plane(dest, a, b, c)
-- ...
end
--- @param dest Mat4
--- @param src Mat4
--- Copies the 4x4 floating-point matrix `src` into `dest`. After this operation, `dest` contains the same matrix values as `src`
@ -6560,6 +6676,7 @@ end
--- @param mtx Mat4
--- @param b Vec3s
--- @return Pointer_integer
--- Multiplies the 4x4 floating-point matrix `mtx` by a 3D signed-integer vector `b`, potentially interpreting `b` as angles or translations depending on usage, and modifies `mtx` accordingly
function mtxf_mul_vec3s(mtx, b)
-- ...
@ -6572,34 +6689,21 @@ function mtxf_inverse(dest, src)
-- ...
end
--- @param mtx Mat4
--- Sets the 4x4 floating-point matrix `mtx` to all zeros. Unless you really need this-It's reccomended to use mtxf_identity instead.
function mtxf_zero(mtx)
-- ...
end
--- @param dest Vec3f
--- @param objMtx Mat4
--- @param camMtx Mat4
--- @return Pointer_number
--- Extracts the position (translation component) from the transformation matrix `objMtx` relative to the coordinate system defined by `camMtx` and stores that 3D position in `dest`. This can be used to get the object's coordinates in camera space
function get_pos_from_transform_mtx(dest, objMtx, camMtx)
-- ...
end
--- @param from Vec3f
--- @param to Vec3f
--- @param dist Pointer_number
--- @param pitch Pointer_integer
--- @param yaw Pointer_integer
--- Calculates the distance between two points in 3D space (`from` and `to`), as well as the pitch and yaw angles that describe the direction from `from` to `to`. The results are stored in `dist`, `pitch`, and `yaw`
function vec3f_get_dist_and_angle(from, to, dist, pitch, yaw)
-- ...
end
--- @param from Vec3f
--- @param to Vec3f
--- @param dist number
--- @param pitch integer
--- @param yaw integer
--- Positions the point `to` at a given `dist`, `pitch`, and `yaw` relative to the point `from`. This can be used to place objects around a reference point at specific angles and distances
function vec3f_set_dist_and_angle(from, to, dist, pitch, yaw)
-- ...
end
--- @param current integer
--- @param target integer
--- @param inc integer
@ -6620,14 +6724,6 @@ function approach_f32(current, target, inc, dec)
-- ...
end
--- @param y number
--- @param x number
--- @return integer
--- Computes the arctangent of y/x and returns the angle as a signed 16-bit integer, typically representing a direction in the SM64 fixed-point angle format. This can be used to find an angle between x and y coordinates
function atan2s(y, x)
-- ...
end
--- @param m MarioState
--- @param result Vec4f
--- @param t number
@ -6660,22 +6756,6 @@ function not_zero(value, replacement)
-- ...
end
--- @param vec Vec3f
--- @param onto Vec3f
--- @param out Vec3f
--- Projects the 3D floating-point vector `vec` onto another 3D floating-point vector `onto`. The resulting projection, stored in `out`, represents how much of `vec` lies along the direction of `onto`
function vec3f_project(vec, onto, out)
-- ...
end
--- @param v1 Vec3f
--- @param v2 Vec3f
--- @return number
--- Calculates the distance between two 3D floating-point points `v1` and `v2`. The distance is the length of the vector `v2 - v1`, i.e., sqrt((v2.x - v1.x)² + (v2.y - v1.y)² + (v2.z - v1.z)²)
function vec3f_dist(v1, v2)
-- ...
end
--- @param edge0 number
--- @param edge1 number
--- @param x number

View file

@ -1129,7 +1129,6 @@
--- @class MarioAnimation
--- @field public currentAnimAddr Pointer_integer
--- @field public padding integer[]
--- @field public targetAnim Animation
--- @class MarioBodyState
@ -1733,6 +1732,7 @@
--- @field public oMarioBurnTimer integer
--- @field public oMarioCannonInputYaw integer
--- @field public oMarioCannonObjectYaw integer
--- @field public oMarioJumboStarCutscenePosZ number
--- @field public oMarioLongJumpIsSlow integer
--- @field public oMarioParticleFlags integer
--- @field public oMarioPolePos number

View file

@ -2,6 +2,7 @@
#include <set>
#include "dynos.cpp.h"
extern "C" {
#include "pc/gfx/gfx.h"
#include "pc/gfx/gfx_rendering_api.h"
}
@ -46,13 +47,6 @@ static bool sDynosDumpTextureCache = false;
// Conversion
//
#define SCALE_5_8(VAL_) (((VAL_) * 0xFF) / 0x1F)
#define SCALE_8_5(VAL_) ((((VAL_) + 4) * 0x1F) / 0xFF)
#define SCALE_4_8(VAL_) ((VAL_) * 0x11)
#define SCALE_8_4(VAL_) ((VAL_) / 0x11)
#define SCALE_3_8(VAL_) ((VAL_) * 0x24)
#define SCALE_8_3(VAL_) ((VAL_) / 0x24)
static u8 *RGBA16_RGBA32(const u8 *aData, u64 aLength) {
u8 *_Buffer = New<u8>(aLength * 2);
u8 *pBuffer = _Buffer;
@ -233,14 +227,7 @@ static void DynOS_Tex_Upload(DataNode<TexData> *aNode, GRAPI *aGfxRApi, s32 aTil
// Cache
//
struct THN {
struct THN *mNext;
const void *mAddr; // Contains the pointer to the DataNode<TexData> struct, NOT the actual texture data
u8 mFmt, mSiz;
s32 mTexId;
u8 mCms, mCmt;
bool mLInf;
};
typedef struct TextureHashmapNode THN;
static bool DynOS_Tex_Cache(THN **aOutput, DataNode<TexData> *aNode, s32 aTile, GRAPI *aGfxRApi, THN **aHashMap, THN *aPool, u32 *aPoolPos, u32 aPoolSize) {
@ -248,15 +235,15 @@ static bool DynOS_Tex_Cache(THN **aOutput, DataNode<TexData> *aNode, s32 aTile,
uintptr_t _Hash = ((uintptr_t) aNode) & ((aPoolSize * 2) - 1);
THN **_Node = &(aHashMap[_Hash]);
while ((*_Node) != NULL && ((*_Node) - aPool) < (*aPoolPos)) {
if ((*_Node)->mAddr == (const void *) aNode) {
aGfxRApi->select_texture(aTile, (*_Node)->mTexId);
if ((*_Node)->texture_addr == (const void *) aNode) {
aGfxRApi->select_texture(aTile, (*_Node)->texture_id);
if (!aNode->mData->mUploaded) {
DynOS_Tex_Upload(aNode, aGfxRApi, aTile, (*_Node)->mTexId);
DynOS_Tex_Upload(aNode, aGfxRApi, aTile, (*_Node)->texture_id);
}
(*aOutput) = (*_Node);
return true;
}
_Node = &(*_Node)->mNext;
_Node = &(*_Node)->next;
}
// If cache is full, clear cache
@ -267,19 +254,19 @@ static bool DynOS_Tex_Cache(THN **aOutput, DataNode<TexData> *aNode, s32 aTile,
// Add new texture to cache
(*_Node) = &aPool[(*aPoolPos)++];
if (!(*_Node)->mAddr) {
(*_Node)->mTexId = aGfxRApi->new_texture();
if (!(*_Node)->texture_addr) {
(*_Node)->texture_id = aGfxRApi->new_texture();
}
aGfxRApi->select_texture(aTile, (*_Node)->mTexId);
aGfxRApi->select_texture(aTile, (*_Node)->texture_id);
aGfxRApi->set_sampler_parameters(aTile, false, 0, 0);
(*_Node)->mCms = 0;
(*_Node)->mCmt = 0;
(*_Node)->mLInf = false;
(*_Node)->mNext = NULL;
(*_Node)->mAddr = aNode;
(*_Node)->mFmt = G_IM_FMT_RGBA;
(*_Node)->mSiz = G_IM_SIZ_32b;
(*aOutput) = (*_Node);
(*_Node)->next = NULL;
(*_Node)->texture_addr = aNode;
(*_Node)->fmt = G_IM_FMT_RGBA;
(*_Node)->siz = G_IM_SIZ_32b;
(*_Node)->cms = 0;
(*_Node)->cmt = 0;
(*_Node)->linear_filter = false;
(*aOutput) = (*_Node);
return false;
}
@ -350,7 +337,7 @@ static bool DynOS_Tex_Import_Typed(THN **aOutput, void *aPtr, s32 aTile, GRAPI *
DataNode<TexData> *_Node = DynOS_Tex_RetrieveNode(aPtr);
if (_Node) {
if (!DynOS_Tex_Cache(aOutput, _Node, aTile, aGfxRApi, aHashMap, aPool, aPoolPos, aPoolSize)) {
DynOS_Tex_Upload(_Node, aGfxRApi, aTile, (*aOutput)->mTexId);
DynOS_Tex_Upload(_Node, aGfxRApi, aTile, (*aOutput)->texture_id);
}
return true;
}

View file

@ -519,30 +519,6 @@ Selects the appropriate camera mode for Mario based on the current gameplay cont
<br />
## [vec3f_sub](#vec3f_sub)
### Description
Subtracts one 3D vector (`src`) from another (`dst`). Stores the result in the destination vector
### Lua Example
`vec3f_sub(dst, src)`
### Parameters
| Field | Type |
| ----- | ---- |
| dst | [Vec3f](structs.md#Vec3f) |
| src | [Vec3f](structs.md#Vec3f) |
### Returns
- None
### C Prototype
`void vec3f_sub(Vec3f dst, Vec3f src);`
[:arrow_up_small:](#)
<br />
## [object_pos_to_vec3f](#object_pos_to_vec3f)
### Description

File diff suppressed because it is too large Load diff

View file

@ -652,7 +652,6 @@
- [soft_reset_camera](functions-3.md#soft_reset_camera)
- [reset_camera](functions-3.md#reset_camera)
- [select_mario_cam_mode](functions-3.md#select_mario_cam_mode)
- [vec3f_sub](functions-3.md#vec3f_sub)
- [object_pos_to_vec3f](functions-3.md#object_pos_to_vec3f)
- [vec3f_to_object_pos](functions-3.md#vec3f_to_object_pos)
- [cam_select_alt_mode](functions-3.md#cam_select_alt_mode)
@ -1189,25 +1188,40 @@
- math_util.h
- [sins](functions-4.md#sins)
- [coss](functions-4.md#coss)
- [atan2s](functions-4.md#atan2s)
- [vec3f_copy](functions-4.md#vec3f_copy)
- [vec3f_set](functions-4.md#vec3f_set)
- [vec3f_add](functions-4.md#vec3f_add)
- [vec3f_sum](functions-4.md#vec3f_sum)
- [vec3f_sub](functions-4.md#vec3f_sub)
- [vec3f_dif](functions-4.md#vec3f_dif)
- [vec3f_mul](functions-4.md#vec3f_mul)
- [vec3s_copy](functions-4.md#vec3s_copy)
- [vec3s_set](functions-4.md#vec3s_set)
- [vec3s_add](functions-4.md#vec3s_add)
- [vec3s_sum](functions-4.md#vec3s_sum)
- [vec3s_to_vec3f](functions-4.md#vec3s_to_vec3f)
- [vec3f_to_vec3s](functions-4.md#vec3f_to_vec3s)
- [find_vector_perpendicular_to_plane](functions-4.md#find_vector_perpendicular_to_plane)
- [vec3f_div](functions-4.md#vec3f_div)
- [vec3f_cross](functions-4.md#vec3f_cross)
- [vec3f_normalize](functions-4.md#vec3f_normalize)
- [vec3f_normalize2](functions-4.md#vec3f_normalize2)
- [vec3f_length](functions-4.md#vec3f_length)
- [vec3f_dot](functions-4.md#vec3f_dot)
- [vec3f_combine](functions-4.md#vec3f_combine)
- [vec3f_rotate_zxy](functions-4.md#vec3f_rotate_zxy)
- [vec3f_project](functions-4.md#vec3f_project)
- [vec3f_dist](functions-4.md#vec3f_dist)
- [vec3f_get_dist_and_angle](functions-4.md#vec3f_get_dist_and_angle)
- [vec3f_set_dist_and_angle](functions-4.md#vec3f_set_dist_and_angle)
- [vec3f_zero](functions-4.md#vec3f_zero)
- [vec3f_to_vec3s](functions-4.md#vec3f_to_vec3s)
- [vec3s_copy](functions-4.md#vec3s_copy)
- [vec3s_set](functions-4.md#vec3s_set)
- [vec3s_add](functions-4.md#vec3s_add)
- [vec3s_sum](functions-4.md#vec3s_sum)
- [vec3s_dif](functions-4.md#vec3s_dif)
- [vec3s_mul](functions-4.md#vec3s_mul)
- [vec3s_div](functions-4.md#vec3s_div)
- [vec3s_length](functions-4.md#vec3s_length)
- [vec3s_dist](functions-4.md#vec3s_dist)
- [vec3s_zero](functions-4.md#vec3s_zero)
- [vec3s_to_vec3f](functions-4.md#vec3s_to_vec3f)
- [find_vector_perpendicular_to_plane](functions-4.md#find_vector_perpendicular_to_plane)
- [mtxf_copy](functions-4.md#mtxf_copy)
- [mtxf_identity](functions-4.md#mtxf_identity)
- [mtxf_translate](functions-4.md#mtxf_translate)
@ -1222,18 +1236,14 @@
- [mtxf_scale_vec3f](functions-4.md#mtxf_scale_vec3f)
- [mtxf_mul_vec3s](functions-4.md#mtxf_mul_vec3s)
- [mtxf_inverse](functions-4.md#mtxf_inverse)
- [mtxf_zero](functions-4.md#mtxf_zero)
- [get_pos_from_transform_mtx](functions-4.md#get_pos_from_transform_mtx)
- [vec3f_get_dist_and_angle](functions-4.md#vec3f_get_dist_and_angle)
- [vec3f_set_dist_and_angle](functions-4.md#vec3f_set_dist_and_angle)
- [approach_s32](functions-4.md#approach_s32)
- [approach_f32](functions-4.md#approach_f32)
- [atan2s](functions-4.md#atan2s)
- [spline_get_weights](functions-4.md#spline_get_weights)
- [anim_spline_init](functions-4.md#anim_spline_init)
- [anim_spline_poll](functions-4.md#anim_spline_poll)
- [not_zero](functions-4.md#not_zero)
- [vec3f_project](functions-4.md#vec3f_project)
- [vec3f_dist](functions-4.md#vec3f_dist)
<br />

View file

@ -1721,7 +1721,6 @@
| Field | Type | Access |
| ----- | ---- | ------ |
| currentAnimAddr | `Pointer` <`integer`> | read-only |
| padding | `Array` <`integer`> | |
| targetAnim | [Animation](structs.md#Animation) | |
[:arrow_up_small:](#)
@ -2141,6 +2140,7 @@
| oMarioTornadoPosY | `number` | |
| oMarioReadingSignDPosZ | `number` | |
| oMarioWhirlpoolPosY | `number` | |
| oMarioJumboStarCutscenePosZ | `number` | |
| oMarioBurnTimer | `integer` | |
| oMarioLongJumpIsSlow | `integer` | |
| oMarioSteepJumpYaw | `integer` | |

View file

@ -88,6 +88,20 @@
#define OPTIMIZE_O3
#endif
#ifdef __clang__
#define INLINE __attribute__((always_inline)) inline
#define NOINLINE __attribute__((noinline))
#elif __GNUC__
#define INLINE __attribute__((always_inline)) inline
#define NOINLINE __attribute__((noinline))
#elif _MSC_VER
#define INLINE __forceinline
#define NOINLINE __noinline
#else
#define INLINE inline
#define NOINLINE noinline
#endif
// Repeats the macro `ACTION(N)` `N` times (one per line)
#define REPEAT_0(ACTION)
#define REPEAT_1(ACTION) ACTION(1)

View file

@ -7,12 +7,16 @@
*/
#ifdef OBJECT_FIELDS_INDEX_DIRECTLY
#define OBJECT_FIELD_U16(index, subIndex) index + subIndex
#define OBJECT_FIELD_S16(index, subIndex) index + subIndex
#define OBJECT_FIELD_U32(index) index
#define OBJECT_FIELD_S32(index) index
#define OBJECT_FIELD_S16(index, subIndex) index
#define OBJECT_FIELD_F32(index) index
#define OBJECT_FIELD_U16P(index) index
#define OBJECT_FIELD_S16P(index) index
#define OBJECT_FIELD_U32P(index) index
#define OBJECT_FIELD_S32P(index) index
#define OBJECT_FIELD_F32P(index) index
#define OBJECT_FIELD_ANIMS(index) index
#define OBJECT_FIELD_WAYPOINT(index) index
#define OBJECT_FIELD_CHAIN_SEGMENT(index) index
@ -21,19 +25,23 @@
#define OBJECT_FIELD_VPTR(index) index
#define OBJECT_FIELD_CVPTR(index) index
#else
#define OBJECT_FIELD_U32(index) rawData.asU32[index]
#define OBJECT_FIELD_S32(index) rawData.asS32[index]
#define OBJECT_FIELD_S16(index, subIndex) rawData.asS16[index][subIndex]
#define OBJECT_FIELD_F32(index) rawData.asF32[index]
#define OBJECT_FIELD_S16P(index) ptrData.asS16P[index]
#define OBJECT_FIELD_S32P(index) ptrData.asS32P[index]
#define OBJECT_FIELD_ANIMS(index) ptrData.asAnims[index]
#define OBJECT_FIELD_WAYPOINT(index) ptrData.asWaypoint[index]
#define OBJECT_FIELD_CHAIN_SEGMENT(index) ptrData.asChainSegment[index]
#define OBJECT_FIELD_OBJ(index) ptrData.asObject[index]
#define OBJECT_FIELD_SURFACE(index) ptrData.asSurface[index]
#define OBJECT_FIELD_VPTR(index) ptrData.asVoidPtr[index]
#define OBJECT_FIELD_CVPTR(index) ptrData.asConstVoidPtr[index]
#define OBJECT_FIELD_U16(index, subIndex) rawData.asU16[index][subIndex]
#define OBJECT_FIELD_S16(index, subIndex) rawData.asS16[index][subIndex]
#define OBJECT_FIELD_U32(index) rawData.asU32[index]
#define OBJECT_FIELD_S32(index) rawData.asS32[index]
#define OBJECT_FIELD_F32(index) rawData.asF32[index]
#define OBJECT_FIELD_U16P(index) ptrData.asU16P[index]
#define OBJECT_FIELD_S16P(index) ptrData.asS16P[index]
#define OBJECT_FIELD_U32P(index) ptrData.asU32P[index]
#define OBJECT_FIELD_S32P(index) ptrData.asS32P[index]
#define OBJECT_FIELD_F32P(index) ptrData.asF32P[index]
#define OBJECT_FIELD_ANIMS(index) ptrData.asAnims[index]
#define OBJECT_FIELD_WAYPOINT(index) ptrData.asWaypoint[index]
#define OBJECT_FIELD_CHAIN_SEGMENT(index) ptrData.asChainSegment[index]
#define OBJECT_FIELD_OBJ(index) ptrData.asObject[index]
#define OBJECT_FIELD_SURFACE(index) ptrData.asSurface[index]
#define OBJECT_FIELD_VPTR(index) ptrData.asVoidPtr[index]
#define OBJECT_FIELD_CVPTR(index) ptrData.asConstVoidPtr[index]
#endif
// 0x088 (0x00), the first field, is object-specific and defined below the common fields.
@ -136,22 +144,23 @@
#define /*0x110*/ oMacroUnk110 OBJECT_FIELD_F32(0x22)
/* Mario */
#define /*0x0F4*/ oMarioParticleFlags OBJECT_FIELD_S32(0x1B)
#define /*0x108*/ oMarioPoleUnk108 OBJECT_FIELD_S32(0x20)
#define /*0x108*/ oMarioReadingSignDYaw OBJECT_FIELD_S32(0x20)
#define /*0x10C*/ oMarioPoleYawVel OBJECT_FIELD_S32(0x21)
#define /*0x10C*/ oMarioCannonObjectYaw OBJECT_FIELD_S32(0x21)
#define /*0x10C*/ oMarioTornadoYawVel OBJECT_FIELD_S32(0x21)
#define /*0x10C*/ oMarioReadingSignDPosX OBJECT_FIELD_F32(0x21)
#define /*0x110*/ oMarioPolePos OBJECT_FIELD_F32(0x22)
#define /*0x110*/ oMarioCannonInputYaw OBJECT_FIELD_S32(0x22)
#define /*0x110*/ oMarioTornadoPosY OBJECT_FIELD_F32(0x22)
#define /*0x110*/ oMarioReadingSignDPosZ OBJECT_FIELD_F32(0x22)
#define /*0x110*/ oMarioWhirlpoolPosY OBJECT_FIELD_F32(0x22)
#define /*0x110*/ oMarioBurnTimer OBJECT_FIELD_S32(0x22)
#define /*0x110*/ oMarioLongJumpIsSlow OBJECT_FIELD_S32(0x22)
#define /*0x110*/ oMarioSteepJumpYaw OBJECT_FIELD_S32(0x22)
#define /*0x110*/ oMarioWalkingPitch OBJECT_FIELD_S32(0x22)
#define /*0x0F4*/ oMarioParticleFlags OBJECT_FIELD_S32(0x1B)
#define /*0x108*/ oMarioPoleUnk108 OBJECT_FIELD_S32(0x20)
#define /*0x108*/ oMarioReadingSignDYaw OBJECT_FIELD_S32(0x20)
#define /*0x10C*/ oMarioPoleYawVel OBJECT_FIELD_S32(0x21)
#define /*0x10C*/ oMarioCannonObjectYaw OBJECT_FIELD_S32(0x21)
#define /*0x10C*/ oMarioTornadoYawVel OBJECT_FIELD_S32(0x21)
#define /*0x10C*/ oMarioReadingSignDPosX OBJECT_FIELD_F32(0x21)
#define /*0x110*/ oMarioPolePos OBJECT_FIELD_F32(0x22)
#define /*0x110*/ oMarioCannonInputYaw OBJECT_FIELD_S32(0x22)
#define /*0x110*/ oMarioTornadoPosY OBJECT_FIELD_F32(0x22)
#define /*0x110*/ oMarioReadingSignDPosZ OBJECT_FIELD_F32(0x22)
#define /*0x110*/ oMarioWhirlpoolPosY OBJECT_FIELD_F32(0x22)
#define /*0x110*/ oMarioJumboStarCutscenePosZ OBJECT_FIELD_F32(0x22)
#define /*0x110*/ oMarioBurnTimer OBJECT_FIELD_S32(0x22)
#define /*0x110*/ oMarioLongJumpIsSlow OBJECT_FIELD_S32(0x22)
#define /*0x110*/ oMarioSteepJumpYaw OBJECT_FIELD_S32(0x22)
#define /*0x110*/ oMarioWalkingPitch OBJECT_FIELD_S32(0x22)
/* 1-Up Hidden */
#define /*0x0F4*/ o1UpHiddenUnkF4 OBJECT_FIELD_S32(0x1B)

View file

@ -21,27 +21,34 @@
struct Controller
{
/*0x00*/ s16 rawStickX; //
/*0x02*/ s16 rawStickY; //
/*0x04*/ f32 stickX; // [-64, 64] positive is right
/*0x08*/ f32 stickY; // [-64, 64] positive is up
/*0x0C*/ f32 stickMag; // distance from center [0, 64]
/*0x10*/ u16 buttonDown;
/*0x12*/ u16 buttonPressed;
/*0x14*/ u16 buttonReleased;
/*0x18*/ OSContStatus *statusData;
/*0x1C*/ OSContPad *controllerData;
/*0x20*/ s32 port;
/*ext */ s16 extStickX; // additional (right) stick values
/*ext */ s16 extStickY;
// For optimization reasons, See MarioState
s32 port;
f32 stickX; // [-64, 64] positive is right
f32 stickY; // [-64, 64] positive is up
f32 stickMag; // distance from center [0, 64]
s16 rawStickX;
s16 rawStickY;
s16 extStickX; // additional (right) stick values
s16 extStickY;
u16 buttonDown;
u16 buttonPressed;
u16 buttonReleased;
OSContStatus *statusData;
OSContPad *controllerData;
};
typedef f32 Vec2f[2];
typedef f32 Vec2f[2]; // X, Y
typedef s16 Vec2s[2];
typedef s32 Vec2i[2];
typedef f32 Vec3f[3]; // X, Y, Z, where Y is up
typedef s16 Vec3s[3];
typedef s32 Vec3i[3];
typedef f32 Vec4f[4];
typedef f32 Vec4f[4]; // X, Y, Z, W
typedef s16 Vec4s[4];
typedef s32 Vec4i[4];
typedef f32 Mat4[4][4];
@ -95,88 +102,116 @@ struct VblankHandler
#define ANIM_FLAG_7 (1 << 7) // 0x80
struct Animation {
/*0x00*/ s16 flags;
/*0x02*/ s16 animYTransDivisor;
/*0x04*/ s16 startFrame;
/*0x06*/ s16 loopStart;
/*0x08*/ s16 loopEnd;
/*0x0A*/ s16 unusedBoneCount;
/*0x0C*/ u16 *values;
/*0x10*/ u16 *index;
/*0x14*/ u32 length; // only used with Mario animations to determine how much to load. 0 otherwise.
/*????*/ u32 valuesLength;
/*????*/ u32 indexLength;
// TODO: Optimize this later if possible.
s16 flags;
s16 animYTransDivisor;
s16 startFrame;
s16 loopStart;
s16 loopEnd;
s16 unusedBoneCount;
u16 *values;
u16 *index;
u32 length; // only used with Mario animations to determine how much to load. 0 otherwise.
u32 valuesLength;
u32 indexLength;
};
struct AnimationTable {
u32 count;
const struct Animation* const anims[];
const struct Animation *const anims[];
};
#define ANIMINDEX_NUMPARTS(animindex) (sizeof(animindex) / sizeof(u16) / 6 - 1)
#define ANIM_FIELD_LENGTH(animindex) (sizeof(animindex) / sizeof(u16))
#define GRAPH_NODE_GUARD 0xAA
#define GRAPH_NODE_GUARD 0xDEADBEEF
struct GraphNode
{
s16 type; // structure type
s16 flags; // hi = drawing layer, lo = rendering modes
// For optimization reasons, See MarioState
#ifdef DEBUG
uintptr_t _guard1;
#endif
struct GraphNode *prev;
u8 _guard1;
struct GraphNode *next;
u8 _guard2;
struct GraphNode *parent;
struct GraphNode *children;
const void *georef;
s16 type; // structure type
s16 flags; // hi = drawing layer, lo = rendering modes
u8 extraFlags;
u8 hookProcess;
s16 padding;
#ifdef DEBUG
uintptr_t _guard2;
#endif
};
struct AnimInfo
{
/*0x00 0x38*/ s16 animID;
/*0x02 0x3A*/ s16 animYTrans;
/*0x04 0x3C*/ struct Animation *curAnim;
/*0x08 0x40*/ s16 animFrame;
/*0x0A 0x42*/ u16 animTimer;
/*0x0C 0x44*/ s32 animFrameAccelAssist;
/*0x10 0x48*/ s32 animAccel;
s16 prevAnimFrame;
s16 prevAnimID;
u32 prevAnimFrameTimestamp;
// For optimization reasons, See MarioState
struct Animation *curAnim;
struct Animation *prevAnimPtr;
s16 animID;
s16 prevAnimID;
s16 animFrame;
s16 prevAnimFrame;
u32 prevAnimFrameTimestamp;
s32 animFrameAccelAssist;
s32 animAccel;
u16 animTimer;
s16 animYTrans;
};
struct GraphNodeObject
{
/*0x00*/ struct GraphNode node;
/*0x14*/ struct GraphNode *sharedChild;
/*0x18*/ s8 areaIndex;
/*0x19*/ s8 activeAreaIndex;
/*0x1A*/ Vec3s angle;
/*0x20*/ Vec3f pos;
// For optimization reasons, See MarioState
struct GraphNode node;
struct GraphNode *sharedChild;
struct SpawnInfo *unk4C;
Mat4 *throwMatrix; // matrix ptr
Mat4 *throwMatrixPrev;
Mat4 prevThrowMatrix;
Vec3s angle;
Vec3s prevAngle;
Vec3f pos;
Vec3f prevPos;
u32 prevTimestamp;
Vec3f shadowPos;
Vec3f prevShadowPos;
Vec3f scale;
Vec3f prevScale;
Vec3f cameraToObject;
u32 prevTimestamp;
u32 prevShadowPosTimestamp;
u32 prevScaleTimestamp;
u32 prevThrowMatrixTimestamp;
u32 skipInterpolationTimestamp;
struct AnimInfo animInfo;
s8 areaIndex;
s8 activeAreaIndex;
bool shadowInvisible;
bool disableAutomaticShadowPos;
/*0x2C*/ Vec3f scale;
Vec3f prevScale;
u32 prevScaleTimestamp;
/*0x38*/ struct AnimInfo animInfo;
/*0x4C*/ struct SpawnInfo *unk4C;
/*0x50*/ Mat4 *throwMatrix; // matrix ptr
Mat4 prevThrowMatrix;
u32 prevThrowMatrixTimestamp;
Mat4 *throwMatrixPrev;
/*0x54*/ Vec3f cameraToObject;
u32 skipInterpolationTimestamp;
bool skipInViewCheck;
bool inited;
};
@ -198,25 +233,73 @@ struct ObjectNode
struct Object
{
/*0x000*/ struct ObjectNode header;
/*0x068*/ struct Object *parentObj;
/*0x06C*/ struct Object *prevObj;
/*0x070*/ u32 collidedObjInteractTypes;
/*0x074*/ s16 activeFlags;
/*0x076*/ s16 numCollidedObjs;
/*0x078*/ struct Object *collidedObjs[4];
/*0x088*/
// For optimization reasons, See MarioState
struct ObjectNode header;
struct Object *prevObj;
struct Object *parentObj;
struct Object *usingObj;
struct Object *platform;
struct Object *collidedObjs[4];
Collision *collisionData;
void *respawnInfo;
void (*areaTimerRunOnceCallback)(void);
const BehaviorScript *behavior;
const BehaviorScript *curBhvCommand;
uintptr_t bhvStack[OBJECT_MAX_BHV_STACK];
u32 bhvStackIndex;
s16 bhvDelayTimer;
s16 activeFlags;
u32 collidedObjInteractTypes;
s16 numCollidedObjs;
s16 respawnInfoType;
f32 hitboxRadius;
f32 hitboxHeight;
f32 hurtboxRadius;
f32 hurtboxHeight;
f32 hitboxDownOffset;
u32 unused1;
u32 areaTimer;
u32 areaTimerDuration;
enum AreaTimerType areaTimerType;
Mat4 transform;
u32 firstSurface;
u32 numSurfaces;
u32 heldByPlayerIndex;
u8 setHome;
u8 ctx;
u8 allowRemoteInteractions;
u8 globalPlayerIndex;
u8 coopFlags;
u8 hookRender;
union
{
// Object fields. See object_fields.h.
u16 asU16[OBJECT_NUM_FIELDS][2];
s16 asS16[OBJECT_NUM_FIELDS][2];
u32 asU32[OBJECT_NUM_FIELDS];
s32 asS32[OBJECT_NUM_FIELDS];
s16 asS16[OBJECT_NUM_FIELDS][2];
f32 asF32[OBJECT_NUM_FIELDS];
} rawData;
union {
union
{
s16 *asS16P[OBJECT_NUM_FIELDS];
u16 *asU16P[OBJECT_NUM_FIELDS];
s32 *asS32P[OBJECT_NUM_FIELDS];
u32 *asU32P[OBJECT_NUM_FIELDS];
f32 *asF32P[OBJECT_NUM_FIELDS];
struct AnimationTable *asAnims[OBJECT_NUM_FIELDS];
struct Waypoint *asWaypoint[OBJECT_NUM_FIELDS];
struct ChainSegment *asChainSegment[OBJECT_NUM_FIELDS];
@ -225,49 +308,19 @@ struct Object
void *asVoidPtr[OBJECT_NUM_FIELDS];
const void *asConstVoidPtr[OBJECT_NUM_FIELDS];
} ptrData;
/*0x1C8*/ u32 unused1;
/*0x1CC*/ const BehaviorScript *curBhvCommand;
/*0x1D0*/ u32 bhvStackIndex;
/*0x1D4*/ uintptr_t bhvStack[OBJECT_MAX_BHV_STACK];
/*0x1F4*/ s16 bhvDelayTimer;
/*0x1F6*/ s16 respawnInfoType;
/*0x1F8*/ f32 hitboxRadius;
/*0x1FC*/ f32 hitboxHeight;
/*0x200*/ f32 hurtboxRadius;
/*0x204*/ f32 hurtboxHeight;
/*0x208*/ f32 hitboxDownOffset;
/*0x20C*/ const BehaviorScript *behavior;
/*0x210*/ u32 heldByPlayerIndex;
/*0x214*/ struct Object *platform;
/*0x218*/ Collision *collisionData;
/*0x21C*/ Mat4 transform;
/*0x25C*/ void *respawnInfo;
/*?????*/ u8 coopFlags;
/*?????*/ enum AreaTimerType areaTimerType;
/*?????*/ u32 areaTimer;
/*?????*/ u32 areaTimerDuration;
/*?????*/ void (*areaTimerRunOnceCallback)(void);
/*?????*/ u8 globalPlayerIndex;
/*?????*/ struct Object* usingObj;
/*?????*/ u8 hookRender;
/*?????*/ u8 setHome;
/*?????*/ u8 allowRemoteInteractions;
/*?????*/ u8 ctx;
/*?????*/ u32 firstSurface;
/*?????*/ u32 numSurfaces;
};
struct ObjectHitbox
{
/*0x00*/ u32 interactType;
/*0x04*/ u8 downOffset;
/*0x05*/ s8 damageOrCoinValue;
/*0x06*/ s8 health;
/*0x07*/ s8 numLootCoins;
/*0x08*/ s16 radius;
/*0x0A*/ s16 height;
/*0x0C*/ s16 hurtboxRadius;
/*0x0E*/ s16 hurtboxHeight;
u32 interactType;
s8 health;
s8 damageOrCoinValue;
s8 numLootCoins;
u8 downOffset;
s16 radius;
s16 height;
s16 hurtboxRadius;
s16 hurtboxHeight;
};
struct Waypoint
@ -278,58 +331,70 @@ struct Waypoint
struct Surface
{
/*0x00*/ s16 type;
/*0x02*/ s16 force;
/*0x04*/ s8 flags;
/*0x05*/ s8 room;
/*0x06*/ s16 lowerY;
/*0x08*/ s16 upperY;
/*0x0A*/ Vec3s vertex1;
/*0x10*/ Vec3s vertex2;
/*0x16*/ Vec3s vertex3;
/*0x1C*/ struct {
f32 x;
f32 y;
f32 z;
} normal;
/*0x28*/ f32 originOffset;
/*0x2C*/ struct Object *object;
// For optimization reasons, See MarioState
s16 type;
s8 flags;
s8 room;
s16 force;
s16 lowerY;
s16 upperY;
Vec3s vertex1;
Vec3s vertex2;
Vec3s vertex3;
Vec3s prevVertex1;
Vec3s prevVertex2;
Vec3s prevVertex3;
struct {
f32 x;
f32 y;
f32 z;
} normal;
f32 originOffset;
u32 modifiedTimestamp;
struct Object *object;
};
struct MarioBodyState
{
/*0x00*/ u32 action;
/*0x04*/ s8 capState; /// see MarioCapGSCId
/*0x05*/ s8 eyeState;
/*0x06*/ s8 handState;
/*0x07*/ s8 wingFlutter; /// whether Mario's wing cap wings are fluttering
/*0x08*/ s16 modelState;
/*0x0A*/ s8 grabPos;
/*0x0B*/ u8 punchState; /// 2 bits for type of punch, 6 bits for punch animation timer
/*0x0C*/ Vec3s torsoAngle;
/*0x12*/ Vec3s headAngle;
/*0x18*/ Vec3f heldObjLastPosition; /// also known as HOLP
/*????*/ Vec3f torsoPos;
/*????*/ Vec3f handFootPos[4];
/*????*/ u32 updateTorsoTime;
/*????*/ Vec3f headPos;
/*????*/ u32 updateHeadPosTime;
/*????*/ u16 shadeR; /// shadow red value
/*????*/ u16 shadeG; /// shadow green value
/*????*/ u16 shadeB; /// shadow blue value
/*????*/ u16 lightR; /// light red value
/*????*/ u16 lightG; /// light green value
/*????*/ u16 lightB; /// light blue value
/*????*/ f32 lightingDirX;
/*????*/ f32 lightingDirY;
/*????*/ f32 lightingDirZ;
/*????*/ u8 allowPartRotation;
/*????*/ bool mirrorMario; // some of these fields are updated for Mirror Mario too
// u8 padding[4];
// For optimization reasons, See MarioState
s8 capState; /// see MarioCapGSCId
s8 eyeState;
s8 handState;
u8 punchState; /// 2 bits for type of punch, 6 bits for punch animation timer
s16 modelState;
u8 allowPartRotation;
s8 grabPos;
s8 wingFlutter; /// whether Mario's wing cap wings are fluttering
bool mirrorMario; // some of these fields are updated for Mirror Mario too
Vec3s headAngle;
Vec3s torsoAngle;
Vec3f headPos;
Vec3f torsoPos;
Vec3f handFootPos[4];
Vec3f heldObjLastPosition; /// also known as HOLP
u32 updateTorsoTime;
u32 updateHeadPosTime;
u32 action;
u16 shadeR; /// shadow red value
u16 shadeG; /// shadow green value
u16 shadeB; /// shadow blue value
u16 lightR; /// light red value
u16 lightG; /// light green value
u16 lightB; /// light blue value
f32 lightingDirX;
f32 lightingDirY;
f32 lightingDirZ;
};
struct OffsetSizePair
@ -350,7 +415,6 @@ struct MarioAnimation
struct MarioAnimDmaRelatedThing *animDmaTable;
u8 *currentAnimAddr;
struct Animation *targetAnim;
u8 padding[4];
};
struct MarioState
@ -472,11 +536,11 @@ struct MarioState
struct TextureInfo
{
u8* texture;
u8 bitSize;
u8 *texture;
const char *name;
u32 width;
u32 height;
const char* name;
u8 bitSize;
};
#define PLAY_MODE_NORMAL 0

View file

@ -34,8 +34,10 @@ void init_scene_graph_node_links(struct GraphNode *graphNode, s32 type) {
graphNode->children = NULL;
graphNode->georef = NULL;
graphNode->hookProcess = 0;
#ifdef DEBUG
graphNode->_guard1 = GRAPH_NODE_GUARD;
graphNode->_guard2 = GRAPH_NODE_GUARD;
#endif
}
/**

View file

@ -7,6 +7,20 @@
#include "trig_tables.inc.c"
Mat4 gMat4Identity = {
{ 1, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 1 },
};
Mat4 gMat4Zero = {
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
};
// These functions have bogus return values.
// Disable the compiler warning.
#pragma GCC diagnostic push
@ -20,170 +34,50 @@ inline f32 coss(s16 sm64Angle) {
return gCosineTable[(u16) (sm64Angle) >> 4];
}
/// Copy vector 'src' to 'dest'
void *vec3f_copy(Vec3f dest, Vec3f src) {
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
return dest;
}
/// Set vector 'dest' to (x, y, z)
void *vec3f_set(Vec3f dest, f32 x, f32 y, f32 z) {
dest[0] = x;
dest[1] = y;
dest[2] = z;
return dest;
}
/// Add vector 'a' to 'dest'
void *vec3f_add(Vec3f dest, Vec3f a) {
dest[0] += a[0];
dest[1] += a[1];
dest[2] += a[2];
return dest;
}
/// Make 'dest' the sum of vectors a and b.
void *vec3f_sum(Vec3f dest, Vec3f a, Vec3f b) {
dest[0] = a[0] + b[0];
dest[1] = a[1] + b[1];
dest[2] = a[2] + b[2];
return dest;
}
/// Multiply vector 'dest' by a
void *vec3f_mul(Vec3f dest, f32 a) {
dest[0] *= a;
dest[1] *= a;
dest[2] *= a;
return dest;
}
/// Copy vector src to dest
void *vec3s_copy(Vec3s dest, Vec3s src) {
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
return dest;
}
/// Set vector 'dest' to (x, y, z)
void *vec3s_set(Vec3s dest, s16 x, s16 y, s16 z) {
dest[0] = x;
dest[1] = y;
dest[2] = z;
return dest;
}
/// Add vector a to 'dest'
void *vec3s_add(Vec3s dest, Vec3s a) {
dest[0] += a[0];
dest[1] += a[1];
dest[2] += a[2];
return dest;
}
/// Make 'dest' the sum of vectors a and b.
void *vec3s_sum(Vec3s dest, Vec3s a, Vec3s b) {
dest[0] = a[0] + b[0];
dest[1] = a[1] + b[1];
dest[2] = a[2] + b[2];
return dest;
}
/// Make 'dest' the difference of vectors a and b.
void *vec3f_dif(Vec3f dest, Vec3f a, Vec3f b) {
dest[0] = a[0] - b[0];
dest[1] = a[1] - b[1];
dest[2] = a[2] - b[2];
return dest;
}
/// Convert short vector a to float vector 'dest'
void *vec3s_to_vec3f(Vec3f dest, Vec3s a) {
dest[0] = a[0];
dest[1] = a[1];
dest[2] = a[2];
return dest;
}
/**
* Convert float vector a to a short vector 'dest' by rounding the components
* to the nearest integer.
*/
void *vec3f_to_vec3s(Vec3s dest, Vec3f a) {
// add/subtract 0.5 in order to round to the nearest s32 instead of truncating
dest[0] = a[0] + ((a[0] > 0) ? 0.5f : -0.5f);
dest[1] = a[1] + ((a[1] > 0) ? 0.5f : -0.5f);
dest[2] = a[2] + ((a[2] > 0) ? 0.5f : -0.5f);
return dest;
}
/**
* Set 'dest' the normal vector of a triangle with vertices a, b and c.
* It is similar to vec3f_cross, but it calculates the vectors (c-b) and (b-a)
* at the same time.
*/
void *find_vector_perpendicular_to_plane(Vec3f dest, Vec3f a, Vec3f b, Vec3f c) {
OPTIMIZE_O3 f32 *find_vector_perpendicular_to_plane(Vec3f dest, Vec3f a, Vec3f b, Vec3f c) {
dest[0] = (b[1] - a[1]) * (c[2] - b[2]) - (c[1] - b[1]) * (b[2] - a[2]);
dest[1] = (b[2] - a[2]) * (c[0] - b[0]) - (c[2] - b[2]) * (b[0] - a[0]);
dest[2] = (b[0] - a[0]) * (c[1] - b[1]) - (c[0] - b[0]) * (b[1] - a[1]);
return dest;
}
/// Make vector 'dest' the cross product of vectors a and b.
void *vec3f_cross(Vec3f dest, Vec3f a, Vec3f b) {
dest[0] = a[1] * b[2] - b[1] * a[2];
dest[1] = a[2] * b[0] - b[2] * a[0];
dest[2] = a[0] * b[1] - b[0] * a[1];
return dest;
#pragma GCC diagnostic pop
OPTIMIZE_O3 f32 *vec3f_project(Vec3f vec, Vec3f onto, Vec3f out) {
f32 numerator = vec3f_dot(vec, onto);
f32 denominator = vec3f_dot(onto, onto);
if (denominator == 0) {
return vec3f_zero(out);
}
vec3f_copy(out, onto);
vec3f_mul(out, numerator / denominator);
return out;
}
/// Scale vector 'dest' so it has length 1
void *vec3f_normalize(Vec3f dest) {
f32 div = sqrtf(dest[0] * dest[0] + dest[1] * dest[1] + dest[2] * dest[2]);
OPTIMIZE_O3 f32 *vec3f_normalize(Vec3f dest) {
f32 div = vec3f_length(dest);
if (div == 0) {
dest[0] = 0;
dest[1] = 0;
dest[2] = 0;
vec3f_set(dest, 0, 0, 0);
return dest;
}
f32 invsqrt = 1.0f / div;
dest[0] *= invsqrt;
dest[1] *= invsqrt;
dest[2] *= invsqrt;
vec3f_mul(dest, invsqrt);
return dest;
}
/// Get length of vector 'a'
f32 vec3f_length(Vec3f a)
{
return sqrtf(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
}
/// Get dot product of vectors 'a' and 'b'
f32 vec3f_dot(Vec3f a, Vec3f b)
{
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
/// takes respective scales of vecA and vecB, and sums them
void vec3f_combine(Vec3f dest, Vec3f vecA, Vec3f vecB, f32 sclA, f32 sclB) {
int i = 0;
for (i = 0; i < 3; ++i) {
dest[i] = vecA[i] * sclA + vecB[i] * sclB;
}
}
/**
* Returns a vector rotated around the z axis, then the x axis, then the y
* axis.
*/
void *vec3f_rotate_zxy(Vec3f dest, Vec3s rotate) {
OPTIMIZE_O3 f32 *vec3f_rotate_zxy(Vec3f dest, Vec3s rotate) {
Vec3f v = { dest[0], dest[1], dest[2] };
f32 sx = sins(rotate[0]);
@ -203,46 +97,32 @@ void *vec3f_rotate_zxy(Vec3f dest, Vec3s rotate) {
dest[0] = v[0] * ((sysz * sx) + cycz) + v[1] * ((sycz * sx) - cysz) + v[2] * (cx * sy);
dest[1] = v[0] * (cx * sz) + v[1] * (cx * cz) + v[2] * -sx;
dest[2] = v[0] * ((cysz * sx) - sycz) + v[1] * ((cycz * sx) + sysz) + v[2] * (cx * cy);
return dest;
}
#pragma GCC diagnostic pop
/**
* Take the vector starting at 'from' pointed at 'to' an retrieve the length
* of that vector, as well as the yaw and pitch angles.
* Basically it converts the direction to spherical coordinates.
*/
OPTIMIZE_O3 void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *yaw) {
f32 x = to[0] - from[0];
f32 y = to[1] - from[1];
f32 z = to[2] - from[2];
/// Copy matrix 'src' to 'dest'
void mtxf_copy(Mat4 dest, Mat4 src) {
register s32 i;
register u32 *d = (u32 *) dest;
register u32 *s = (u32 *) src;
for (i = 0; i < 16; i++) {
*d++ = *s++;
}
*dist = sqrtf(x * x + y * y + z * z);
*pitch = atan2s(sqrtf(x * x + z * z), y);
*yaw = atan2s(z, x);
}
/**
* Set mtx to the identity matrix
* Construct the 'to' point which is distance 'dist' away from the 'from' position,
* and has the angles pitch and yaw.
*/
void mtxf_identity(Mat4 mtx) {
register s32 i;
register f32 *dest;
// These loops must be one line to match on -O2
// initialize everything except the first and last cells to 0
for (dest = (f32 *) mtx + 1, i = 0; i < 14; dest++, i++) *dest = 0;
// initialize the diagonal cells to 1
for (dest = (f32 *) mtx, i = 0; i < 4; dest += 5, i++) *dest = 1;
}
/**
* Set dest to a translation matrix of vector b
*/
void mtxf_translate(Mat4 dest, Vec3f b) {
mtxf_identity(dest);
dest[3][0] = b[0];
dest[3][1] = b[1];
dest[3][2] = b[2];
OPTIMIZE_O3 void vec3f_set_dist_and_angle(Vec3f from, Vec3f to, f32 dist, s16 pitch, s16 yaw) {
to[0] = from[0] + dist * coss(pitch) * sins(yaw);
to[1] = from[1] + dist * sins(pitch);
to[2] = from[2] + dist * coss(pitch) * coss(yaw);
}
/**
@ -251,7 +131,7 @@ void mtxf_translate(Mat4 dest, Vec3f b) {
* at the position 'to'. The up-vector is assumed to be (0, 1, 0), but the 'roll'
* angle allows a bank rotation of the camera.
*/
void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll) {
OPTIMIZE_O3 void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll) {
Vec3f forward, right, up;
f32 sinRoll, cosRoll;
f32 dx, dz, xzDist;
@ -319,15 +199,15 @@ void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll) {
* Build a matrix that rotates around the z axis, then the x axis, then the y
* axis, and then translates.
*/
void mtxf_rotate_zxy_and_translate(Mat4 dest, Vec3f translate, Vec3s rotate) {
register f32 sx = sins(rotate[0]);
register f32 cx = coss(rotate[0]);
OPTIMIZE_O3 void mtxf_rotate_zxy_and_translate(Mat4 dest, Vec3f translate, Vec3s rotate) {
f32 sx = sins(rotate[0]);
f32 cx = coss(rotate[0]);
register f32 sy = sins(rotate[1]);
register f32 cy = coss(rotate[1]);
f32 sy = sins(rotate[1]);
f32 cy = coss(rotate[1]);
register f32 sz = sins(rotate[2]);
register f32 cz = coss(rotate[2]);
f32 sz = sins(rotate[2]);
f32 cz = coss(rotate[2]);
dest[0][0] = cy * cz + sx * sy * sz;
dest[1][0] = -cy * sz + sx * sy * cz;
@ -352,15 +232,15 @@ void mtxf_rotate_zxy_and_translate(Mat4 dest, Vec3f translate, Vec3s rotate) {
* Build a matrix that rotates around the x axis, then the y axis, then the z
* axis, and then translates.
*/
void mtxf_rotate_xyz_and_translate(Mat4 dest, Vec3f b, Vec3s c) {
register f32 sx = sins(c[0]);
register f32 cx = coss(c[0]);
OPTIMIZE_O3 void mtxf_rotate_xyz_and_translate(Mat4 dest, Vec3f b, Vec3s c) {
f32 sx = sins(c[0]);
f32 cx = coss(c[0]);
register f32 sy = sins(c[1]);
register f32 cy = coss(c[1]);
f32 sy = sins(c[1]);
f32 cy = coss(c[1]);
register f32 sz = sins(c[2]);
register f32 cz = coss(c[2]);
f32 sz = sins(c[2]);
f32 cz = coss(c[2]);
dest[0][0] = cy * cz;
dest[0][1] = cy * sz;
@ -389,7 +269,7 @@ void mtxf_rotate_xyz_and_translate(Mat4 dest, Vec3f b, Vec3s c) {
* 'position' is the position of the object in the world
* 'angle' rotates the object while still facing the camera.
*/
void mtxf_billboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle) {
OPTIMIZE_O3 void mtxf_billboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle) {
dest[0][0] = coss(angle);
dest[0][1] = sins(angle);
dest[0][2] = 0;
@ -415,7 +295,7 @@ void mtxf_billboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle) {
}
// straight up mtxf_billboard but minus the dest[1][n] lines. transform for cylindrical billboards
void mtxf_cylboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle) {
OPTIMIZE_O3 void mtxf_cylboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle) {
dest[0][0] = coss(angle);
dest[0][1] = sins(angle);
dest[0][2] = 0;
@ -447,7 +327,7 @@ void mtxf_cylboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle) {
* 'yaw' is the angle which it should face
* 'pos' is the object's position in the world
*/
void mtxf_align_terrain_normal(Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw) {
OPTIMIZE_O3 void mtxf_align_terrain_normal(Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw) {
Vec3f lateralDir;
Vec3f leftDir;
Vec3f forwardDir;
@ -490,7 +370,7 @@ void mtxf_align_terrain_normal(Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw) {
* 'pos' is the object's position in the world
* 'radius' is the distance from each triangle vertex to the center
*/
void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s16 yaw, f32 radius) {
OPTIMIZE_O3 void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s16 yaw, f32 radius) {
struct Surface *sp74;
Vec3f point0;
Vec3f point1;
@ -557,69 +437,21 @@ void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s16 yaw, f32 radius) {
}
/**
* Sets matrix 'dest' to the matrix product b * a assuming they are both
* transformation matrices with a w-component of 1. Since the bottom row
* is assumed to equal [0, 0, 0, 1], it saves some multiplications and
* addition.
* Sets matrix 'dest' to the matrix product b * a.
* The resulting matrix represents first applying transformation b and
* then a.
*/
void mtxf_mul(Mat4 dest, Mat4 a, Mat4 b) {
Mat4 temp;
register f32 entry0;
register f32 entry1;
register f32 entry2;
// column 0
entry0 = a[0][0];
entry1 = a[0][1];
entry2 = a[0][2];
temp[0][0] = entry0 * b[0][0] + entry1 * b[1][0] + entry2 * b[2][0];
temp[0][1] = entry0 * b[0][1] + entry1 * b[1][1] + entry2 * b[2][1];
temp[0][2] = entry0 * b[0][2] + entry1 * b[1][2] + entry2 * b[2][2];
// column 1
entry0 = a[1][0];
entry1 = a[1][1];
entry2 = a[1][2];
temp[1][0] = entry0 * b[0][0] + entry1 * b[1][0] + entry2 * b[2][0];
temp[1][1] = entry0 * b[0][1] + entry1 * b[1][1] + entry2 * b[2][1];
temp[1][2] = entry0 * b[0][2] + entry1 * b[1][2] + entry2 * b[2][2];
// column 2
entry0 = a[2][0];
entry1 = a[2][1];
entry2 = a[2][2];
temp[2][0] = entry0 * b[0][0] + entry1 * b[1][0] + entry2 * b[2][0];
temp[2][1] = entry0 * b[0][1] + entry1 * b[1][1] + entry2 * b[2][1];
temp[2][2] = entry0 * b[0][2] + entry1 * b[1][2] + entry2 * b[2][2];
// column 3
entry0 = a[3][0];
entry1 = a[3][1];
entry2 = a[3][2];
temp[3][0] = entry0 * b[0][0] + entry1 * b[1][0] + entry2 * b[2][0] + b[3][0];
temp[3][1] = entry0 * b[0][1] + entry1 * b[1][1] + entry2 * b[2][1] + b[3][1];
temp[3][2] = entry0 * b[0][2] + entry1 * b[1][2] + entry2 * b[2][2] + b[3][2];
temp[0][3] = temp[1][3] = temp[2][3] = 0;
temp[3][3] = 1;
mtxf_copy(dest, temp);
}
/**
* Set matrix 'dest' to 'mtx' scaled by vector s
*/
void mtxf_scale_vec3f(Mat4 dest, Mat4 mtx, Vec3f s) {
register s32 i;
for (i = 0; i < 4; i++) {
dest[0][i] = mtx[0][i] * s[0];
dest[1][i] = mtx[1][i] * s[1];
dest[2][i] = mtx[2][i] * s[2];
dest[3][i] = mtx[3][i];
OPTIMIZE_O3 void mtxf_mul(Mat4 dest, Mat4 a, Mat4 b) {
Mat4 tmp;
for (s32 i = 0; i < 4; i++) {
for (s32 j = 0; j < 4; j++) {
tmp[i][j] = a[i][0] * b[0][j] +
a[i][1] * b[1][j] +
a[i][2] * b[2][j] +
a[i][3] * b[3][j];
}
}
mtxf_copy(dest, tmp);
}
/**
@ -627,14 +459,16 @@ void mtxf_scale_vec3f(Mat4 dest, Mat4 mtx, Vec3f s) {
* to the point. Note that the bottom row is assumed to be [0, 0, 0, 1], which is
* true for transformation matrices if the translation has a w component of 1.
*/
void mtxf_mul_vec3s(Mat4 mtx, Vec3s b) {
register f32 x = b[0];
register f32 y = b[1];
register f32 z = b[2];
OPTIMIZE_O3 s16 *mtxf_mul_vec3s(Mat4 mtx, Vec3s b) {
f32 x = b[0];
f32 y = b[1];
f32 z = b[2];
b[0] = x * mtx[0][0] + y * mtx[1][0] + z * mtx[2][0] + mtx[3][0];
b[1] = x * mtx[0][1] + y * mtx[1][1] + z * mtx[2][1] + mtx[3][1];
b[2] = x * mtx[0][2] + y * mtx[1][2] + z * mtx[2][2] + mtx[3][2];
return b;
}
/**
@ -646,7 +480,7 @@ void mtxf_mul_vec3s(Mat4 mtx, Vec3s b) {
* exception. On Wii and Wii U Virtual Console the value will simply be clamped
* and no crashes occur.
*/
void mtxf_to_mtx(Mtx *dest, Mat4 src) {
OPTIMIZE_O3 void mtxf_to_mtx(Mtx *dest, Mat4 src) {
#ifdef AVOID_UB
// Avoid type-casting which is technically UB by calling the equivalent
// guMtxF2L function. This helps little-endian systems, as well.
@ -669,7 +503,7 @@ void mtxf_to_mtx(Mtx *dest, Mat4 src) {
/**
* Set 'mtx' to a transformation matrix that rotates around the z axis.
*/
void mtxf_rotate_xy(Mtx *mtx, s16 angle) {
OPTIMIZE_O3 void mtxf_rotate_xy(Mtx *mtx, s16 angle) {
Mat4 temp;
mtxf_identity(temp);
@ -693,12 +527,11 @@ void mtxf_rotate_xy(Mtx *mtx, s16 angle) {
* furthermore, this is currently only used to get the inverse of the camera transform
* because that is always orthonormal, the determinant will never be 0, so that check is removed
*/
void mtxf_inverse(register Mat4 dest, register Mat4 src) {
register f32 det_1;
OPTIMIZE_O3 void mtxf_inverse(Mat4 dest, Mat4 src) {
Mat4 buf;
// calculating the determinant has been reduced since the check is removed
det_1 = 1.0f / (
f32 det_1 = 1.0f / (
src[0][0] * src[1][1] * src[2][2]
+ src[0][1] * src[1][2] * src[2][0]
+ src[0][2] * src[1][0] * src[2][1]
@ -726,7 +559,7 @@ void mtxf_inverse(register Mat4 dest, register Mat4 src) {
buf[0][3] = buf[1][3] = buf[2][3] = 0.0f;
buf[3][3] = 1.0f;
memcpy(dest, buf, sizeof(f32) * 4 * 4);
mtxf_copy(dest, buf);
}
/**
@ -737,7 +570,7 @@ void mtxf_inverse(register Mat4 dest, register Mat4 src) {
* objMtx back from screen orientation to world orientation, and then subtracting
* the camera position.
*/
void get_pos_from_transform_mtx(Vec3f dest, Mat4 objMtx, Mat4 camMtx) {
OPTIMIZE_O3 f32 *get_pos_from_transform_mtx(Vec3f dest, Mat4 objMtx, Mat4 camMtx) {
f32 camX = camMtx[3][0] * camMtx[0][0] + camMtx[3][1] * camMtx[0][1] + camMtx[3][2] * camMtx[0][2];
f32 camY = camMtx[3][0] * camMtx[1][0] + camMtx[3][1] * camMtx[1][1] + camMtx[3][2] * camMtx[1][2];
f32 camZ = camMtx[3][0] * camMtx[2][0] + camMtx[3][1] * camMtx[2][1] + camMtx[3][2] * camMtx[2][2];
@ -748,38 +581,15 @@ void get_pos_from_transform_mtx(Vec3f dest, Mat4 objMtx, Mat4 camMtx) {
objMtx[3][0] * camMtx[1][0] + objMtx[3][1] * camMtx[1][1] + objMtx[3][2] * camMtx[1][2] - camY;
dest[2] =
objMtx[3][0] * camMtx[2][0] + objMtx[3][1] * camMtx[2][1] + objMtx[3][2] * camMtx[2][2] - camZ;
}
/**
* Take the vector starting at 'from' pointed at 'to' an retrieve the length
* of that vector, as well as the yaw and pitch angles.
* Basically it converts the direction to spherical coordinates.
*/
void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *yaw) {
register f32 x = to[0] - from[0];
register f32 y = to[1] - from[1];
register f32 z = to[2] - from[2];
*dist = sqrtf(x * x + y * y + z * z);
*pitch = atan2s(sqrtf(x * x + z * z), y);
*yaw = atan2s(z, x);
}
/**
* Construct the 'to' point which is distance 'dist' away from the 'from' position,
* and has the angles pitch and yaw.
*/
void vec3f_set_dist_and_angle(Vec3f from, Vec3f to, f32 dist, s16 pitch, s16 yaw) {
to[0] = from[0] + dist * coss(pitch) * sins(yaw);
to[1] = from[1] + dist * sins(pitch);
to[2] = from[2] + dist * coss(pitch) * coss(yaw);
return dest;
}
/**
* Return the value 'current' after it tries to approach target, going up at
* most 'inc' and going down at most 'dec'.
*/
s32 approach_s32(s32 current, s32 target, s32 inc, s32 dec) {
OPTIMIZE_O3 s32 approach_s32(s32 current, s32 target, s32 inc, s32 dec) {
//! If target is close to the max or min s32, then it's possible to overflow
// past it without stopping.
@ -801,7 +611,7 @@ s32 approach_s32(s32 current, s32 target, s32 inc, s32 dec) {
* Return the value 'current' after it tries to approach target, going up at
* most 'inc' and going down at most 'dec'.
*/
f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec) {
OPTIMIZE_O3 f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec) {
if (current < target) {
current += inc;
if (current > target) {
@ -820,7 +630,7 @@ f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec) {
* Helper function for atan2s. Does a look up of the arctangent of y/x assuming
* the resulting angle is in range [0, 0x2000] (1/8 of a circle).
*/
static u16 atan2_lookup(f32 y, f32 x) {
static OPTIMIZE_O3 u16 atan2_lookup(f32 y, f32 x) {
s16 idx = (s16)(y / x * 1024.0f + 0.5f);
idx = (idx >= 0 && idx < 0x401) ? idx : 0;
return gArctanTable[idx];
@ -893,7 +703,7 @@ f32 atan2f(f32 y, f32 x) {
* [0, 0, 0, 0, 1, 2, ... n-1, n, n, n, n]
* TODO: verify the classification of the spline / figure out how polynomials were computed
*/
void spline_get_weights(struct MarioState* m, Vec4f result, f32 t, UNUSED s32 c) {
OPTIMIZE_O3 void spline_get_weights(struct MarioState* m, Vec4f result, f32 t, UNUSED s32 c) {
if (!m) { return; }
f32 tinv = 1 - t;
f32 tinv2 = tinv * tinv;
@ -943,7 +753,7 @@ void spline_get_weights(struct MarioState* m, Vec4f result, f32 t, UNUSED s32 c)
* The array should end with three entries with s=0 (infinite keyframe duration).
* That's because the spline has a 3rd degree polynomial, so it looks 3 points ahead.
*/
void anim_spline_init(struct MarioState* m, Vec4s *keyFrames) {
OPTIMIZE_O3 void anim_spline_init(struct MarioState* m, Vec4s *keyFrames) {
if (!m) { return; }
m->splineKeyframe = keyFrames;
m->splineKeyframeFraction = 0;
@ -955,7 +765,7 @@ void anim_spline_init(struct MarioState* m, Vec4s *keyFrames) {
* anim_spline_init should be called before polling for vectors.
* Returns TRUE when the last point is reached, FALSE otherwise.
*/
s32 anim_spline_poll(struct MarioState* m, Vec3f result) {
OPTIMIZE_O3 s32 anim_spline_poll(struct MarioState* m, Vec3f result) {
if (!m) { return 0; }
Vec4f weights = { 0 };
s32 i;
@ -996,31 +806,9 @@ s32 anim_spline_poll(struct MarioState* m, Vec3f result) {
/**
* Returns the second value if it does not equal zero.
*/
f32 not_zero(f32 value, f32 replacement) {
OPTIMIZE_O3 f32 not_zero(f32 value, f32 replacement) {
if (replacement != 0) {
return replacement;
}
return value;
}
void vec3f_project(Vec3f vec, Vec3f onto, Vec3f out) {
f32 numerator = vec3f_dot(vec, onto);
f32 denominator = vec3f_dot(onto, onto);
if (denominator == 0) {
out[0] = 0;
out[1] = 0;
out[2] = 0;
return;
}
vec3f_copy(out, onto);
vec3f_mul(out, numerator / denominator);
}
f32 vec3f_dist(Vec3f v1, Vec3f v2) {
Vec3f diff = {
v1[0] - v2[0],
v1[1] - v2[1],
v1[2] - v2[2],
};
return vec3f_length(diff);
}
}

View file

@ -4,6 +4,7 @@
#include <PR/ultratypes.h>
#include "types.h"
#include "pc/platform.h"
/*
* The sine and cosine tables overlap, but "#define gCosineTable (gSineTable +
@ -81,6 +82,9 @@ extern f32 gCosineTable[];
#endif
extern Mat4 gMat4Identity;
extern Mat4 gMat4Zero;
/* |description|
Calculates the sine of the given angle, where the angle is specified as a signed 16-bit integer representing a fixed-point "SM64 angle". This function returns a floating-point result corresponding to sin(angle)
|descriptionEnd| */
@ -91,214 +95,6 @@ Calculates the cosine of the given angle, where the angle is specified as a sign
|descriptionEnd| */
f32 coss(s16 sm64Angle);
#include "../../include/libc/stdlib.h"
/* |description|
Copies the contents of a 3D floating-point vector (`src`) into another 3D floating-point vector (`dest`). After this operation, `dest` will have the same x, y, and z values as `src`
|descriptionEnd| */
void *vec3f_copy(Vec3f dest, Vec3f src);
/* |description|
Sets the values of the 3D floating-point vector `dest` to the given x, y, and z values. After this function, `dest` will have values (x, y, z)
|descriptionEnd| */
void *vec3f_set(Vec3f dest, f32 x, f32 y, f32 z);
/* |description|
Adds the components of the 3D floating-point vector `a` to `dest`. After this operation, `dest.x` will be `dest.x + a.x`, and similarly for the y and z components
|descriptionEnd| */
void *vec3f_add(Vec3f dest, Vec3f a);
/* |description|
Adds the corresponding components of two 3D floating-point vectors `a` and `b`, and stores the result in `dest`. For example, `dest.x = a.x + b.x`, `dest.y = a.y + b.y`, and `dest.z = a.z + b.z`
|descriptionEnd| */
void *vec3f_sum(Vec3f dest, Vec3f a, Vec3f b);
/* |description|
Subtracts the components of the 3D floating-point vector `b` from the components of `a` and stores the result in `dest`. For example, `dest.x = a.x - b.x`
This results in a vector that represents the difference between `a` and `b`.
|descriptionEnd| */
void *vec3f_dif(Vec3f dest, Vec3f a, Vec3f b);
/* |description|
Multiplies each component of the 3D floating-point vector `dest` by the scalar value `a`. For instance, `dest.x = dest.x * a`, and similarly for y and z. This scales the vector `dest` by `a`
|descriptionEnd| */
void *vec3f_mul(Vec3f dest, f32 a);
/* |description|
Copies the components of one 3D signed-integer vector (`src`) to another (`dest`). After this function, `dest` will have the same x, y, and z integer values as `src`
|descriptionEnd| */
void *vec3s_copy(Vec3s dest, Vec3s src);
/* |description|
Sets the 3D signed-integer vector `dest` to the specified integer values (x, y, z), so that `dest` becomes (x, y, z).
|descriptionEnd| */
void *vec3s_set(Vec3s dest, s16 x, s16 y, s16 z);
/* |description|
Adds the components of a 3D signed-integer vector `a` to the corresponding components of `dest`. After this operation, each component of `dest` is increased by the corresponding component in `a`
|descriptionEnd| */
void *vec3s_add(Vec3s dest, Vec3s a);
/* |description|
Adds the components of two 3D signed-integer vectors `a` and `b` together and stores the resulting vector in `dest`. For example, `dest.x = a.x + b.x`, and similarly for y and z
|descriptionEnd| */
void *vec3s_sum(Vec3s dest, Vec3s a, Vec3s b);
/* |description|
Subtracts the components of a 3D signed-integer vector `b` from the components of `a` and stores the result in `dest`. This gives a vector representing the difference `a - b`
|descriptionEnd| */
void *vec3s_sub(Vec3s dest, Vec3s a);
/* |description|
Converts a 3D signed-integer vector `a` (vec3s) into a 3D floating-point vector and stores it in `dest`. After this operation, `dest` will contain the floating-point equivalents of `a`'s integer components
|descriptionEnd| */
void *vec3s_to_vec3f(Vec3f dest, Vec3s a);
/* |description|
Converts a 3D floating-point vector `a` (Vec3f) into a 3D signed-integer vector and stores it in `dest`. After this operation, `dest` will contain the integer versions of `a`'s floating-point components
|descriptionEnd| */
void *vec3f_to_vec3s(Vec3s dest, Vec3f a);
/* |description|
Determines a vector that is perpendicular (normal) to the plane defined by three given 3D floating-point points `a`, `b`, and `c`. The resulting perpendicular vector is stored in `dest`
|descriptionEnd| */
void *find_vector_perpendicular_to_plane(Vec3f dest, Vec3f a, Vec3f b, Vec3f c);
/* |description|
Computes the cross product of two 3D floating-point vectors `a` and `b`. The cross product is a vector perpendicular to both `a` and `b`. The result is stored in `dest`
|descriptionEnd| */
void *vec3f_cross(Vec3f dest, Vec3f a, Vec3f b);
/* |description|
Normalizes the 3D floating-point vector `dest` so that its length (magnitude) becomes 1, while retaining its direction. This effectively scales `dest` so that it lies on the unit sphere
|descriptionEnd| */
void *vec3f_normalize(Vec3f dest);
/* |description|
Calculates the length (magnitude) of the 3D floating-point vector `a`. The length is defined as sqrt(x² + y² + z²) for the vector components (x, y, z)
|descriptionEnd| */
f32 vec3f_length(Vec3f a);
/* |description|
Computes the dot product of the two 3D floating-point vectors `a` and `b`. The dot product is a scalar value defined by (a.x * b.x + a.y * b.y + a.z * b.z), representing how aligned the two vectors are
|descriptionEnd| */
f32 vec3f_dot(Vec3f a, Vec3f b);
/* |description|
Takes two 3D floating-point vectors `vecA` and `vecB`, multiplies them by `sclA` and `sclB` respectively, and then adds the scaled vectors together. The final combined vector is stored in `dest`
|descriptionEnd| */
void vec3f_combine(Vec3f dest, Vec3f vecA, Vec3f vecB, f32 sclA, f32 sclB);
/* |description|
Rotates the 3D floating-point vector `v` by the angles specified in the 3D signed-integer vector `rotate`, applying the rotations in the order Z, then X, then Y. The rotated vector replaces `v`
|descriptionEnd| */
void *vec3f_rotate_zxy(Vec3f v, Vec3s rotate);
/* |description|
Copies the 4x4 floating-point matrix `src` into `dest`. After this operation, `dest` contains the same matrix values as `src`
|descriptionEnd| */
void mtxf_copy(Mat4 dest, Mat4 src);
/* |description|
Sets the 4x4 floating-point matrix `mtx` to the identity matrix. The identity matrix leaves points unchanged when they are transformed by it which is useful for matrix math
|descriptionEnd| */
void mtxf_identity(Mat4 mtx);
/* |description|
Applies a translation to the 4x4 floating-point matrix `dest` by adding the coordinates in the 3D floating-point vector `b`. This shifts any transformed point by `b`
|descriptionEnd| */
void mtxf_translate(Mat4 dest, Vec3f b);
/* |description|
Adjusts the 4x4 floating-point matrix `mtx` so that it represents a viewing transformation looking from the point `from` toward the point `to`, with a given roll angle. This creates a view matrix oriented toward `to`
|descriptionEnd| */
void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll);
/* |description|
Rotates `dest` according to the angles in `rotate` using ZXY order, and then translates it by the 3D floating-point vector `translate`. This effectively positions and orients `dest` in 3D space
|descriptionEnd| */
void mtxf_rotate_zxy_and_translate(Mat4 dest, Vec3f translate, Vec3s rotate);
/* |description|
Rotates `dest` using angles in XYZ order, and then translates it by the 3D floating-point vector `b` and applies the rotations described by `c`. This sets up `dest` with a specific orientation and position in space
|descriptionEnd| */
void mtxf_rotate_xyz_and_translate(Mat4 dest, Vec3f b, Vec3s c);
/* |description|
Transforms a 4x4 floating-point matrix `mtx` into a "billboard" oriented toward the camera or a given direction. The billboard is placed at `position` and rotated by `angle`. This is useful for objects that should always face the viewer
|descriptionEnd| */
void mtxf_billboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle);
/* |description|
Creates a "cylindrical billboard" transformation from the 4x4 matrix `mtx` placed at `position` with a given `angle`. Unlike a full billboard, this might allow rotation around one axis while still facing the viewer on others
|descriptionEnd| */
void mtxf_cylboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle);
/* |description|
Aligns `dest` so that it fits the orientation of a terrain surface defined by its normal vector `upDir`. The transformation is positioned at `pos` and oriented with a given `yaw`. This is often used to make objects sit naturally on uneven ground
|descriptionEnd| */
void mtxf_align_terrain_normal(Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw);
/* |description|
Aligns `mtx` to fit onto a terrain triangle at `pos`, applying a given `yaw` and scaling by `radius`. This helps position objects so they match the orientation of the terrain's surface
|descriptionEnd| */
void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s16 yaw, f32 radius);
/* |description|
Multiplies two 4x4 floating-point matrices `a` and `b` (in that order), storing the product in `dest`. This can be used for combining multiple transformations into one
|descriptionEnd| */
void mtxf_mul(Mat4 dest, Mat4 a, Mat4 b);
/* |description|
Scales the 4x4 floating-point matrix `mtx` by the scaling factors found in the 3D floating-point vector `s`, and stores the result in `dest`. This enlarges or shrinks objects in 3D space
|descriptionEnd| */
void mtxf_scale_vec3f(Mat4 dest, Mat4 mtx, Vec3f s);
/* |description|
Multiplies the 4x4 floating-point matrix `mtx` by a 3D signed-integer vector `b`, potentially interpreting `b` as angles or translations depending on usage, and modifies `mtx` accordingly
|descriptionEnd| */
void mtxf_mul_vec3s(Mat4 mtx, Vec3s b);
/* |description|
Converts the floating-point matrix `src` into a fixed-point (integer-based) matrix suitable for the `Mtx` format, and stores the result in `dest`
|descriptionEnd| */
void mtxf_to_mtx(Mtx *dest, Mat4 src);
/* |description|
Rotates the matrix `mtx` in the XY plane by the given `angle`. Rotating in the XY plane typically means pivoting around the Z axis
|descriptionEnd| */
void mtxf_rotate_xy(Mtx *mtx, s16 angle);
/* |description|
Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Applying the inverse transformation undoes whatever `src` did, returning points back to their original coordinate space
|descriptionEnd| */
void mtxf_inverse(Mat4 dest, Mat4 src);
/* |description|
Extracts the position (translation component) from the transformation matrix `objMtx` relative to the coordinate system defined by `camMtx` and stores that 3D position in `dest`. This can be used to get the object's coordinates in camera space
|descriptionEnd| */
void get_pos_from_transform_mtx(Vec3f dest, Mat4 objMtx, Mat4 camMtx);
/* |description|
Calculates the distance between two points in 3D space (`from` and `to`), as well as the pitch and yaw angles that describe the direction from `from` to `to`. The results are stored in `dist`, `pitch`, and `yaw`
|descriptionEnd| */
void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *yaw);
/* |description|
Positions the point `to` at a given `dist`, `pitch`, and `yaw` relative to the point `from`. This can be used to place objects around a reference point at specific angles and distances
|descriptionEnd| */
void vec3f_set_dist_and_angle(Vec3f from, Vec3f to, f32 dist, s16 pitch, s16 yaw);
/* |description|
Gradually moves an integer `current` value toward a `target` value, increasing it by `inc` if it is too low, or decreasing it by `dec` if it is too high. This is often used for smooth transitions or animations
|descriptionEnd| */
s32 approach_s32(s32 current, s32 target, s32 inc, s32 dec);
/* |description|
Similar to `approach_s32`, but operates on floating-point numbers. It moves `current` toward `target` by increasing it by `inc` if below target, or decreasing it by `dec` if above target, creating a smooth interpolation
|descriptionEnd| */
f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec);
/* |description|
Computes the arctangent of y/x and returns the angle as a signed 16-bit integer, typically representing a direction in the SM64 fixed-point angle format. This can be used to find an angle between x and y coordinates
|descriptionEnd| */
@ -309,35 +105,302 @@ Computes the arctangent of a/b and returns it as a floating-point angle in radia
|descriptionEnd| */
f32 atan2f(f32 a, f32 b);
/* |description|
Computes spline interpolation weights for a given parameter `t` and stores these weights in `result`. This is used in spline-based animations to find intermediate positions between keyframes
|descriptionEnd| */
void spline_get_weights(struct MarioState* m, Vec4f result, f32 t, UNUSED s32 c);
#include "../../include/libc/stdlib.h"
/* |description|
Initializes a spline-based animation for the `MarioState` structure `m` using the provided array of 3D signed-integer vectors `keyFrames`. This sets up the animation so that it can be advanced by polling
Copies the contents of a 3D floating-point vector (`src`) into another 3D floating-point vector (`dest`). After this operation, `dest` will have the same x, y, and z values as `src`
|descriptionEnd| */
void anim_spline_init(struct MarioState* m, Vec4s *keyFrames);
INLINE OPTIMIZE_O3 f32 *vec3f_copy(Vec3f dest, Vec3f src);
/* |description|
Advances the spline-based animation associated with `m` and stores the current interpolated position in `result`. It returns the animation's status, allowing the caller to determine if the animation is ongoing or has completed
Sets the values of the 3D floating-point vector `dest` to the given x, y, and z values. After this function, `dest` will have values (x, y, z)
|descriptionEnd| */
s32 anim_spline_poll(struct MarioState* m, Vec3f result);
INLINE OPTIMIZE_O3 f32 *vec3f_set(Vec3f dest, f32 x, f32 y, f32 z);
/* |description|
Checks if `value` is zero. If not, it returns `value`. If it is zero, it returns the `replacement` value. This function ensures that a zero value can be substituted with a fallback value if needed
Adds the components of the 3D floating-point vector `a` to `dest`. After this operation, `dest.x` will be `dest.x + a.x`, and similarly for the y and z components
|descriptionEnd| */
f32 not_zero(f32 value, f32 replacement);
INLINE OPTIMIZE_O3 f32 *vec3f_add(Vec3f dest, Vec3f a);
/* |description|
Adds the corresponding components of two 3D floating-point vectors `a` and `b`, and stores the result in `dest`. For example, `dest.x = a.x + b.x`, `dest.y = a.y + b.y`, and `dest.z = a.z + b.z`
|descriptionEnd| */
INLINE OPTIMIZE_O3 f32 *vec3f_sum(Vec3f dest, Vec3f a, Vec3f b);
/* |description|
Subtracts the components of the 3D floating-point vector `a` from `dest`. After this operation, `dest.x` will be `dest.x - a.x`, and similarly for the y and z components
|descriptionEnd| */
INLINE OPTIMIZE_O3 f32 *vec3f_sub(Vec3f dest, Vec3f a);
/* |description|
Subtracts the components of the 3D floating-point vector `b` from the components of `a` and stores the result in `dest`. For example, `dest.x = a.x - b.x`
This results in a vector that represents the difference between `a` and `b`.
|descriptionEnd| */
INLINE OPTIMIZE_O3 f32 *vec3f_dif(Vec3f dest, Vec3f a, Vec3f b);
/* |description|
Multiplies each component of the 3D floating-point vector `dest` by the scalar value `a`. For instance, `dest.x = dest.x * a`, and similarly for y and z. This scales the vector `dest` by `a`
|descriptionEnd| */
INLINE OPTIMIZE_O3 f32 *vec3f_mul(Vec3f dest, f32 a);
/* |description|
Divides each component of the 3D floating-point vector `dest` by the scalar value `a`. For instance, `dest.x = dest.x / a`, and similarly for y and z. This scales the vector `dest` by `a`
|descriptionEnd| */
INLINE OPTIMIZE_O3 f32 *vec3f_div(Vec3f dest, f32 a);
/* |description|
Computes the cross product of two 3D floating-point vectors `a` and `b`. The cross product is a vector perpendicular to both `a` and `b`. The result is stored in `dest`
|descriptionEnd| */
INLINE OPTIMIZE_O3 f32 *vec3f_cross(Vec3f dest, Vec3f a, Vec3f b);
/* |description|
Normalizes the 3D floating-point vector `dest` so that its length (magnitude) becomes 1, while retaining its direction. This effectively scales `dest` so that it lies on the unit sphere
|descriptionEnd| */
OPTIMIZE_O3 f32 *vec3f_normalize(Vec3f dest);
/* |description|
Normalizes each component of the 3D floating-point vector 'v'.
|descriptionEnd| */
INLINE OPTIMIZE_O3 f32 *vec3f_normalize2(Vec3f v);
/* |description|
Calculates the length (magnitude) of the 3D floating-point vector `a`. The length is defined as sqrt(x² + y² + z²) for the vector components (x, y, z)
|descriptionEnd| */
INLINE OPTIMIZE_O3 f32 vec3f_length(Vec3f a);
/* |description|
Computes the dot product of the two 3D floating-point vectors `a` and `b`. The dot product is a scalar value defined by (a.x * b.x + a.y * b.y + a.z * b.z), representing how aligned the two vectors are
|descriptionEnd| */
INLINE OPTIMIZE_O3 f32 vec3f_dot(Vec3f a, Vec3f b);
/* |description|
Takes two 3D floating-point vectors `vecA` and `vecB`, multiplies them by `sclA` and `sclB` respectively, and then adds the scaled vectors together. The final combined vector is stored in `dest`
|descriptionEnd| */
INLINE OPTIMIZE_O3 f32 *vec3f_combine(Vec3f dest, Vec3f vecA, Vec3f vecB, f32 sclA, f32 sclB);
/* |description|
Rotates the 3D floating-point vector `v` by the angles specified in the 3D signed-integer vector `rotate`, applying the rotations in the order Z, then X, then Y. The rotated vector replaces `v`
|descriptionEnd| */
OPTIMIZE_O3 f32 *vec3f_rotate_zxy(Vec3f v, Vec3s rotate);
/* |description|
Projects the 3D floating-point vector `vec` onto another 3D floating-point vector `onto`. The resulting projection, stored in `out`, represents how much of `vec` lies along the direction of `onto`
|descriptionEnd| */
void vec3f_project(Vec3f vec, Vec3f onto, Vec3f out);
OPTIMIZE_O3 f32 *vec3f_project(Vec3f vec, Vec3f onto, Vec3f out);
/* |description|
Calculates the distance between two 3D floating-point points `v1` and `v2`. The distance is the length of the vector `v2 - v1`, i.e., sqrt((v2.x - v1.x)² + (v2.y - v1.y)² + (v2.z - v1.z)²)
|descriptionEnd| */
f32 vec3f_dist(Vec3f v1, Vec3f v2);
INLINE OPTIMIZE_O3 f32 vec3f_dist(Vec3f v1, Vec3f v2);
/* |description|
Calculates the distance between two points in 3D space (`from` and `to`), as well as the pitch and yaw angles that describe the direction from `from` to `to`. The results are stored in `dist`, `pitch`, and `yaw`
|descriptionEnd| */
OPTIMIZE_O3 void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *yaw);
/* |description|
Positions the point `to` at a given `dist`, `pitch`, and `yaw` relative to the point `from`. This can be used to place objects around a reference point at specific angles and distances
|descriptionEnd| */
OPTIMIZE_O3 void vec3f_set_dist_and_angle(Vec3f from, Vec3f to, f32 dist, s16 pitch, s16 yaw);
/* |description|
Sets the values of the 3D floating-point vector `v` to 0. After this function, `v` will have values of 0.
|descriptionEnd| */
INLINE OPTIMIZE_O3 f32 *vec3f_zero(Vec3f v);
/* |description|
Converts a 3D floating-point vector `a` (Vec3f) into a 3D signed-integer vector and stores it in `dest`. After this operation, `dest` will contain the integer versions of `a`'s floating-point components
|descriptionEnd| */
INLINE OPTIMIZE_O3 s16 *vec3f_to_vec3s(Vec3s dest, Vec3f a);
/* |description|
Copies the components of one 3D signed-integer vector (`src`) to another (`dest`). After this function, `dest` will have the same x, y, and z integer values as `src`
|descriptionEnd| */
INLINE OPTIMIZE_O3 s16 *vec3s_copy(Vec3s dest, Vec3s src);
/* |description|
Sets the 3D signed-integer vector `dest` to the specified integer values (x, y, z), so that `dest` becomes (x, y, z).
|descriptionEnd| */
INLINE OPTIMIZE_O3 s16 *vec3s_set(Vec3s dest, s16 x, s16 y, s16 z);
/* |description|
Adds the components of a 3D signed-integer vector `a` to the corresponding components of `dest`. After this operation, each component of `dest` is increased by the corresponding component in `a`
|descriptionEnd| */
INLINE OPTIMIZE_O3 s16 *vec3s_add(Vec3s dest, Vec3s a);
/* |description|
Adds the components of two 3D signed-integer vectors `a` and `b` together and stores the resulting vector in `dest`. For example, `dest.x = a.x + b.x`, and similarly for y and z
|descriptionEnd| */
INLINE OPTIMIZE_O3 s16 *vec3s_sum(Vec3s dest, Vec3s a, Vec3s b);
/* |description|
Subtracts the components of a 3D signed-integer vector `b` from the components of `a` and stores the result in `dest`. This gives a vector representing the difference `a - b`
|descriptionEnd| */
INLINE OPTIMIZE_O3 s16 *vec3s_sub(Vec3s dest, Vec3s a);
/* |description|
Subtracts the components of the 3D signed-integer vector `b` from the components of `a` and stores the result in `dest`. For example, `dest.x = a.x - b.x`
This results in a vector that represents the difference between `a` and `b`.
|descriptionEnd| */
INLINE OPTIMIZE_O3 s16 *vec3s_dif(Vec3s dest, Vec3s a, Vec3s b);
/* |description|
Multiplies each component of the 3D signed-integer vector `dest` by the scalar value `a`. For instance, `dest.x = dest.x * a`, and similarly for y and z. This scales the vector `dest` by `a`
|descriptionEnd| */
INLINE OPTIMIZE_O3 s16 *vec3s_mul(Vec3s dest, s16 a);
/* |description|
Divides each component of the 3D signed-integer vector `dest` by the scalar value `a`. For instance, `dest.x = dest.x / a`, and similarly for y and z. This scales the vector `dest` by `a`
|descriptionEnd| */
INLINE OPTIMIZE_O3 s16 *vec3s_div(Vec3s dest, s16 a);
/* |description|
Calculates the length (magnitude) of the 3D signed-integer vector `a`. The length is defined as sqrt(x² + y² + z²) for the vector components (x, y, z)
|descriptionEnd| */
INLINE OPTIMIZE_O3 f32 vec3s_length(Vec3s a);
/* |description|
Calculates the distance between two 3D signed-integer points `v1` and `v2`. The distance is the length of the vector `v2 - v1`, i.e., sqrt((v2.x - v1.x)² + (v2.y - v1.y)² + (v2.z - v1.z)²)
|descriptionEnd| */
INLINE OPTIMIZE_O3 f32 vec3s_dist(Vec3s v1, Vec3s v2);
/* |description|
Sets the values of the 3D signed-integer vector `v` to 0. After this function, `v` will have values of 0.
|descriptionEnd| */
INLINE OPTIMIZE_O3 s16 *vec3s_zero(Vec3s v);
/* |description|
Converts a 3D signed-integer vector `a` (vec3s) into a 3D floating-point vector and stores it in `dest`. After this operation, `dest` will contain the floating-point equivalents of `a`'s integer components
|descriptionEnd| */
INLINE OPTIMIZE_O3 f32 *vec3s_to_vec3f(Vec3f dest, Vec3s a);
/* |description|
Determines a vector that is perpendicular (normal) to the plane defined by three given 3D floating-point points `a`, `b`, and `c`. The resulting perpendicular vector is stored in `dest`
|descriptionEnd| */
OPTIMIZE_O3 f32 *find_vector_perpendicular_to_plane(Vec3f dest, Vec3f a, Vec3f b, Vec3f c);
/* |description|
Copies the 4x4 floating-point matrix `src` into `dest`. After this operation, `dest` contains the same matrix values as `src`
|descriptionEnd| */
INLINE OPTIMIZE_O3 void mtxf_copy(Mat4 dest, Mat4 src);
/* |description|
Sets the 4x4 floating-point matrix `mtx` to the identity matrix. The identity matrix leaves points unchanged when they are transformed by it which is useful for matrix math
|descriptionEnd| */
INLINE OPTIMIZE_O3 void mtxf_identity(Mat4 mtx);
/* |description|
Applies a translation to the 4x4 floating-point matrix `dest` by adding the coordinates in the 3D floating-point vector `b`. This shifts any transformed point by `b`
|descriptionEnd| */
INLINE OPTIMIZE_O3 void mtxf_translate(Mat4 dest, Vec3f b);
/* |description|
Adjusts the 4x4 floating-point matrix `mtx` so that it represents a viewing transformation looking from the point `from` toward the point `to`, with a given roll angle. This creates a view matrix oriented toward `to`
|descriptionEnd| */
OPTIMIZE_O3 void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll);
/* |description|
Rotates `dest` according to the angles in `rotate` using ZXY order, and then translates it by the 3D floating-point vector `translate`. This effectively positions and orients `dest` in 3D space
|descriptionEnd| */
OPTIMIZE_O3 void mtxf_rotate_zxy_and_translate(Mat4 dest, Vec3f translate, Vec3s rotate);
/* |description|
Rotates `dest` using angles in XYZ order, and then translates it by the 3D floating-point vector `b` and applies the rotations described by `c`. This sets up `dest` with a specific orientation and position in space
|descriptionEnd| */
OPTIMIZE_O3 void mtxf_rotate_xyz_and_translate(Mat4 dest, Vec3f b, Vec3s c);
/* |description|
Transforms a 4x4 floating-point matrix `mtx` into a "billboard" oriented toward the camera or a given direction. The billboard is placed at `position` and rotated by `angle`. This is useful for objects that should always face the viewer
|descriptionEnd| */
OPTIMIZE_O3 void mtxf_billboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle);
/* |description|
Creates a "cylindrical billboard" transformation from the 4x4 matrix `mtx` placed at `position` with a given `angle`. Unlike a full billboard, this might allow rotation around one axis while still facing the viewer on others
|descriptionEnd| */
OPTIMIZE_O3 void mtxf_cylboard(Mat4 dest, Mat4 mtx, Vec3f position, s16 angle);
/* |description|
Aligns `dest` so that it fits the orientation of a terrain surface defined by its normal vector `upDir`. The transformation is positioned at `pos` and oriented with a given `yaw`. This is often used to make objects sit naturally on uneven ground
|descriptionEnd| */
OPTIMIZE_O3 void mtxf_align_terrain_normal(Mat4 dest, Vec3f upDir, Vec3f pos, s16 yaw);
/* |description|
Aligns `mtx` to fit onto a terrain triangle at `pos`, applying a given `yaw` and scaling by `radius`. This helps position objects so they match the orientation of the terrain's surface
|descriptionEnd| */
OPTIMIZE_O3 void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s16 yaw, f32 radius);
/* |description|
Multiplies two 4x4 floating-point matrices `a` and `b` (in that order), storing the product in `dest`. This can be used for combining multiple transformations into one
|descriptionEnd| */
OPTIMIZE_O3 void mtxf_mul(Mat4 dest, Mat4 a, Mat4 b);
/* |description|
Scales the 4x4 floating-point matrix `mtx` by the scaling factors found in the 3D floating-point vector `s`, and stores the result in `dest`. This enlarges or shrinks objects in 3D space
|descriptionEnd| */
INLINE OPTIMIZE_O3 void mtxf_scale_vec3f(Mat4 dest, Mat4 mtx, Vec3f s);
/* |description|
Multiplies the 4x4 floating-point matrix `mtx` by a 3D signed-integer vector `b`, potentially interpreting `b` as angles or translations depending on usage, and modifies `mtx` accordingly
|descriptionEnd| */
OPTIMIZE_O3 s16 *mtxf_mul_vec3s(Mat4 mtx, Vec3s b);
/* |description|
Converts the floating-point matrix `src` into a fixed-point (integer-based) matrix suitable for the `Mtx` format, and stores the result in `dest`
|descriptionEnd| */
OPTIMIZE_O3 void mtxf_to_mtx(Mtx *dest, Mat4 src);
/* |description|
Rotates the matrix `mtx` in the XY plane by the given `angle`. Rotating in the XY plane typically means pivoting around the Z axis
|descriptionEnd| */
OPTIMIZE_O3 void mtxf_rotate_xy(Mtx *mtx, s16 angle);
/* |description|
Inverts the 4x4 floating-point matrix `src` and stores the inverse in `dest`. Applying the inverse transformation undoes whatever `src` did, returning points back to their original coordinate space
|descriptionEnd| */
OPTIMIZE_O3 void mtxf_inverse(Mat4 dest, Mat4 src);
/* |description|
Sets the 4x4 floating-point matrix `mtx` to all zeros.
Unless you really need this-It's reccomended to use mtxf_identity instead.
|descriptionEnd| */
INLINE OPTIMIZE_O3 void mtxf_zero(Mat4 mtx);
/* |description|
Extracts the position (translation component) from the transformation matrix `objMtx` relative to the coordinate system defined by `camMtx` and stores that 3D position in `dest`. This can be used to get the object's coordinates in camera space
|descriptionEnd| */
OPTIMIZE_O3 f32 *get_pos_from_transform_mtx(Vec3f dest, Mat4 objMtx, Mat4 camMtx);
/* |description|
Gradually moves an integer `current` value toward a `target` value, increasing it by `inc` if it is too low, or decreasing it by `dec` if it is too high. This is often used for smooth transitions or animations
|descriptionEnd| */
OPTIMIZE_O3 s32 approach_s32(s32 current, s32 target, s32 inc, s32 dec);
/* |description|
Similar to `approach_s32`, but operates on floating-point numbers. It moves `current` toward `target` by increasing it by `inc` if below target, or decreasing it by `dec` if above target, creating a smooth interpolation
|descriptionEnd| */
OPTIMIZE_O3 f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec);
/* |description|
Computes spline interpolation weights for a given parameter `t` and stores these weights in `result`. This is used in spline-based animations to find intermediate positions between keyframes
|descriptionEnd| */
OPTIMIZE_O3 void spline_get_weights(struct MarioState* m, Vec4f result, f32 t, UNUSED s32 c);
/* |description|
Initializes a spline-based animation for the `MarioState` structure `m` using the provided array of 3D signed-integer vectors `keyFrames`. This sets up the animation so that it can be advanced by polling
|descriptionEnd| */
OPTIMIZE_O3 void anim_spline_init(struct MarioState* m, Vec4s *keyFrames);
/* |description|
Advances the spline-based animation associated with `m` and stores the current interpolated position in `result`. It returns the animation's status, allowing the caller to determine if the animation is ongoing or has completed
|descriptionEnd| */
OPTIMIZE_O3 s32 anim_spline_poll(struct MarioState* m, Vec3f result);
/* |description|
Checks if `value` is zero. If not, it returns `value`. If it is zero, it returns the `replacement` value. This function ensures that a zero value can be substituted with a fallback value if needed
|descriptionEnd| */
OPTIMIZE_O3 f32 not_zero(f32 value, f32 replacement);
#include "math_util.inl"
#endif // MATH_UTIL_H

323
src/engine/math_util.inl Normal file
View file

@ -0,0 +1,323 @@
/*
.inl files are for inlined functions and function templates.
It's best to put them in this file so they can be recompiled if needed.
Credit to PeachyPeach, Isaac0, Blockyyy, and others for suggestions
optimizations and bug reports.
*/
#ifndef MATH_UTIL_INL
#define MATH_UTIL_INL
/*
Vec3f Functions
*/
/**
* Copy vector 'src' to 'dest'.
*/
INLINE OPTIMIZE_O3 f32 *vec3f_copy(Vec3f dest, Vec3f src) {
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
return dest;
}
/**
* Set vector 'dest' to (x, y, z).
*/
INLINE OPTIMIZE_O3 f32 *vec3f_set(Vec3f dest, f32 x, f32 y, f32 z) {
dest[0] = x;
dest[1] = y;
dest[2] = z;
return dest;
}
/**
* Add vector 'a' to 'dest'.
*/
INLINE OPTIMIZE_O3 f32 *vec3f_add(Vec3f dest, Vec3f a) {
dest[0] += a[0];
dest[1] += a[1];
dest[2] += a[2];
return dest;
}
/**
* Make 'dest' the sum of vectors a and b.
*/
INLINE OPTIMIZE_O3 f32 *vec3f_sum(Vec3f dest, Vec3f a, Vec3f b) {
dest[0] = a[0] + b[0];
dest[1] = a[1] + b[1];
dest[2] = a[2] + b[2];
return dest;
}
/**
* Subtracts vector a from 'dest'.
*/
INLINE OPTIMIZE_O3 f32 *vec3f_sub(Vec3f dest, Vec3f a) {
if (!dest || !a) { return NULL; }
dest[0] -= a[0];
dest[1] -= a[1];
dest[2] -= a[2];
return dest;
}
/**
* Make 'dest' the difference of vectors a and b.
*/
INLINE OPTIMIZE_O3 f32 *vec3f_dif(Vec3f dest, Vec3f a, Vec3f b) {
dest[0] = a[0] - b[0];
dest[1] = a[1] - b[1];
dest[2] = a[2] - b[2];
return dest;
}
/**
* Multiply vector 'dest' by a.
*/
INLINE OPTIMIZE_O3 f32 *vec3f_mul(Vec3f dest, f32 a) {
dest[0] *= a;
dest[1] *= a;
dest[2] *= a;
return dest;
}
/**
* Divides vector 'dest' by a.
*/
INLINE OPTIMIZE_O3 f32 *vec3f_div(Vec3f dest, f32 a) {
dest[0] /= a;
dest[1] /= a;
dest[2] /= a;
return dest;
}
/**
* Make vector 'dest' the cross product of vectors a and b.
*/
INLINE OPTIMIZE_O3 f32 *vec3f_cross(Vec3f dest, Vec3f a, Vec3f b) {
dest[0] = a[1] * b[2] - b[1] * a[2];
dest[1] = a[2] * b[0] - b[2] * a[0];
dest[2] = a[0] * b[1] - b[0] * a[1];
return dest;
}
/**
* Normalizes each component of the 3D floating-point vector 'v'.
*/
INLINE OPTIMIZE_O3 f32 *vec3f_normalize2(Vec3f v) {
float s = vec3f_length(v);
vec3f_div(v, s);
return v;
}
/**
* Get length of vector 'a'.
*/
INLINE OPTIMIZE_O3 f32 vec3f_length(Vec3f a) {
return sqrtf(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
}
/**
* Get dot product of vectors 'a' and 'b'.
*/
INLINE OPTIMIZE_O3 f32 vec3f_dot(Vec3f a, Vec3f b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
/**
* Takes respective scales of vecA and vecB, and sums them.
*/
INLINE OPTIMIZE_O3 f32 *vec3f_combine(Vec3f dest, Vec3f vecA, Vec3f vecB, f32 sclA, f32 sclB) {
for (s32 i = 0; i < 3; ++i) {
dest[i] = vecA[i] * sclA + vecB[i] * sclB;
}
return dest;
}
/**
* Calculates the distance between point 'v1' and 'v2'.
*/
INLINE OPTIMIZE_O3 f32 vec3f_dist(Vec3f v1, Vec3f v2) {
Vec3f diff;
vec3f_dif(diff, v1, v2);
return vec3f_length(diff);
}
INLINE OPTIMIZE_O3 f32 *vec3f_zero(Vec3f v) {
return vec3f_set(v, 0, 0, 0);
}
/**
* Convert float vector a to a short vector 'dest' by rounding the components
* to the nearest integer.
*/
INLINE OPTIMIZE_O3 s16 *vec3f_to_vec3s(Vec3s dest, Vec3f a) {
// add/subtract 0.5 in order to round to the nearest s32 instead of truncating
dest[0] = a[0] + ((a[0] > 0) ? 0.5f : -0.5f);
dest[1] = a[1] + ((a[1] > 0) ? 0.5f : -0.5f);
dest[2] = a[2] + ((a[2] > 0) ? 0.5f : -0.5f);
return dest;
}
/*
Vec3s Functions
*/
/**
* Copy vector src to dest.
*/
INLINE OPTIMIZE_O3 s16 *vec3s_copy(Vec3s dest, Vec3s src) {
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
return dest;
}
/**
* Set vector 'dest' to (x, y, z).
*/
INLINE OPTIMIZE_O3 s16 *vec3s_set(Vec3s dest, s16 x, s16 y, s16 z) {
dest[0] = x;
dest[1] = y;
dest[2] = z;
return dest;
}
/**
* Add vector a to 'dest'.
*/
INLINE OPTIMIZE_O3 s16 *vec3s_add(Vec3s dest, Vec3s a) {
dest[0] += a[0];
dest[1] += a[1];
dest[2] += a[2];
return dest;
}
/**
* Make 'dest' the sum of vectors a and b.
*/
INLINE OPTIMIZE_O3 s16 *vec3s_sum(Vec3s dest, Vec3s a, Vec3s b) {
dest[0] = a[0] + b[0];
dest[1] = a[1] + b[1];
dest[2] = a[2] + b[2];
return dest;
}
/**
* Subtracts vector a from 'dest'.
*/
INLINE OPTIMIZE_O3 s16 *vec3s_sub(Vec3s dest, Vec3s a) {
dest[0] -= a[0];
dest[1] -= a[1];
dest[2] -= a[2];
return dest;
}
/**
* Make 'dest' the difference of vectors a and b.
*/
INLINE OPTIMIZE_O3 s16 *vec3s_dif(Vec3s dest, Vec3s a, Vec3s b) {
dest[0] = a[0] - b[0];
dest[1] = a[1] - b[1];
dest[2] = a[2] - b[2];
return dest;
}
/**
* Multiply vector 'dest' by a.
*/
INLINE OPTIMIZE_O3 s16 *vec3s_mul(Vec3s dest, s16 a) {
dest[0] *= a;
dest[1] *= a;
dest[2] *= a;
return dest;
}
/**
* Divides vector 'dest' by a.
*/
INLINE OPTIMIZE_O3 s16 *vec3s_div(Vec3s dest, s16 a) {
dest[0] /= a;
dest[1] /= a;
dest[2] /= a;
return dest;
}
/**
* Get length of vector 'a'.
*/
INLINE OPTIMIZE_O3 f32 vec3s_length(Vec3s a) {
return sqrtf(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
}
/**
* Calculates the distance between point 'v1' and 'v2'.
*/
INLINE OPTIMIZE_O3 f32 vec3s_dist(Vec3s v1, Vec3s v2) {
Vec3s diff;
vec3s_dif(diff, v1, v2);
return vec3s_length(diff);
}
INLINE OPTIMIZE_O3 s16 *vec3s_zero(Vec3s v) {
return vec3s_set(v, 0, 0, 0);
}
/**
* Convert short vector a to float vector 'dest'.
*/
INLINE OPTIMIZE_O3 f32 *vec3s_to_vec3f(Vec3f dest, Vec3s a) {
dest[0] = a[0];
dest[1] = a[1];
dest[2] = a[2];
return dest;
}
/*
Mat4 Functions
*/
/**
* Copy matrix 'src' to 'dest'.
*/
INLINE OPTIMIZE_O3 void mtxf_copy(Mat4 dest, Mat4 src) {
memcpy(dest, src, sizeof(Mat4));
}
/**
* Set mtx to the identity matrix
*/
INLINE OPTIMIZE_O3 void mtxf_identity(Mat4 mtx) {
mtxf_copy(mtx, gMat4Identity);
}
/**
* Set dest to a translation matrix of vector b
*/
INLINE OPTIMIZE_O3 void mtxf_translate(Mat4 dest, Vec3f b) {
mtxf_identity(dest);
vec3f_copy(dest[3], b);
}
/**
* Set matrix 'dest' to 'mtx' scaled by vector s
*/
INLINE OPTIMIZE_O3 void mtxf_scale_vec3f(Mat4 dest, Mat4 mtx, Vec3f s) {
mtxf_copy(dest, mtx);
vec3f_mul(dest[0], s[0]);
vec3f_mul(dest[1], s[1]);
vec3f_mul(dest[2], s[2]);
}
/**
* Set mtx to all zeros.
*/
INLINE OPTIMIZE_O3 void mtxf_zero(Mat4 mtx) {
mtxf_copy(mtx, gMat4Zero);
}
#endif // MATH_UTIL_INL

View file

@ -6,15 +6,15 @@
*/
static struct ObjectHitbox sAmpHitbox = {
/* interactType: */ INTERACT_SHOCK,
/* downOffset: */ 40,
/* damageOrCoinValue: */ 1,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 40,
/* height: */ 50,
/* hurtboxRadius: */ 50,
/* hurtboxHeight: */ 60,
.interactType = INTERACT_SHOCK,
.downOffset = 40,
.damageOrCoinValue = 1,
.health = 0,
.numLootCoins = 0,
.radius = 40,
.height = 50,
.hurtboxRadius = 50,
.hurtboxHeight = 60,
};
/**

View file

@ -1,15 +1,15 @@
// bobomb.c.inc
static struct ObjectHitbox sBobombHitbox = {
/* interactType: */ INTERACT_GRABBABLE,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 65,
/* height: */ 113,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_GRABBABLE,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 0,
.numLootCoins = 0,
.radius = 65,
.height = 113,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
static u32 forceCannonOpen = FALSE;
@ -31,19 +31,19 @@ void bobomb_spawn_coin(void) {
}
void bobomb_act_explode(void) {
struct Object *explosion;
if (o->oTimer < 5)
if (o->oTimer < 5) {
cur_obj_scale(1.0 + (f32) o->oTimer / 5.0);
else {
explosion = spawn_object(o, MODEL_EXPLOSION, bhvExplosion);
if (explosion != NULL) {
explosion->oGraphYOffset += 100.0f;
}
bobomb_spawn_coin();
create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000);
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
return;
}
struct Object *explosion = spawn_object(o, MODEL_EXPLOSION, bhvExplosion);
if (explosion != NULL) {
explosion->oGraphYOffset += 100.0f;
}
bobomb_spawn_coin();
create_respawner(MODEL_BLACK_BOBOMB, bhvBobomb, 3000);
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
}

View file

@ -1,15 +1,15 @@
// boo.c.inc
static struct ObjectHitbox sBooGivingStarHitbox = {
/* interactType: */ 0,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 3,
/* health: */ 3,
/* numLootCoins: */ 0,
/* radius: */ 140,
/* height: */ 80,
/* hurtboxRadius: */ 40,
/* hurtboxHeight: */ 60,
.interactType = 0,
.downOffset = 0,
.damageOrCoinValue = 3,
.health = 3,
.numLootCoins = 0,
.radius = 140,
.height = 80,
.hurtboxRadius = 40,
.hurtboxHeight = 60,
};
// Relative positions
@ -119,31 +119,27 @@ static s32 boo_should_be_active(void) {
}
void bhv_courtyard_boo_triplet_init(void) {
s32 i;
struct Object *boo;
if (gHudDisplay.stars < gBehaviorValues.CourtyardBoosRequirement) {
obj_mark_for_deletion(o);
} else {
for (i = 0; i < 3; i++) {
boo = spawn_object_relative(
0x01,
sCourtyardBooTripletPositions[i][0],
sCourtyardBooTripletPositions[i][1],
sCourtyardBooTripletPositions[i][2],
o,
MODEL_BOO,
bhvGhostHuntBoo
);
if (boo == NULL) { continue; }
boo->oMoveAngleYaw = random_u16();
}
return;
}
for (s32 i = 0; i < 3; i++) {
struct Object *boo = spawn_object_relative(
0x01,
sCourtyardBooTripletPositions[i][0],
sCourtyardBooTripletPositions[i][1],
sCourtyardBooTripletPositions[i][2],
o,
MODEL_BOO,
bhvGhostHuntBoo
);
if (boo == NULL) { continue; }
boo->oMoveAngleYaw = random_u16();
}
}
static void boo_approach_target_opacity_and_update_scale(void) {
f32 scale;
if (o->oBooTargetOpacity != o->oOpacity) {
if (o->oBooTargetOpacity > o->oOpacity) {
o->oOpacity += 20;
@ -160,7 +156,7 @@ static void boo_approach_target_opacity_and_update_scale(void) {
}
}
scale = (o->oOpacity/255.0f * 0.4 + 0.6) * o->oBooBaseScale;
f32 scale = (o->oOpacity/255.0f * 0.4 + 0.6) * o->oBooBaseScale;
obj_scale(o, scale); // why no cur_obj_scale? was cur_obj_scale written later?
}
@ -346,9 +342,9 @@ static s32 boo_update_during_death(void) {
static s32 obj_has_attack_type(u32 attackType) {
if ((o->oInteractStatus & INT_STATUS_ATTACK_MASK) == attackType) {
return TRUE;
} else {
return FALSE;
}
return FALSE;
}
static s32 boo_get_attack_status(void) {
@ -663,10 +659,9 @@ static void big_boo_spawn_merry_go_round_star(void) {
spawn_default_star(starPos[0], starPos[1], starPos[2]);
merryGoRound = cur_obj_nearest_object_with_behavior(bhvMerryGoRound);
if (merryGoRound != NULL) {
merryGoRound->oMerryGoRoundStopped = TRUE;
}
if (merryGoRound == NULL) { return; }
merryGoRound->oMerryGoRoundStopped = TRUE;
}
static void big_boo_act_3(void) {
@ -834,16 +829,15 @@ static void boo_with_cage_act_3(void) {
}
void bhv_boo_with_cage_init(void) {
struct Object* cage;
if (gHudDisplay.stars < gBehaviorValues.CourtyardBoosRequirement) {
obj_mark_for_deletion(o);
} else {
cage = spawn_object(o, MODEL_HAUNTED_CAGE, bhvBooCage);
if (cage != NULL) {
cage->oBehParams = o->oBehParams;
}
return;
}
struct Object *cage = spawn_object(o, MODEL_HAUNTED_CAGE, bhvBooCage);
if (cage == NULL) { return; }
cage->oBehParams = o->oBehParams;
}
static void (*sBooWithCageActions[])(void) = {

View file

@ -10,15 +10,15 @@
* Mario has to enter to enter BBH.
*/
static struct ObjectHitbox sBooCageHitbox = {
/* interactType: */ INTERACT_BBH_ENTRANCE,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 120,
/* height: */ 300,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_BBH_ENTRANCE,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 0,
.numLootCoins = 0,
.radius = 120,
.height = 300,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
static void bhv_boo_cage_on_received_post(UNUSED u8 localIndex) {

View file

@ -1,15 +1,15 @@
// bowling_ball.c.inc
static struct ObjectHitbox sBowlingBallHitbox = {
/* interactType: */ INTERACT_DAMAGE,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 2,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 100,
/* height: */ 150,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_DAMAGE,
.downOffset = 0,
.damageOrCoinValue = 2,
.health = 0,
.numLootCoins = 0,
.radius = 100,
.height = 150,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
Trajectory sThiHugeMetalBallTraj[] = {

View file

@ -1632,27 +1632,27 @@ void (*sFallingBowserPlatformActions[])(void) = { falling_bowser_plat_act_0,
falling_bowser_plat_act_2 };
struct ObjectHitbox sGrowingBowserFlameHitbox = {
/* interactType: */ INTERACT_FLAME,
/* downOffset: */ 20,
/* damageOrCoinValue: */ 1,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 10,
/* height: */ 40,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_FLAME,
.downOffset = 20,
.damageOrCoinValue = 1,
.health = 0,
.numLootCoins = 0,
.radius = 10,
.height = 40,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
struct ObjectHitbox sBowserFlameHitbox = {
/* interactType: */ INTERACT_FLAME,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 1,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 10,
/* height: */ 40,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_FLAME,
.downOffset = 0,
.damageOrCoinValue = 1,
.health = 0,
.numLootCoins = 0,
.radius = 10,
.height = 40,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
f32 D_8032F748[] = { -8.0f, -6.0f, -3.0f };

View file

@ -1,15 +1,15 @@
// bowser_key.c.inc
struct ObjectHitbox sBowserKeyHitbox = {
/* interactType: */ INTERACT_STAR_OR_KEY,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 160,
/* height: */ 100,
/* hurtboxRadius: */ 160,
/* hurtboxHeight: */ 100,
.interactType = INTERACT_STAR_OR_KEY,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 0,
.numLootCoins = 0,
.radius = 160,
.height = 100,
.hurtboxRadius = 160,
.hurtboxHeight = 100,
};
void bhv_bowser_key_init(void) {

View file

@ -1,15 +1,15 @@
// breakable_box.c.inc
struct ObjectHitbox sBreakableBoxSmallHitbox = {
/* interactType: */ INTERACT_GRABBABLE,
/* downOffset: */ 20,
/* damageOrCoinValue: */ 0,
/* health: */ 1,
/* numLootCoins: */ 0,
/* radius: */ 150,
/* height: */ 250,
/* hurtboxRadius: */ 150,
/* hurtboxHeight: */ 250,
.interactType = INTERACT_GRABBABLE,
.downOffset = 20,
.damageOrCoinValue = 0,
.health = 1,
.numLootCoins = 0,
.radius = 150,
.height = 250,
.hurtboxRadius = 150,
.hurtboxHeight = 250,
};
void bhv_breakable_box_small_init(void) {

View file

@ -1,15 +1,15 @@
// bubba.inc.c
static struct ObjectHitbox sBubbaHitbox = {
/* interactType: */ INTERACT_CLAM_OR_BUBBA,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 1,
/* health: */ 99,
/* numLootCoins: */ 0,
/* radius: */ 300,
/* height: */ 200,
/* hurtboxRadius: */ 300,
/* hurtboxHeight: */ 200,
.interactType = INTERACT_CLAM_OR_BUBBA,
.downOffset = 0,
.damageOrCoinValue = 1,
.health = 99,
.numLootCoins = 0,
.radius = 300,
.height = 200,
.hurtboxRadius = 300,
.hurtboxHeight = 200,
};
void bubba_act_0(void) {

View file

@ -1,27 +1,27 @@
// bully.c.inc
static struct ObjectHitbox sSmallBullyHitbox = {
/* interactType: */ INTERACT_BULLY,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 1,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 73,
/* height: */ 123,
/* hurtboxRadius: */ 63,
/* hurtboxHeight: */ 113,
.interactType = INTERACT_BULLY,
.downOffset = 0,
.damageOrCoinValue = 1,
.health = 0,
.numLootCoins = 0,
.radius = 73,
.height = 123,
.hurtboxRadius = 63,
.hurtboxHeight = 113,
};
static struct ObjectHitbox sBigBullyHitbox = {
/* interactType: */ INTERACT_BULLY,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 1,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 115,
/* height: */ 235,
/* hurtboxRadius: */ 105,
/* hurtboxHeight: */ 225,
.interactType = INTERACT_BULLY,
.downOffset = 0,
.damageOrCoinValue = 1,
.health = 0,
.numLootCoins = 0,
.radius = 115,
.height = 235,
.hurtboxRadius = 105,
.hurtboxHeight = 225,
};
static u8 bhv_bully_ignore_if_true(void) {

View file

@ -1,15 +1,15 @@
// cap.c.inc
static struct ObjectHitbox sCapHitbox = {
/* interactType: */ INTERACT_CAP,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 80,
/* height: */ 80,
/* hurtboxRadius: */ 90,
/* hurtboxHeight: */ 90,
.interactType = INTERACT_CAP,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 0,
.numLootCoins = 0,
.radius = 80,
.height = 80,
.hurtboxRadius = 90,
.hurtboxHeight = 90,
};
s32 cap_set_hitbox(void) {

View file

@ -13,15 +13,15 @@
* Hitbox for chain chomp.
*/
static struct ObjectHitbox sChainChompHitbox = {
/* interactType: */ INTERACT_MR_BLIZZARD,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 3,
/* health: */ 1,
/* numLootCoins: */ 0,
/* radius: */ 80,
/* height: */ 160,
/* hurtboxRadius: */ 80,
/* hurtboxHeight: */ 160,
.interactType = INTERACT_MR_BLIZZARD,
.downOffset = 0,
.damageOrCoinValue = 3,
.health = 1,
.numLootCoins = 0,
.radius = 80,
.height = 160,
.hurtboxRadius = 80,
.hurtboxHeight = 160,
};
/**

View file

@ -1,15 +1,15 @@
// clam.inc.c
struct ObjectHitbox sClamShellHitbox = {
/* interactType: */ INTERACT_CLAM_OR_BUBBA,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 2,
/* health: */ 99,
/* numLootCoins: */ 0,
/* radius: */ 150,
/* height: */ 80,
/* hurtboxRadius: */ 150,
/* hurtboxHeight: */ 80,
.interactType = INTERACT_CLAM_OR_BUBBA,
.downOffset = 0,
.damageOrCoinValue = 2,
.health = 99,
.numLootCoins = 0,
.radius = 150,
.height = 80,
.hurtboxRadius = 150,
.hurtboxHeight = 80,
};
void clam_act_0(void) {

View file

@ -1,15 +1,15 @@
// coin.c.inc
struct ObjectHitbox sYellowCoinHitbox = {
/* interactType: */ INTERACT_COIN,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 1,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 100,
/* height: */ 64,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_COIN,
.downOffset = 0,
.damageOrCoinValue = 1,
.health = 0,
.numLootCoins = 0,
.radius = 100,
.height = 64,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
s16 D_8032F2A4[][2] = { { 0, -150 }, { 0, -50 }, { 0, 50 }, { 0, 150 },

View file

@ -9,15 +9,15 @@
* Hitbox for evil lakitu.
*/
static struct ObjectHitbox sEnemyLakituHitbox = {
/* interactType: */ INTERACT_HIT_FROM_BELOW,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 2,
/* health: */ 0,
/* numLootCoins: */ 5,
/* radius: */ 50,
/* height: */ 50,
/* hurtboxRadius: */ 40,
/* hurtboxHeight: */ 50,
.interactType = INTERACT_HIT_FROM_BELOW,
.downOffset = 0,
.damageOrCoinValue = 2,
.health = 0,
.numLootCoins = 5,
.radius = 50,
.height = 50,
.hurtboxRadius = 40,
.hurtboxHeight = 50,
};
/**

View file

@ -1,15 +1,15 @@
// exclamation_box.c.inc
struct ObjectHitbox sExclamationBoxHitbox = {
/* interactType: */ INTERACT_BREAKABLE,
/* downOffset: */ 5,
/* damageOrCoinValue: */ 0,
/* health: */ 1,
/* numLootCoins: */ 0,
/* radius: */ 40,
/* height: */ 30,
/* hurtboxRadius: */ 40,
/* hurtboxHeight: */ 30,
.interactType = INTERACT_BREAKABLE,
.downOffset = 5,
.damageOrCoinValue = 0,
.health = 1,
.numLootCoins = 0,
.radius = 40,
.height = 30,
.hurtboxRadius = 40,
.hurtboxHeight = 30,
};
void bhv_rotating_exclamation_box_loop(void) {

View file

@ -1,13 +1,13 @@
struct ObjectHitbox sEyerokHitbox = {
/* interactType: */ INTERACT_BOUNCE_TOP,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 4,
/* numLootCoins: */ 0,
/* radius: */ 150,
/* height: */ 100,
/* hurtboxRadius: */ 1,
/* hurtboxHeight: */ 1,
.interactType = INTERACT_BOUNCE_TOP,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 4,
.numLootCoins = 0,
.radius = 150,
.height = 100,
.hurtboxRadius = 1,
.hurtboxHeight = 1,
};
s8 D_80331BA4[] = { 0, 1, 3, 2, 1, 0 };

View file

@ -6,15 +6,15 @@
*/
static struct ObjectHitbox sFallingPillarHitbox = {
/* interactType: */ INTERACT_DAMAGE,
/* downOffset: */ 150,
/* damageOrCoinValue: */ 3,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 150,
/* height: */ 300,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_DAMAGE,
.downOffset = 150,
.damageOrCoinValue = 3,
.health = 0,
.numLootCoins = 0,
.radius = 150,
.height = 300,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
/**

View file

@ -1,25 +1,25 @@
struct ObjectHitbox sFirePiranhaPlantHitbox = {
/* interactType: */ INTERACT_BOUNCE_TOP,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 2,
/* health: */ 0,
/* numLootCoins: */ 1,
/* radius: */ 80,
/* height: */ 160,
/* hurtboxRadius: */ 50,
/* hurtboxHeight: */ 150,
.interactType = INTERACT_BOUNCE_TOP,
.downOffset = 0,
.damageOrCoinValue = 2,
.health = 0,
.numLootCoins = 1,
.radius = 80,
.height = 160,
.hurtboxRadius = 50,
.hurtboxHeight = 150,
};
struct ObjectHitbox sPiranhaPlantFireHitbox = {
/* interactType: */ INTERACT_FLAME,
/* downOffset: */ 10,
/* damageOrCoinValue: */ 0,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 10,
/* height: */ 20,
/* hurtboxRadius: */ 10,
/* hurtboxHeight: */ 20,
.interactType = INTERACT_FLAME,
.downOffset = 10,
.damageOrCoinValue = 0,
.health = 0,
.numLootCoins = 0,
.radius = 10,
.height = 20,
.hurtboxRadius = 10,
.hurtboxHeight = 20,
};
s32 sNumActiveFirePiranhaPlants;

View file

@ -7,15 +7,15 @@
* Hitbox for fly guy.
*/
static struct ObjectHitbox sFlyGuyHitbox = {
/* interactType: */ INTERACT_BOUNCE_TOP,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 2,
/* health: */ 0,
/* numLootCoins: */ 2,
/* radius: */ 70,
/* height: */ 60,
/* hurtboxRadius: */ 40,
/* hurtboxHeight: */ 50,
.interactType = INTERACT_BOUNCE_TOP,
.downOffset = 0,
.damageOrCoinValue = 2,
.health = 0,
.numLootCoins = 2,
.radius = 70,
.height = 60,
.hurtboxRadius = 40,
.hurtboxHeight = 50,
};
/**

View file

@ -6,15 +6,15 @@ struct Struct80331B30 {
};
struct ObjectHitbox sFlyingBookendHitbox = {
/* interactType: */ INTERACT_HIT_FROM_BELOW,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 2,
/* health: */ 0,
/* numLootCoins: */ -1,
/* radius: */ 60,
/* height: */ 30,
/* hurtboxRadius: */ 40,
/* hurtboxHeight: */ 30,
.interactType = INTERACT_HIT_FROM_BELOW,
.downOffset = 0,
.damageOrCoinValue = 2,
.health = 0,
.numLootCoins = -1,
.radius = 60,
.height = 30,
.hurtboxRadius = 40,
.hurtboxHeight = 30,
};
struct Struct80331B30 D_80331B30[] = {
@ -24,15 +24,15 @@ struct Struct80331B30 D_80331B30[] = {
};
struct ObjectHitbox sBookSwitchHitbox = {
/* interactType: */ INTERACT_BREAKABLE,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 99,
/* numLootCoins: */ 0,
/* radius: */ 20,
/* height: */ 30,
/* hurtboxRadius: */ 20,
/* hurtboxHeight: */ 30,
.interactType = INTERACT_BREAKABLE,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 99,
.numLootCoins = 0,
.radius = 20,
.height = 30,
.hurtboxRadius = 20,
.hurtboxHeight = 30,
};
void flying_bookend_act_0(void) {

View file

@ -9,15 +9,15 @@
* Hitbox for goomba.
*/
static struct ObjectHitbox sGoombaHitbox = {
/* interactType: */ INTERACT_BOUNCE_TOP,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 1,
/* health: */ 0,
/* numLootCoins: */ 1,
/* radius: */ 72,
/* height: */ 50,
/* hurtboxRadius: */ 42,
/* hurtboxHeight: */ 40,
.interactType = INTERACT_BOUNCE_TOP,
.downOffset = 0,
.damageOrCoinValue = 1,
.health = 0,
.numLootCoins = 1,
.radius = 72,
.height = 50,
.hurtboxRadius = 42,
.hurtboxHeight = 40,
};
/**

View file

@ -1,15 +1,15 @@
// haunted_chair.inc.c
struct ObjectHitbox sHauntedChairHitbox = {
/* interactType: */ INTERACT_MR_BLIZZARD,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 2,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 50,
/* height: */ 50,
/* hurtboxRadius: */ 50,
/* hurtboxHeight: */ 50,
.interactType = INTERACT_MR_BLIZZARD,
.downOffset = 0,
.damageOrCoinValue = 2,
.health = 0,
.numLootCoins = 0,
.radius = 50,
.height = 50,
.hurtboxRadius = 50,
.hurtboxHeight = 50,
};
void bhv_haunted_chair_init(void) {

View file

@ -1,15 +1,15 @@
// jrb_ship.c.inc
struct ObjectHitbox sSkullSlidingBoxHitbox = {
/* interactType: */ INTERACT_DAMAGE,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 1,
/* health: */ 1,
/* numLootCoins: */ 0,
/* radius: */ 130,
/* height: */ 100,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_DAMAGE,
.downOffset = 0,
.damageOrCoinValue = 1,
.health = 1,
.numLootCoins = 0,
.radius = 130,
.height = 100,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
void bhv_sunken_ship_part_loop(void) {

View file

@ -1,15 +1,15 @@
// jumping_box.c.inc
struct ObjectHitbox sJumpingBoxHitbox = {
/* interactType: */ INTERACT_GRABBABLE,
/* downOffset: */ 20,
/* damageOrCoinValue: */ 0,
/* health: */ 1,
/* numLootCoins: */ 5,
/* radius: */ 150,
/* height: */ 250,
/* hurtboxRadius: */ 150,
/* hurtboxHeight: */ 250,
.interactType = INTERACT_GRABBABLE,
.downOffset = 20,
.damageOrCoinValue = 0,
.health = 1,
.numLootCoins = 5,
.radius = 150,
.height = 250,
.hurtboxRadius = 150,
.hurtboxHeight = 250,
};
void jumping_box_act_0(void) {

View file

@ -1,13 +1,13 @@
static struct ObjectHitbox sKleptoHitbox = {
/* interactType: */ INTERACT_HIT_FROM_BELOW,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 1,
/* numLootCoins: */ 0,
/* radius: */ 160,
/* height: */ 250,
/* hurtboxRadius: */ 80,
/* hurtboxHeight: */ 200,
.interactType = INTERACT_HIT_FROM_BELOW,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 1,
.numLootCoins = 0,
.radius = 160,
.height = 250,
.hurtboxRadius = 80,
.hurtboxHeight = 200,
};
static Vec3f sKleptoTargetPositions[] = {

View file

@ -11,15 +11,15 @@
* uses a hardcoded soft hitbox.
*/
static struct ObjectHitbox sKoopaHitbox = {
/* interactType: */ INTERACT_KOOPA,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 0,
/* numLootCoins: */ -1,
/* radius: */ 60,
/* height: */ 40,
/* hurtboxRadius: */ 40,
/* hurtboxHeight: */ 30,
.interactType = INTERACT_KOOPA,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 0,
.numLootCoins = -1,
.radius = 60,
.height = 40,
.hurtboxRadius = 40,
.hurtboxHeight = 30,
};
/**

View file

@ -1,15 +1,15 @@
// koopa_shell.c.inc
struct ObjectHitbox sKoopaShellHitbox = {
/* interactType: */ INTERACT_KOOPA_SHELL,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 4,
/* health: */ 1,
/* numLootCoins: */ 1,
/* radius: */ 50,
/* height: */ 50,
/* hurtboxRadius: */ 50,
/* hurtboxHeight: */ 50,
.interactType = INTERACT_KOOPA_SHELL,
.downOffset = 0,
.damageOrCoinValue = 4,
.health = 1,
.numLootCoins = 1,
.radius = 50,
.height = 50,
.hurtboxRadius = 50,
.hurtboxHeight = 50,
};
void koopa_shell_spawn_water_drop(void) {

View file

@ -1,15 +1,15 @@
// koopa_shell_underwater.c.inc
struct ObjectHitbox sKoopaShellUnderwaterHitbox = {
/* interactType: */ INTERACT_GRABBABLE,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 1,
/* numLootCoins: */ 0,
/* radius: */ 80,
/* height: */ 50,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_GRABBABLE,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 1,
.numLootCoins = 0,
.radius = 80,
.height = 50,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
void set_koopa_shell_underwater_hitbox(void) {

View file

@ -1,14 +1,14 @@
static struct ObjectHitbox sMadPianoHitbox = {
/* interactType: */ INTERACT_MR_BLIZZARD,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 3,
/* health: */ 99,
/* numLootCoins: */ 0,
/* radius: */ 200,
/* height: */ 150,
/* hurtboxRadius: */ 200,
/* hurtboxHeight: */ 150,
.interactType = INTERACT_MR_BLIZZARD,
.downOffset = 0,
.damageOrCoinValue = 3,
.health = 99,
.numLootCoins = 0,
.radius = 200,
.height = 150,
.hurtboxRadius = 200,
.hurtboxHeight = 150,
};
static void mad_piano_act_wait(void) {

View file

@ -18,15 +18,15 @@ static Trajectory sMantaRayTraj[] = {
};
static struct ObjectHitbox sMantaRayHitbox = {
/* interactType: */ INTERACT_DAMAGE,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 3,
/* numLootCoins: */ 0,
/* radius: */ 210,
/* height: */ 60,
/* hurtboxRadius: */ 200,
/* hurtboxHeight: */ 50,
.interactType = INTERACT_DAMAGE,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 3,
.numLootCoins = 0,
.radius = 210,
.height = 60,
.hurtboxRadius = 200,
.hurtboxHeight = 50,
};
/**

View file

@ -1,15 +1,15 @@
// metal_box.c.inc
struct ObjectHitbox sMetalBoxHitbox = {
/* interactType: */ 0,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 1,
/* numLootCoins: */ 0,
/* radius: */ 220,
/* height: */ 300,
/* hurtboxRadius: */ 220,
/* hurtboxHeight: */ 300,
.interactType = 0,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 1,
.numLootCoins = 0,
.radius = 220,
.height = 300,
.hurtboxRadius = 220,
.hurtboxHeight = 300,
};
s32 check_if_moving_over_floor(f32 a0, f32 a1) {

View file

@ -1,27 +1,27 @@
// moneybag.c.inc
static struct ObjectHitbox sMoneybagHitbox = {
/* interactType: */ INTERACT_BOUNCE_TOP,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 2,
/* health: */ 1,
/* numLootCoins: */ 0,
/* radius: */ 120,
/* height: */ 60,
/* hurtboxRadius: */ 100,
/* hurtboxHeight: */ 50,
.interactType = INTERACT_BOUNCE_TOP,
.downOffset = 0,
.damageOrCoinValue = 2,
.health = 1,
.numLootCoins = 0,
.radius = 120,
.height = 60,
.hurtboxRadius = 100,
.hurtboxHeight = 50,
};
static struct ObjectHitbox sMoneybagHiddenHitbox = {
/* interactType: */ INTERACT_DAMAGE,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 2,
/* health: */ 1,
/* numLootCoins: */ 0,
/* radius: */ 120,
/* height: */ 60,
/* hurtboxRadius: */ 100,
/* hurtboxHeight: */ 50,
.interactType = INTERACT_DAMAGE,
.downOffset = 0,
.damageOrCoinValue = 2,
.health = 1,
.numLootCoins = 0,
.radius = 120,
.height = 60,
.hurtboxRadius = 100,
.hurtboxHeight = 50,
};
void bhv_moneybag_init(void) {

View file

@ -390,15 +390,15 @@ static void monty_mole_act_jump_out_of_hole(void) {
* Hitbox for monty mole.
*/
static struct ObjectHitbox sMontyMoleHitbox = {
/* interactType: */ INTERACT_BOUNCE_TOP,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 2,
/* health: */ -1,
/* numLootCoins: */ 0,
/* radius: */ 70,
/* height: */ 50,
/* hurtboxRadius: */ 30,
/* hurtboxHeight: */ 40,
.interactType = INTERACT_BOUNCE_TOP,
.downOffset = 0,
.damageOrCoinValue = 2,
.health = -1,
.numLootCoins = 0,
.radius = 70,
.height = 50,
.hurtboxRadius = 30,
.hurtboxHeight = 40,
};
/**
@ -524,15 +524,15 @@ static void monty_mole_rock_act_held(void) {
* Hitbox for monty mole rock.
*/
static struct ObjectHitbox sMontyMoleRockHitbox = {
/* interactType: */ INTERACT_MR_BLIZZARD,
/* downOffset: */ 15,
/* damageOrCoinValue: */ 1,
/* health: */ 99,
/* numLootCoins: */ 0,
/* radius: */ 30,
/* height: */ 15,
/* hurtboxRadius: */ 30,
/* hurtboxHeight: */ 15,
.interactType = INTERACT_MR_BLIZZARD,
.downOffset = 15,
.damageOrCoinValue = 1,
.health = 99,
.numLootCoins = 0,
.radius = 30,
.height = 15,
.hurtboxRadius = 30,
.hurtboxHeight = 15,
};
/**

View file

@ -3,27 +3,27 @@
// sp18 = collisionFlagsPtr
static struct ObjectHitbox sMovingYellowCoinHitbox = {
/* interactType: */ INTERACT_COIN,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 1,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 100,
/* height: */ 64,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_COIN,
.downOffset = 0,
.damageOrCoinValue = 1,
.health = 0,
.numLootCoins = 0,
.radius = 100,
.height = 64,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
static struct ObjectHitbox sMovingBlueCoinHitbox = {
/* interactType: */ INTERACT_COIN,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 5,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 100,
/* height: */ 64,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_COIN,
.downOffset = 0,
.damageOrCoinValue = 5,
.health = 0,
.numLootCoins = 0,
.radius = 100,
.height = 64,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
s32 coin_step(s16 *collisionFlagsPtr) {

View file

@ -1,14 +1,14 @@
// Mr. Blizzard hitbox
struct ObjectHitbox sMrBlizzardHitbox = {
/* interactType: */ INTERACT_MR_BLIZZARD,
/* downOffset: */ 24,
/* damageOrCoinValue: */ 2,
/* health: */ 99,
/* numLootCoins: */ 3,
/* radius: */ 65,
/* height: */ 170,
/* hurtboxRadius: */ 65,
/* hurtboxHeight: */ 170,
.interactType = INTERACT_MR_BLIZZARD,
.downOffset = 24,
.damageOrCoinValue = 2,
.health = 99,
.numLootCoins = 3,
.radius = 65,
.height = 170,
.hurtboxRadius = 65,
.hurtboxHeight = 170,
};
// Mr. Blizzard particle spawner.
@ -472,15 +472,15 @@ static void mr_blizzard_snowball_act_1(void) {
}
// Snowball hitbox.
struct ObjectHitbox sMrBlizzardSnowballHitbox = {
/* interactType: */ INTERACT_MR_BLIZZARD,
/* downOffset: */ 12,
/* damageOrCoinValue: */ 1,
/* health: */ 99,
/* numLootCoins: */ 0,
/* radius: */ 30,
/* height: */ 30,
/* hurtboxRadius: */ 25,
/* hurtboxHeight: */ 25,
.interactType = INTERACT_MR_BLIZZARD,
.downOffset = 12,
.damageOrCoinValue = 1,
.health = 99,
.numLootCoins = 0,
.radius = 30,
.height = 30,
.hurtboxRadius = 25,
.hurtboxHeight = 25,
};
/**

View file

@ -264,15 +264,15 @@ void mr_i_act_0(void) {
void (*sMrIActions[])(void) = { mr_i_act_0, mr_i_act_1, mr_i_act_2, mr_i_act_3 };
struct ObjectHitbox sMrIHitbox = {
/* interactType: */ INTERACT_DAMAGE,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 2,
/* health: */ 2,
/* numLootCoins: */ 5,
/* radius: */ 80,
/* height: */ 150,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_DAMAGE,
.downOffset = 0,
.damageOrCoinValue = 2,
.health = 2,
.numLootCoins = 5,
.radius = 80,
.height = 150,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
void bhv_mr_i_loop(void) {

View file

@ -11,15 +11,15 @@
* Hitbox for a single pokey body part.
*/
static struct ObjectHitbox sPokeyBodyPartHitbox = {
/* interactType: */ INTERACT_BOUNCE_TOP,
/* downOffset: */ 10,
/* damageOrCoinValue: */ 2,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 40,
/* height: */ 20,
/* hurtboxRadius: */ 20,
/* hurtboxHeight: */ 20,
.interactType = INTERACT_BOUNCE_TOP,
.downOffset = 10,
.damageOrCoinValue = 2,
.health = 0,
.numLootCoins = 0,
.radius = 40,
.height = 20,
.hurtboxRadius = 20,
.hurtboxHeight = 20,
};
/**

View file

@ -1,14 +1,14 @@
struct ObjectHitbox sRecoveryHeartHitbox = {
/* interactType: */ 0,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 50,
/* height: */ 50,
/* hurtboxRadius: */ 50,
/* hurtboxHeight: */ 50,
.interactType = 0,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 0,
.numLootCoins = 0,
.radius = 50,
.height = 50,
.hurtboxRadius = 50,
.hurtboxHeight = 50,
};
void bhv_recovery_heart_loop(void) {

View file

@ -8,15 +8,15 @@
* Red coin's hitbox details.
*/
static struct ObjectHitbox sRedCoinHitbox = {
/* interactType: */ INTERACT_COIN,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 2,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 100,
/* height: */ 64,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_COIN,
.downOffset = 0,
.damageOrCoinValue = 2,
.health = 0,
.numLootCoins = 0,
.radius = 100,
.height = 64,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
/**

View file

@ -1,15 +1,15 @@
// scuttlebug.c.inc
struct ObjectHitbox sScuttlebugHitbox = {
/* interactType: */ INTERACT_BOUNCE_TOP,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 1,
/* health: */ 1,
/* numLootCoins: */ 3,
/* radius: */ 130,
/* height: */ 70,
/* hurtboxRadius: */ 90,
/* hurtboxHeight: */ 60,
.interactType = INTERACT_BOUNCE_TOP,
.downOffset = 0,
.damageOrCoinValue = 1,
.health = 1,
.numLootCoins = 3,
.radius = 130,
.height = 70,
.hurtboxRadius = 90,
.hurtboxHeight = 60,
};
s32 update_angle_from_move_flags(s32 *angle) {

View file

@ -4,15 +4,15 @@ struct Struct80331C38 {
};
struct ObjectHitbox sSkeeterHitbox = {
/* interactType: */ INTERACT_BOUNCE_TOP,
/* downOffset: */ 20,
/* damageOrCoinValue: */ 2,
/* health: */ 0,
/* numLootCoins: */ 3,
/* radius: */ 180,
/* height: */ 100,
/* hurtboxRadius: */ 150,
/* hurtboxHeight: */ 90,
.interactType = INTERACT_BOUNCE_TOP,
.downOffset = 20,
.damageOrCoinValue = 2,
.health = 0,
.numLootCoins = 3,
.radius = 180,
.height = 100,
.hurtboxRadius = 150,
.hurtboxHeight = 90,
};
struct Struct80331C38 D_80331C38[] = {

View file

@ -1,15 +1,15 @@
// snowman.c.inc
static struct ObjectHitbox sRollingSphereHitbox = {
/* interactType: */ INTERACT_DAMAGE,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 3,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 210,
/* height: */ 350,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_DAMAGE,
.downOffset = 0,
.damageOrCoinValue = 3,
.health = 0,
.numLootCoins = 0,
.radius = 210,
.height = 350,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
void bhv_snowmans_bottom_init(void) {

View file

@ -6,27 +6,27 @@
*/
struct ObjectHitbox sSnufitHitbox = {
/* interactType: */ INTERACT_HIT_FROM_BELOW,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 2,
/* health: */ 0,
/* numLootCoins: */ 2,
/* radius: */ 100,
/* height: */ 60,
/* hurtboxRadius: */ 70,
/* hurtboxHeight: */ 50,
.interactType = INTERACT_HIT_FROM_BELOW,
.downOffset = 0,
.damageOrCoinValue = 2,
.health = 0,
.numLootCoins = 2,
.radius = 100,
.height = 60,
.hurtboxRadius = 70,
.hurtboxHeight = 50,
};
struct ObjectHitbox sSnufitBulletHitbox = {
/* interactType: */ INTERACT_SNUFIT_BULLET,
/* downOffset: */ 50,
/* damageOrCoinValue: */ 1,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 100,
/* height: */ 50,
/* hurtboxRadius: */ 100,
/* hurtboxHeight: */ 50,
.interactType = INTERACT_SNUFIT_BULLET,
.downOffset = 50,
.damageOrCoinValue = 1,
.health = 0,
.numLootCoins = 0,
.radius = 100,
.height = 50,
.hurtboxRadius = 100,
.hurtboxHeight = 50,
};
/**

View file

@ -1,15 +1,15 @@
// sparkle_spawn_star.c.inc
struct ObjectHitbox sSparkleSpawnStarHitbox = {
/* interactType: */ INTERACT_STAR_OR_KEY,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 80,
/* height: */ 50,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_STAR_OR_KEY,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 0,
.numLootCoins = 0,
.radius = 80,
.height = 50,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
void bhv_spawned_star_init(void) {

View file

@ -47,15 +47,15 @@ void spawn_star_number(void) {
}
static struct ObjectHitbox sCollectStarHitbox = {
/* interactType: */ INTERACT_STAR_OR_KEY,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 80,
/* height: */ 50,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_STAR_OR_KEY,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 0,
.numLootCoins = 0,
.radius = 80,
.height = 50,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
void bhv_collect_star_init(void) {

View file

@ -1,15 +1,15 @@
// spindrift.c.inc
struct ObjectHitbox sSpindriftHitbox = {
/* interactType: */ INTERACT_BOUNCE_TOP,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 2,
/* health: */ 1,
/* numLootCoins: */ 3,
/* radius: */ 90,
/* height: */ 80,
/* hurtboxRadius: */ 80,
/* hurtboxHeight: */ 70,
.interactType = INTERACT_BOUNCE_TOP,
.downOffset = 0,
.damageOrCoinValue = 2,
.health = 1,
.numLootCoins = 3,
.radius = 90,
.height = 80,
.hurtboxRadius = 80,
.hurtboxHeight = 70,
};
void bhv_spindrift_loop(void) {

View file

@ -10,15 +10,15 @@
* changed to INTERACT_SPINY_WALKING while walking.
*/
static struct ObjectHitbox sSpinyHitbox = {
/* interactType: */ INTERACT_MR_BLIZZARD,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 2,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 80,
/* height: */ 50,
/* hurtboxRadius: */ 40,
/* hurtboxHeight: */ 40,
.interactType = INTERACT_MR_BLIZZARD,
.downOffset = 0,
.damageOrCoinValue = 2,
.health = 0,
.numLootCoins = 0,
.radius = 80,
.height = 50,
.hurtboxRadius = 40,
.hurtboxHeight = 40,
};
/**

View file

@ -1,15 +1,15 @@
// strong_wind_particle.c.inc
struct ObjectHitbox sStrongWindParticleHitbox = {
/* interactType: */ INTERACT_STRONG_WIND,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 20,
/* height: */ 70,
/* hurtboxRadius: */ 20,
/* hurtboxHeight: */ 70,
.interactType = INTERACT_STRONG_WIND,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 0,
.numLootCoins = 0,
.radius = 20,
.height = 70,
.hurtboxRadius = 20,
.hurtboxHeight = 70,
};
void bhv_strong_wind_particle_loop(void) {

View file

@ -1,15 +1,15 @@
// switch_hidden_objects.c.inc
struct ObjectHitbox sBreakableBoxHitbox = {
/* interactType: */ INTERACT_BREAKABLE,
/* downOffset: */ 20,
/* damageOrCoinValue: */ 0,
/* health: */ 1,
/* numLootCoins: */ 0,
/* radius: */ 150,
/* height: */ 200,
/* hurtboxRadius: */ 150,
/* hurtboxHeight: */ 200,
.interactType = INTERACT_BREAKABLE,
.downOffset = 20,
.damageOrCoinValue = 0,
.health = 1,
.numLootCoins = 0,
.radius = 150,
.height = 200,
.hurtboxRadius = 150,
.hurtboxHeight = 200,
};
void breakable_box_init(void) {

View file

@ -8,15 +8,15 @@
* Hitbox for swoop.
*/
static struct ObjectHitbox sSwoopHitbox = {
/* interactType: */ INTERACT_HIT_FROM_BELOW,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 1,
/* health: */ 0,
/* numLootCoins: */ 1,
/* radius: */ 100,
/* height: */ 80,
/* hurtboxRadius: */ 70,
/* hurtboxHeight: */ 70,
.interactType = INTERACT_HIT_FROM_BELOW,
.downOffset = 0,
.damageOrCoinValue = 1,
.health = 0,
.numLootCoins = 1,
.radius = 100,
.height = 80,
.hurtboxRadius = 70,
.hurtboxHeight = 70,
};
/**

View file

@ -4,15 +4,15 @@
* Hitbox for treasure chest bottom.
*/
static struct ObjectHitbox sTreasureChestBottomHitbox = {
/* interactType: */ INTERACT_SHOCK,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 1,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 300,
/* height: */ 300,
/* hurtboxRadius: */ 310,
/* hurtboxHeight: */ 310,
.interactType = INTERACT_SHOCK,
.downOffset = 0,
.damageOrCoinValue = 1,
.health = 0,
.numLootCoins = 0,
.radius = 300,
.height = 300,
.hurtboxRadius = 310,
.hurtboxHeight = 310,
};

View file

@ -5,15 +5,15 @@ struct TripletButterflyActivationData {
};
static struct ObjectHitbox sTripletButterflyExplodeHitbox = {
/* interactType: */ INTERACT_MR_BLIZZARD,
/* downOffset: */ 50,
/* damageOrCoinValue: */ 2,
/* health: */ 1,
/* numLootCoins: */ 0,
/* radius: */ 100,
/* height: */ 50,
/* hurtboxRadius: */ 100,
/* hurtboxHeight: */ 50,
.interactType = INTERACT_MR_BLIZZARD,
.downOffset = 50,
.damageOrCoinValue = 2,
.health = 1,
.numLootCoins = 0,
.radius = 100,
.height = 50,
.hurtboxRadius = 100,
.hurtboxHeight = 50,
};
static struct TripletButterflyActivationData sTripletButterflyActivationData[] = {

View file

@ -6,15 +6,15 @@
*/
struct ObjectHitbox sTweesterHitbox = {
/* interactType: */ INTERACT_TORNADO,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 1500,
/* height: */ 4000,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_TORNADO,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 0,
.numLootCoins = 0,
.radius = 1500,
.height = 4000,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
/**

View file

@ -1,15 +1,15 @@
// unagi.inc.c
struct ObjectHitbox sUnagiHitbox = {
/* interactType: */ INTERACT_CLAM_OR_BUBBA,
/* downOffset: */ 50,
/* damageOrCoinValue: */ 3,
/* health: */ 99,
/* numLootCoins: */ 0,
/* radius: */ 150,
/* height: */ 150,
/* hurtboxRadius: */ 150,
/* hurtboxHeight: */ 150,
.interactType = INTERACT_CLAM_OR_BUBBA,
.downOffset = 50,
.damageOrCoinValue = 3,
.health = 99,
.numLootCoins = 0,
.radius = 150,
.height = 150,
.hurtboxRadius = 150,
.hurtboxHeight = 150,
};
void bhv_unagi_init(void) {

View file

@ -13,15 +13,15 @@
* bombs that are shot from cannons are intangible.
*/
static struct ObjectHitbox sWaterBombHitbox = {
/* interactType: */ INTERACT_MR_BLIZZARD,
/* downOffset: */ 25,
/* damageOrCoinValue: */ 1,
/* health: */ 99,
/* numLootCoins: */ 0,
/* radius: */ 80,
/* height: */ 50,
/* hurtboxRadius: */ 60,
/* hurtboxHeight: */ 50,
.interactType = INTERACT_MR_BLIZZARD,
.downOffset = 25,
.damageOrCoinValue = 1,
.health = 99,
.numLootCoins = 0,
.radius = 80,
.height = 50,
.hurtboxRadius = 60,
.hurtboxHeight = 50,
};
/**

View file

@ -1,15 +1,15 @@
// whirlpool.c.inc
static struct ObjectHitbox sWhirlpoolHitbox = {
/* interactType: */ INTERACT_WHIRLPOOL,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 0,
/* health: */ 0,
/* numLootCoins: */ 0,
/* radius: */ 200,
/* height: */ 500,
/* hurtboxRadius: */ 0,
/* hurtboxHeight: */ 0,
.interactType = INTERACT_WHIRLPOOL,
.downOffset = 0,
.damageOrCoinValue = 0,
.health = 0,
.numLootCoins = 0,
.radius = 200,
.height = 500,
.hurtboxRadius = 0,
.hurtboxHeight = 0,
};
void bhv_whirlpool_init(void) {

View file

@ -11,30 +11,30 @@
* Hitbox for wiggler's non-head body parts.
*/
static struct ObjectHitbox sWigglerBodyPartHitbox = {
/* interactType: */ INTERACT_BOUNCE_TOP,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 3,
/* health: */ 99, // never decreases
/* numLootCoins: */ 0,
/* radius: */ 20,
/* height: */ 20,
/* hurtboxRadius: */ 20,
/* hurtboxHeight: */ 10,
.interactType = INTERACT_BOUNCE_TOP,
.downOffset = 0,
.damageOrCoinValue = 3,
.health = 99, // never decreases
.numLootCoins = 0,
.radius = 20,
.height = 20,
.hurtboxRadius = 20,
.hurtboxHeight = 10,
};
/**
* Hitbox for wiggler's head.
*/
static struct ObjectHitbox sWigglerHitbox = {
/* interactType: */ INTERACT_BOUNCE_TOP,
/* downOffset: */ 0,
/* damageOrCoinValue: */ 3,
/* health: */ 4,
/* numLootCoins: */ 0,
/* radius: */ 60,
/* height: */ 50,
/* hurtboxRadius: */ 30,
/* hurtboxHeight: */ 40,
.interactType = INTERACT_BOUNCE_TOP,
.downOffset = 0,
.damageOrCoinValue = 3,
.health = 4,
.numLootCoins = 0,
.radius = 60,
.height = 50,
.hurtboxRadius = 30,
.hurtboxHeight = 40,
};
/**

View file

@ -3788,13 +3788,6 @@ void stub_camera_2(UNUSED struct Camera *c) {
void stub_camera_3(UNUSED struct Camera *c) {
}
void vec3f_sub(Vec3f dst, Vec3f src) {
if (!dst || !src) { return; }
dst[0] -= src[0];
dst[1] -= src[1];
dst[2] -= src[2];
}
void object_pos_to_vec3f(Vec3f dst, struct Object *o) {
if (!dst || !o) { return; }
dst[0] = o->oPosX;

View file

@ -784,12 +784,6 @@ void stub_camera_2(UNUSED struct Camera *c);
void stub_camera_3(UNUSED struct Camera *c);
/* |description|
Subtracts one 3D vector (`src`) from another (`dst`).
Stores the result in the destination vector
|descriptionEnd| */
void vec3f_sub(Vec3f dst, Vec3f src);
/* |description|
Converts an object's position to a `Vec3f` format.
Useful for aligning object behaviors or interactions with the camera system

View file

@ -2247,7 +2247,7 @@ static s32 jumbo_star_cutscene_taking_off(struct MarioState *m) {
if (m->actionState == 0) {
set_character_animation(m, CHAR_ANIM_FINAL_BOWSER_RAISE_HAND_SPIN);
marioObj->rawData.asF32[0x22] = 0.0f;
marioObj->oMarioJumboStarCutscenePosZ = 0.0f;
if (is_anim_past_end(m)) {
play_mario_landing_sound(m, SOUND_ACTION_TERRAIN_LANDING);
@ -2259,7 +2259,7 @@ static s32 jumbo_star_cutscene_taking_off(struct MarioState *m) {
play_sound_and_spawn_particles(m, SOUND_ACTION_TERRAIN_JUMP, 1);
}
if (animFrame >= 3) {
marioObj->rawData.asF32[0x22] -= 32.0f;
marioObj->oMarioJumboStarCutscenePosZ -= 32.0f;
}
switch (animFrame) {
@ -2282,7 +2282,7 @@ static s32 jumbo_star_cutscene_taking_off(struct MarioState *m) {
}
}
vec3f_set(m->pos, 0.0f, 307.0, marioObj->rawData.asF32[0x22]);
vec3f_set(m->pos, 0.0f, 307.0, marioObj->oMarioJumboStarCutscenePosZ);
m->pos[0] += 100.0f * m->playerIndex;
update_mario_pos_for_anim(m);

View file

@ -16,9 +16,22 @@
static s16 sMovingSandSpeeds[] = { 12, 8, 4, 0 };
struct Surface gWaterSurfacePseudoFloor = {
SURFACE_VERY_SLIPPERY, 0, 0, 0, 0, 0, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
{ 0.0f, 1.0f, 0.0f }, 0.0f, NULL,
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, 0
.type = SURFACE_VERY_SLIPPERY,
.flags = 0,
.room = 0,
.force = 0,
.lowerY = 0,
.upperY = 0,
.vertex1 = { 0, 0, 0 },
.vertex2 = { 0, 0, 0 },
.vertex3 = { 0, 0, 0 },
.prevVertex1 = { 0, 0, 0 },
.prevVertex2 = { 0, 0, 0 },
.prevVertex3 = { 0, 0, 0 },
.normal = { 0.0f, 1.0f, 0.0f },
.originOffset = 0.0f,
.modifiedTimestamp = 0,
.object = NULL
};
/**

View file

@ -528,8 +528,8 @@ s16 obj_turn_toward_object(struct Object *obj, struct Object *target, s16 angleI
break;
}
startAngle = o->rawData.asU32[angleIndex];
o->rawData.asU32[angleIndex] = approach_s16_symmetric(startAngle, targetAngle, turnAmount);
startAngle = o->OBJECT_FIELD_U32(angleIndex);
o->OBJECT_FIELD_U32(angleIndex) = approach_s16_symmetric(startAngle, targetAngle, turnAmount);
return targetAngle;
}
@ -2319,15 +2319,15 @@ Transforms the vector at `localTranslateIndex` into the object's local coordinat
|descriptionEnd| */
void obj_translate_local(struct Object *obj, s16 posIndex, s16 localTranslateIndex) {
if (obj == NULL) { return; }
f32 dx = obj->rawData.asF32[localTranslateIndex + 0];
f32 dy = obj->rawData.asF32[localTranslateIndex + 1];
f32 dz = obj->rawData.asF32[localTranslateIndex + 2];
f32 dx = obj->OBJECT_FIELD_F32(localTranslateIndex + 0);
f32 dy = obj->OBJECT_FIELD_F32(localTranslateIndex + 1);
f32 dz = obj->OBJECT_FIELD_F32(localTranslateIndex + 2);
obj->rawData.asF32[posIndex + 0] +=
obj->OBJECT_FIELD_F32(posIndex + 0) +=
obj->transform[0][0] * dx + obj->transform[1][0] * dy + obj->transform[2][0] * dz;
obj->rawData.asF32[posIndex + 1] +=
obj->OBJECT_FIELD_F32(posIndex + 1) +=
obj->transform[0][1] * dx + obj->transform[1][1] * dy + obj->transform[2][1] * dz;
obj->rawData.asF32[posIndex + 2] +=
obj->OBJECT_FIELD_F32(posIndex + 2) +=
obj->transform[0][2] * dx + obj->transform[1][2] * dy + obj->transform[2][2] * dz;
}
@ -2336,13 +2336,13 @@ void obj_build_transform_from_pos_and_angle(struct Object *obj, s16 posIndex, s1
f32 translate[3];
s16 rotation[3];
translate[0] = obj->rawData.asF32[posIndex + 0];
translate[1] = obj->rawData.asF32[posIndex + 1];
translate[2] = obj->rawData.asF32[posIndex + 2];
translate[0] = obj->OBJECT_FIELD_F32(posIndex + 0);
translate[1] = obj->OBJECT_FIELD_F32(posIndex + 1);
translate[2] = obj->OBJECT_FIELD_F32(posIndex + 2);
rotation[0] = obj->rawData.asS32[angleIndex + 0];
rotation[1] = obj->rawData.asS32[angleIndex + 1];
rotation[2] = obj->rawData.asS32[angleIndex + 2];
rotation[0] = obj->OBJECT_FIELD_S32(angleIndex + 0);
rotation[1] = obj->OBJECT_FIELD_S32(angleIndex + 1);
rotation[2] = obj->OBJECT_FIELD_S32(angleIndex + 2);
mtxf_rotate_zxy_and_translate(obj->transform, translate, rotation);
}

View file

@ -1535,10 +1535,12 @@ void geo_process_node_and_siblings(struct GraphNode *firstNode) {
break;
}
#ifdef DEBUG
if (curGraphNode->_guard1 != GRAPH_NODE_GUARD || curGraphNode->_guard2 != GRAPH_NODE_GUARD) {
LOG_ERROR("Graph Node corrupted!");
break;
}
#endif
// Sanity check our stack index, If we above or equal to our stack size. Return to prevent OOB\.
if ((gMatStackIndex + 1) >= MATRIX_STACK_SIZE) {

View file

@ -291,10 +291,8 @@ struct Object *allocate_object(struct ObjectNode *objList) {
obj->collidedObjInteractTypes = 0;
obj->numCollidedObjs = 0;
for (s32 i = 0; i < OBJECT_NUM_FIELDS; i++) {
obj->rawData.asS32[i] = 0;
obj->ptrData.asVoidPtr[i] = NULL;
}
memset(&obj->rawData, 0, sizeof(obj->rawData));
memset(&obj->ptrData, 0, sizeof(obj->ptrData));
obj->unused1 = 0;
obj->bhvStackIndex = 0;
@ -329,13 +327,9 @@ struct Object *allocate_object(struct ObjectNode *objList) {
obj->oRoom = -1;
obj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
obj->header.gfx.pos[0] = -10000.0f;
obj->header.gfx.pos[1] = -10000.0f;
obj->header.gfx.pos[2] = -10000.0f;
vec3f_set(obj->header.gfx.pos, -10000.0f, -10000.0f, -10000.0f);
vec3s_zero(obj->header.gfx.angle);
obj->header.gfx.throwMatrix = NULL;
obj->header.gfx.angle[0] = 0;
obj->header.gfx.angle[1] = 0;
obj->header.gfx.angle[2] = 0;
obj->header.gfx.inited = false;
obj->coopFlags = 0;

View file

@ -51,20 +51,20 @@ extern ALIGNED8 const u8 texture_hud_char_apostrophe[];
extern ALIGNED8 const u8 texture_hud_char_double_quote[];
struct GlobalTextures gGlobalTextures = {
.camera = { .texture = (u8*)texture_hud_char_camera, .bitSize = 8, .width = 16, .height = 16, "texture_hud_char_camera" },
.lakitu = { .texture = (u8*)texture_hud_char_lakitu, .bitSize = 8, .width = 16, .height = 16, "texture_hud_char_lakitu" },
.no_camera = { .texture = (u8*)texture_hud_char_no_camera, .bitSize = 8, .width = 16, .height = 16, "texture_hud_char_no_camera" },
.arrow_up = { .texture = (u8*)texture_hud_char_arrow_up, .bitSize = 8, .width = 8, .height = 8, "texture_hud_char_arrow_up" },
.arrow_down = { .texture = (u8*)texture_hud_char_arrow_down, .bitSize = 8, .width = 8, .height = 8, "texture_hud_char_arrow_down" },
.coin = { .texture = (u8*)texture_hud_char_coin, .bitSize = 8, .width = 16, .height = 16, "texture_hud_char_coin" },
.star = { .texture = (u8*)texture_hud_char_star, .bitSize = 8, .width = 16, .height = 16, "texture_hud_char_star" },
.apostrophe = { .texture = (u8*)texture_hud_char_apostrophe, .bitSize = 8, .width = 16, .height = 16, "texture_hud_char_apostrophe" },
.double_quote = { .texture = (u8*)texture_hud_char_double_quote, .bitSize = 8, .width = 16, .height = 16, "texture_hud_char_double_quote" },
.mario_head = { .texture = (u8*)texture_hud_char_mario_head, .bitSize = 8, .width = 16, .height = 16, "texture_hud_char_mario_head" },
.luigi_head = { .texture = (u8*)texture_hud_char_luigi_head, .bitSize = 8, .width = 16, .height = 16, "texture_hud_char_luigi_head" },
.toad_head = { .texture = (u8*)texture_hud_char_toad_head, .bitSize = 8, .width = 16, .height = 16, "texture_hud_char_toad_head" },
.waluigi_head = { .texture = (u8*)texture_hud_char_waluigi_head, .bitSize = 8, .width = 16, .height = 16, "texture_hud_char_waluigi_head" },
.wario_head = { .texture = (u8*)texture_hud_char_wario_head, .bitSize = 8, .width = 16, .height = 16, "texture_hud_char_wario_head" }
.camera = { .texture = (u8*)texture_hud_char_camera, "texture_hud_char_camera", .width = 16, .height = 16, .bitSize = 8 },
.lakitu = { .texture = (u8*)texture_hud_char_lakitu, "texture_hud_char_lakitu", .width = 16, .height = 16, .bitSize = 8 },
.no_camera = { .texture = (u8*)texture_hud_char_no_camera, "texture_hud_char_no_camera", .width = 16, .height = 16, .bitSize = 8 },
.arrow_up = { .texture = (u8*)texture_hud_char_arrow_up, "texture_hud_char_arrow_up", .width = 8, .height = 8, .bitSize = 8 },
.arrow_down = { .texture = (u8*)texture_hud_char_arrow_down, "texture_hud_char_arrow_down", .width = 8, .height = 8, .bitSize = 8 },
.coin = { .texture = (u8*)texture_hud_char_coin, "texture_hud_char_coin", .width = 16, .height = 16, .bitSize = 8 },
.star = { .texture = (u8*)texture_hud_char_star, "texture_hud_char_star", .width = 16, .height = 16, .bitSize = 8 },
.apostrophe = { .texture = (u8*)texture_hud_char_apostrophe, "texture_hud_char_apostrophe", .width = 16, .height = 16, .bitSize = 8 },
.double_quote = { .texture = (u8*)texture_hud_char_double_quote, "texture_hud_char_double_quote", .width = 16, .height = 16, .bitSize = 8 },
.mario_head = { .texture = (u8*)texture_hud_char_mario_head, "texture_hud_char_mario_head", .width = 16, .height = 16, .bitSize = 8 },
.luigi_head = { .texture = (u8*)texture_hud_char_luigi_head, "texture_hud_char_luigi_head", .width = 16, .height = 16, .bitSize = 8 },
.toad_head = { .texture = (u8*)texture_hud_char_toad_head, "texture_hud_char_toad_head", .width = 16, .height = 16, .bitSize = 8 },
.waluigi_head = { .texture = (u8*)texture_hud_char_waluigi_head, "texture_hud_char_waluigi_head", .width = 16, .height = 16, .bitSize = 8 },
.wario_head = { .texture = (u8*)texture_hud_char_wario_head, "texture_hud_char_wario_head", .width = 16, .height = 16, .bitSize = 8 }
};
static void djui_hud_position_translate(f32* x, f32* y) {

93
src/pc/gfx/gfx.h Normal file
View file

@ -0,0 +1,93 @@
#ifndef GFX_H
#define GFX_H
#include <math.h>
#include <assert.h>
#define SUPPORT_CHECK(x) assert(x)
// SCALE_M_N: upscale/downscale M-bit integer to N-bit
#define SCALE_5_8(VAL_) (((VAL_) * 0xFF) / 0x1F)
#define SCALE_8_5(VAL_) ((((VAL_) + 4) * 0x1F) / 0xFF)
#define SCALE_4_8(VAL_) ((VAL_) * 0x11)
#define SCALE_8_4(VAL_) ((VAL_) / 0x11)
#define SCALE_3_8(VAL_) ((VAL_) * 0x24)
#define SCALE_8_3(VAL_) ((VAL_) / 0x24)
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
#define HALF_SCREEN_WIDTH (SCREEN_WIDTH / 2)
#define HALF_SCREEN_HEIGHT (SCREEN_HEIGHT / 2)
#define MAX_BUFFERED 256
#define MAX_MATRIX_STACK_SIZE 11
#define MAX_LIGHTS 18
#define MAX_VERTICES 64
#define MAX_CACHED_TEXTURES 4096 // for preloading purposes
#define HASH_SHIFT 0
#define HASHMAP_LEN (MAX_CACHED_TEXTURES * 2)
#define HASH_MASK (HASHMAP_LEN - 1)
struct RGBA {
uint8_t r, g, b, a;
};
struct Box {
uint16_t x, y, width, height;
};
struct GfxVertex {
float x, y, z, w;
float u, v;
struct RGBA color;
uint8_t fog_z;
uint8_t clip_rej;
};
struct GfxDimensions {
uint32_t width, height;
float aspect_ratio;
float x_adjust_ratio;
uint32_t x_adjust_4by3;
};
struct GfxTexture {
const uint8_t *addr;
uint32_t size_bytes;
};
struct UnloadedTex {
const uint8_t *addr;
uint8_t siz;
uint8_t tile_number;
};
struct TextureTile {
uint8_t fmt;
uint8_t siz;
uint8_t cms, cmt;
uint16_t uls, ult, lrs, lrt; // U10.2
uint32_t line_size_bytes;
};
struct TextureHashmapNode {
struct TextureHashmapNode *next;
const void *texture_addr;
uint32_t texture_id;
uint8_t fmt, siz;
uint8_t cms, cmt;
bool linear_filter;
};
struct TextureCache {
struct TextureHashmapNode *hashmap[HASHMAP_LEN];
struct TextureHashmapNode pool[MAX_CACHED_TEXTURES];
uint32_t pool_pos;
};
extern struct GfxDimensions gfx_current_dimensions;
#define RATIO_X (gfx_current_dimensions.width / (2.0f * HALF_SCREEN_WIDTH))
#define RATIO_Y (gfx_current_dimensions.height / (2.0f * HALF_SCREEN_HEIGHT))
#endif // GFX_H

View file

@ -4,7 +4,6 @@
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
#ifdef __SSE__
#include <xmmintrin.h>
@ -19,148 +18,76 @@
#include <PR/gbi.h>
#include "config.h"
#include "gfx_pc.h"
#include "gfx_cc.h"
#include "gfx_window_manager_api.h"
#include "gfx_rendering_api.h"
#include "gfx_screen_config.h"
#include "../platform.h"
#include "../configfile.h"
#include "../fs/fs.h"
#include "../pc_main.h"
#include "macros.h"
#include "game/rendering_graph_node.h"
#include "engine/lighting_engine.h"
#include "pc/debug_context.h"
#include "engine/math_util.h"
#include "game/object_helpers.h"
#include "game/rendering_graph_node.h"
#define SUPPORT_CHECK(x) assert(x)
#include "pc/configfile.h"
#include "pc/debug_context.h"
#include "pc/pc_main.h"
#include "pc/platform.h"
#include "pc/fs/fs.h"
#include "pc/gfx/gfx_cc.h"
#include "pc/gfx/gfx_pc.h"
#include "pc/gfx/gfx_rendering_api.h"
#include "pc/gfx/gfx_screen_config.h"
#include "pc/gfx/gfx_window_manager_api.h"
// this is used for multi-textures
// and it's quite a hack... instead of allowing 8 tiles, we basically only allow 2
#define G_TX_LOADTILE_6_UNKNOWN 6
//////////////////////////////////
// SCALE_M_N: upscale/downscale M-bit integer to N-bit
#define SCALE_5_8(VAL_) (((VAL_) * 0xFF) / 0x1F)
#define SCALE_8_5(VAL_) ((((VAL_) + 4) * 0x1F) / 0xFF)
#define SCALE_4_8(VAL_) ((VAL_) * 0x11)
#define SCALE_8_4(VAL_) ((VAL_) / 0x11)
#define SCALE_3_8(VAL_) ((VAL_) * 0x24)
#define SCALE_8_3(VAL_) ((VAL_) / 0x24)
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
#define HALF_SCREEN_WIDTH (SCREEN_WIDTH / 2)
#define HALF_SCREEN_HEIGHT (SCREEN_HEIGHT / 2)
#define RATIO_X (gfx_current_dimensions.width / (2.0f * HALF_SCREEN_WIDTH))
#define RATIO_Y (gfx_current_dimensions.height / (2.0f * HALF_SCREEN_HEIGHT))
#define MAX_BUFFERED 256
#define MAX_LIGHTS 18
#define MAX_VERTICES 64
# define MAX_CACHED_TEXTURES 4096 // for preloading purposes
# define HASH_SHIFT 0
#define HASHMAP_LEN (MAX_CACHED_TEXTURES * 2)
#define HASH_MASK (HASHMAP_LEN - 1)
#define RDP_TILES 8
u8 gGfxPcResetTex1 = 0;
struct RGBA {
uint8_t r, g, b, a;
};
struct XYWidthHeight {
uint16_t x, y, width, height;
};
struct LoadedVertex {
float x, y, z, w;
float u, v;
struct RGBA color;
uint8_t fog_z;
uint8_t clip_rej;
};
struct TextureHashmapNode {
struct TextureHashmapNode *next;
const uint8_t *texture_addr;
uint8_t fmt, siz;
uint32_t texture_id;
uint8_t cms, cmt;
bool linear_filter;
};
static struct {
struct TextureHashmapNode *hashmap[HASHMAP_LEN];
struct TextureHashmapNode pool[MAX_CACHED_TEXTURES];
uint32_t pool_pos;
} gfx_texture_cache;
static struct TextureCache gfx_texture_cache = { 0 };
static struct ColorCombiner color_combiner_pool[CC_MAX_SHADERS] = { 0 };
static uint8_t color_combiner_pool_size = 0;
static uint8_t color_combiner_pool_index = 0;
static struct RSP {
float modelview_matrix_stack[11][4][4];
uint8_t modelview_matrix_stack_size;
ALIGNED16 float MP_matrix[4][4];
ALIGNED16 float P_matrix[4][4];
Light_t current_lights[MAX_LIGHTS + 1];
float current_lights_coeffs[MAX_LIGHTS][3];
float current_lookat_coeffs[2][3]; // lookat_x, lookat_y
uint8_t current_num_lights; // includes ambient light
bool lights_changed;
ALIGNED16 Mat4 MP_matrix;
ALIGNED16 Mat4 P_matrix;
ALIGNED16 Mat4 modelview_matrix_stack[MAX_MATRIX_STACK_SIZE];
uint32_t modelview_matrix_stack_size;
uint32_t geometry_mode;
int16_t fog_mul, fog_offset;
struct {
// U0.16
uint16_t s, t;
} texture_scaling_factor;
bool lights_changed;
uint8_t current_num_lights; // includes ambient light
Vec3f current_lights_coeffs[MAX_LIGHTS];
Vec3f current_lookat_coeffs[2]; // lookat_x, lookat_y
Light_t current_lights[MAX_LIGHTS + 1];
struct LoadedVertex loaded_vertices[MAX_VERTICES + 4];
struct GfxVertex loaded_vertices[MAX_VERTICES + 4];
} rsp;
#define RDP_TILES 2
static struct RDP {
const uint8_t *palette;
struct {
const uint8_t *addr;
uint8_t siz;
uint8_t tile_number;
} texture_to_load;
struct {
const uint8_t *addr;
uint32_t size_bytes;
} loaded_texture[RDP_TILES];
struct {
uint8_t fmt;
uint8_t siz;
uint8_t cms, cmt;
uint16_t uls, ult, lrs, lrt; // U10.2
uint32_t line_size_bytes;
} texture_tile;
struct UnloadedTex texture_to_load;
struct TextureTile texture_tile;
struct GfxTexture loaded_texture[RDP_TILES];
bool textures_changed[RDP_TILES];
uint32_t other_mode_l, other_mode_h;
struct CombineMode combine_mode;
struct RGBA env_color, prim_color, fog_color, fill_color;
struct XYWidthHeight viewport, scissor;
struct Box viewport, scissor;
bool viewport_or_scissor_changed;
void *z_buf_address;
void *color_image_address;
@ -171,21 +98,21 @@ static struct RenderingState {
bool depth_mask;
bool decal_mode;
bool alpha_blend;
struct XYWidthHeight viewport, scissor;
struct Box viewport, scissor;
struct ShaderProgram *shader_program;
struct TextureHashmapNode *textures[2];
} rendering_state;
struct GfxDimensions gfx_current_dimensions;
struct GfxDimensions gfx_current_dimensions = { 0 };
static bool dropped_frame;
static bool dropped_frame = false;
static float buf_vbo[MAX_BUFFERED * (26 * 3)]; // 3 vertices in a triangle and 26 floats per vtx
static size_t buf_vbo_len;
static size_t buf_vbo_num_tris;
static float buf_vbo[MAX_BUFFERED * (26 * 3)] = { 0.0f }; // 3 vertices in a triangle and 26 floats per vtx
static size_t buf_vbo_len = 0;
static size_t buf_vbo_num_tris = 0;
static struct GfxWindowManagerAPI *gfx_wapi;
static struct GfxRenderingAPI *gfx_rapi;
static struct GfxWindowManagerAPI *gfx_wapi = NULL;
static struct GfxRenderingAPI *gfx_rapi = NULL;
static f32 sDepthZAdd = 0;
static f32 sDepthZMult = 1;
@ -401,13 +328,13 @@ static bool gfx_texture_cache_lookup(int tile, struct TextureHashmapNode **n, co
}
gfx_rapi->select_texture(tile, (*node)->texture_id);
gfx_rapi->set_sampler_parameters(tile, false, 0, 0);
(*node)->cms = 0;
(*node)->cmt = 0;
(*node)->linear_filter = false;
(*node)->next = NULL;
(*node)->texture_addr = orig_addr;
(*node)->fmt = fmt;
(*node)->siz = siz;
(*node)->cms = 0;
(*node)->cmt = 0;
(*node)->linear_filter = false;
*n = *node;
return false;
#undef CMPADDR
@ -676,20 +603,13 @@ static void import_texture(int tile) {
//printf("Time diff: %d\n", t1 - t0);
}
static void gfx_normalize_vector(float v[3]) {
float s = sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
v[0] /= s;
v[1] /= s;
v[2] /= s;
}
static void gfx_transposed_matrix_mul(float res[3], const float a[3], const float b[4][4]) {
static void OPTIMIZE_O3 gfx_transposed_matrix_mul(Vec3f res, const Vec3f a, const Mat4 b) {
res[0] = a[0] * b[0][0] + a[1] * b[0][1] + a[2] * b[0][2];
res[1] = a[0] * b[1][0] + a[1] * b[1][1] + a[2] * b[1][2];
res[2] = a[0] * b[2][0] + a[1] * b[2][1] + a[2] * b[2][2];
}
static void calculate_normal_dir(const Light_t *light, float coeffs[3], bool applyLightingDir) {
static void calculate_normal_dir(const Light_t *light, Vec3f coeffs, bool applyLightingDir) {
float light_dir[3] = {
light->dir[0] / 127.0f,
light->dir[1] / 127.0f,
@ -703,24 +623,11 @@ static void calculate_normal_dir(const Light_t *light, float coeffs[3], bool app
}
gfx_transposed_matrix_mul(coeffs, light_dir, rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1]);
gfx_normalize_vector(coeffs);
vec3f_normalize2(coeffs);
}
static void OPTIMIZE_O3 gfx_matrix_mul(float res[4][4], const float a[4][4], const float b[4][4]) {
float tmp[4][4];
for (int32_t i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
tmp[i][j] = a[i][0] * b[0][j] +
a[i][1] * b[1][j] +
a[i][2] * b[2][j] +
a[i][3] * b[3][j];
}
}
memcpy(res, tmp, sizeof(tmp));
}
static void gfx_sp_matrix(uint8_t parameters, const int32_t *addr) {
float matrix[4][4];
static void OPTIMIZE_O3 gfx_sp_matrix(uint8_t parameters, const int32_t *addr) {
Mat4 matrix;
#if 0
// Original code when fixed point matrices were used
for (int32_t i = 0; i < 4; i++) {
@ -737,23 +644,23 @@ static void gfx_sp_matrix(uint8_t parameters, const int32_t *addr) {
if (parameters & G_MTX_PROJECTION) {
if (parameters & G_MTX_LOAD) {
memcpy(rsp.P_matrix, matrix, sizeof(matrix));
mtxf_copy(rsp.P_matrix, matrix);
} else {
gfx_matrix_mul(rsp.P_matrix, matrix, rsp.P_matrix);
mtxf_mul(rsp.P_matrix, matrix, rsp.P_matrix);
}
} else { // G_MTX_MODELVIEW
if ((parameters & G_MTX_PUSH) && rsp.modelview_matrix_stack_size < 11) {
if ((parameters & G_MTX_PUSH) && rsp.modelview_matrix_stack_size < MAX_MATRIX_STACK_SIZE) {
++rsp.modelview_matrix_stack_size;
memcpy(rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 2], sizeof(matrix));
mtxf_copy(rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 2]);
}
if (parameters & G_MTX_LOAD) {
memcpy(rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], matrix, sizeof(matrix));
mtxf_copy(rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], matrix);
} else {
gfx_matrix_mul(rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], matrix, rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1]);
mtxf_mul(rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], matrix, rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1]);
}
rsp.lights_changed = 1;
}
gfx_matrix_mul(rsp.MP_matrix, rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], rsp.P_matrix);
mtxf_mul(rsp.MP_matrix, rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], rsp.P_matrix);
}
static void gfx_sp_pop_matrix(uint32_t count) {
@ -761,7 +668,7 @@ static void gfx_sp_pop_matrix(uint32_t count) {
if (rsp.modelview_matrix_stack_size > 0) {
--rsp.modelview_matrix_stack_size;
if (rsp.modelview_matrix_stack_size > 0) {
gfx_matrix_mul(rsp.MP_matrix, rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], rsp.P_matrix);
mtxf_mul(rsp.MP_matrix, rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], rsp.P_matrix);
}
}
}
@ -774,8 +681,8 @@ static float gfx_adjust_x_for_aspect_ratio(float x) {
static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *vertices, bool luaVertexColor) {
if (!vertices) { return; }
float globalLightCached[2][3];
float vertexColorCached[3];
Vec3f globalLightCached[2];
Vec3f vertexColorCached;
if (rsp.geometry_mode & G_LIGHTING) {
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++)
@ -801,7 +708,7 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons
for (size_t i = 0; i < n_vertices; i++, dest_index++) {
const Vtx_t *v = &vertices[i].v;
const Vtx_tn *vn = &vertices[i].n;
struct LoadedVertex *d = &rsp.loaded_vertices[dest_index];
struct GfxVertex *d = &rsp.loaded_vertices[dest_index];
#ifdef __SSE__
__m128 ob0 = _mm_set1_ps(v->ob[0]);
@ -993,10 +900,10 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons
}
static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx) {
struct LoadedVertex *v1 = &rsp.loaded_vertices[vtx1_idx];
struct LoadedVertex *v2 = &rsp.loaded_vertices[vtx2_idx];
struct LoadedVertex *v3 = &rsp.loaded_vertices[vtx3_idx];
struct LoadedVertex *v_arr[3] = {v1, v2, v3};
struct GfxVertex *v1 = &rsp.loaded_vertices[vtx1_idx];
struct GfxVertex *v2 = &rsp.loaded_vertices[vtx2_idx];
struct GfxVertex *v3 = &rsp.loaded_vertices[vtx3_idx];
struct GfxVertex *v_arr[3] = {v1, v2, v3};
if (v1->clip_rej & v2->clip_rej & v3->clip_rej) {
// The whole triangle lies outside the visible area
@ -1364,7 +1271,6 @@ static void gfx_dp_set_texture_image(UNUSED uint32_t format, uint32_t size, UNUS
}
static void gfx_dp_set_tile(uint8_t fmt, uint32_t siz, uint32_t line, uint32_t tmem, uint8_t tile, uint32_t palette, uint32_t cmt, UNUSED uint32_t maskt, UNUSED uint32_t shiftt, uint32_t cms, UNUSED uint32_t masks, UNUSED uint32_t shifts) {
if (tile == G_TX_RENDERTILE) {
SUPPORT_CHECK(palette == 0); // palette should set upper 4 bits of color index in 4b mode
rdp.texture_tile.fmt = fmt;
@ -1525,10 +1431,10 @@ static void gfx_draw_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t lr
ulxf = gfx_adjust_x_for_aspect_ratio(ulxf);
lrxf = gfx_adjust_x_for_aspect_ratio(lrxf);
struct LoadedVertex* ul = &rsp.loaded_vertices[MAX_VERTICES + 0];
struct LoadedVertex* ll = &rsp.loaded_vertices[MAX_VERTICES + 1];
struct LoadedVertex* lr = &rsp.loaded_vertices[MAX_VERTICES + 2];
struct LoadedVertex* ur = &rsp.loaded_vertices[MAX_VERTICES + 3];
struct GfxVertex* ul = &rsp.loaded_vertices[MAX_VERTICES + 0];
struct GfxVertex* ll = &rsp.loaded_vertices[MAX_VERTICES + 1];
struct GfxVertex* lr = &rsp.loaded_vertices[MAX_VERTICES + 2];
struct GfxVertex* ur = &rsp.loaded_vertices[MAX_VERTICES + 3];
ul->x = ulxf;
ul->y = ulyf;
@ -1551,8 +1457,8 @@ static void gfx_draw_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t lr
ur->w = 1.0f;
// The coordinates for texture rectangle shall bypass the viewport setting
struct XYWidthHeight default_viewport = {0, 0, gfx_current_dimensions.width, gfx_current_dimensions.height};
struct XYWidthHeight viewport_saved = rdp.viewport;
struct Box default_viewport = {0, 0, gfx_current_dimensions.width, gfx_current_dimensions.height};
struct Box viewport_saved = rdp.viewport;
uint32_t geometry_mode_saved = rsp.geometry_mode;
rdp.viewport = default_viewport;
@ -1603,10 +1509,10 @@ static void gfx_dp_texture_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int3
float lrs = ((uls << 7) + dsdx * width) >> 7;
float lrt = ((ult << 7) + dtdy * height) >> 7;
struct LoadedVertex* ul = &rsp.loaded_vertices[MAX_VERTICES + 0];
struct LoadedVertex* ll = &rsp.loaded_vertices[MAX_VERTICES + 1];
struct LoadedVertex* lr = &rsp.loaded_vertices[MAX_VERTICES + 2];
struct LoadedVertex* ur = &rsp.loaded_vertices[MAX_VERTICES + 3];
struct GfxVertex* ul = &rsp.loaded_vertices[MAX_VERTICES + 0];
struct GfxVertex* ll = &rsp.loaded_vertices[MAX_VERTICES + 1];
struct GfxVertex* lr = &rsp.loaded_vertices[MAX_VERTICES + 2];
struct GfxVertex* ur = &rsp.loaded_vertices[MAX_VERTICES + 3];
ul->u = uls;
ul->v = ult;
lr->u = lrs;
@ -1644,7 +1550,7 @@ static void gfx_dp_fill_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t
}
for (int32_t i = MAX_VERTICES; i < MAX_VERTICES + 4; i++) {
struct LoadedVertex* v = &rsp.loaded_vertices[i];
struct GfxVertex* v = &rsp.loaded_vertices[i];
v->color = rdp.fill_color;
}
@ -2046,7 +1952,7 @@ static void OPTIMIZE_O3 djui_gfx_dp_execute_clipping(void) {
float maxV = rsp.loaded_vertices[start_index].v;
for (size_t i = start_index; i < dest_index; i++) {
struct LoadedVertex* d = &rsp.loaded_vertices[i];
struct GfxVertex* d = &rsp.loaded_vertices[i];
minX = fmin(minX, d->x);
maxX = fmax(maxX, d->x);
minY = fmin(minY, d->y);
@ -2063,7 +1969,7 @@ static void OPTIMIZE_O3 djui_gfx_dp_execute_clipping(void) {
float midU = (minU + maxU) / 2.0f;
float midV = (minV + maxV) / 2.0f;
for (size_t i = start_index; i < dest_index; i++) {
struct LoadedVertex* d = &rsp.loaded_vertices[i];
struct GfxVertex* d = &rsp.loaded_vertices[i];
if (d->x <= midX) {
d->x += (maxX - minX) * (sDjuiClipX1 / 255.0f);
} else {
@ -2143,104 +2049,11 @@ static void OPTIMIZE_O3 djui_gfx_dp_set_override(void* texture, uint32_t w, uint
static void OPTIMIZE_O3 djui_gfx_sp_simple_vertex(size_t n_vertices, size_t dest_index, const Vtx *vertices) {
gfx_sp_vertex(n_vertices, dest_index, vertices, false);
return;
/*
TODO: Figure out why the background of text goes black when mods print text
for (size_t i = 0; i < n_vertices; i++, dest_index++) {
const Vtx_t *v = &vertices[i].v;
struct LoadedVertex *d = &rsp.loaded_vertices[dest_index];
float x = v->ob[0] * rsp.MP_matrix[0][0] + v->ob[1] * rsp.MP_matrix[1][0] + v->ob[2] * rsp.MP_matrix[2][0] + rsp.MP_matrix[3][0];
float y = v->ob[0] * rsp.MP_matrix[0][1] + v->ob[1] * rsp.MP_matrix[1][1] + v->ob[2] * rsp.MP_matrix[2][1] + rsp.MP_matrix[3][1];
float z = v->ob[0] * rsp.MP_matrix[0][2] + v->ob[1] * rsp.MP_matrix[1][2] + v->ob[2] * rsp.MP_matrix[2][2] + rsp.MP_matrix[3][2];
float w = v->ob[0] * rsp.MP_matrix[0][3] + v->ob[1] * rsp.MP_matrix[1][3] + v->ob[2] * rsp.MP_matrix[2][3] + rsp.MP_matrix[3][3];
x = gfx_adjust_x_for_aspect_ratio(x);
short U = v->tc[0] * rsp.texture_scaling_factor.s >> 16;
short V = v->tc[1] * rsp.texture_scaling_factor.t >> 16;
d->color.r = v->cn[0];
d->color.g = v->cn[1];
d->color.b = v->cn[2];
d->u = U;
d->v = V;
d->x = x;
d->y = y;
d->z = z;
d->w = w;
d->color.a = v->cn[3];
}
*/
}
static void OPTIMIZE_O3 djui_gfx_sp_simple_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx) {
gfx_sp_tri1(vtx1_idx, vtx2_idx, vtx3_idx);
return;
/*
TODO: Figure out why the background of text goes black when mods print text
struct LoadedVertex *v1 = &rsp.loaded_vertices[vtx1_idx];
struct LoadedVertex *v2 = &rsp.loaded_vertices[vtx2_idx];
struct LoadedVertex *v3 = &rsp.loaded_vertices[vtx3_idx];
struct LoadedVertex *v_arr[3] = {v1, v2, v3};
uint32_t cc_id = rdp.combine_mode;
bool use_alpha = true;
cc_id |= SHADER_OPT_ALPHA;
if (!use_alpha) {
cc_id &= ~0xfff000;
}
struct ColorCombiner *comb = gfx_lookup_or_create_color_combiner(cc_id);
struct ShaderProgram *prg = comb->prg;
if (prg != rendering_state.shader_program) {
gfx_flush();
gfx_rapi->unload_shader(rendering_state.shader_program);
gfx_rapi->load_shader(prg);
rendering_state.shader_program = prg;
}
if (rdp.textures_changed[0]) {
gfx_flush();
import_texture(0);
rdp.textures_changed[0] = false;
}
uint32_t tex_width = (rdp.texture_tile.lrs - rdp.texture_tile.uls + 4) / 4;
uint32_t tex_height = (rdp.texture_tile.lrt - rdp.texture_tile.ult + 4) / 4;
bool z_is_from_0_to_1 = gfx_rapi->z_is_from_0_to_1();
for (int32_t i = 0; i < 3; i++) {
float z = v_arr[i]->z, w = v_arr[i]->w;
if (z_is_from_0_to_1) {
z = (z + w) / 2.0f;
}
buf_vbo[buf_vbo_len++] = v_arr[i]->x;
buf_vbo[buf_vbo_len++] = v_arr[i]->y;
buf_vbo[buf_vbo_len++] = z;
buf_vbo[buf_vbo_len++] = w;
float u = (v_arr[i]->u - rdp.texture_tile.uls * 8) / 32.0f;
float v = (v_arr[i]->v - rdp.texture_tile.ult * 8) / 32.0f;
buf_vbo[buf_vbo_len++] = u / tex_width;
buf_vbo[buf_vbo_len++] = v / tex_height;
struct RGBA *color;
color = &rdp.env_color;
buf_vbo[buf_vbo_len++] = color->r / 255.0f;
buf_vbo[buf_vbo_len++] = color->g / 255.0f;
buf_vbo[buf_vbo_len++] = color->b / 255.0f;
buf_vbo[buf_vbo_len++] = color->a / 255.0f;
}
if (++buf_vbo_num_tris == MAX_BUFFERED) {
gfx_flush();
}
*/
}
void gfx_pc_precomp_shader(uint32_t rgb1, uint32_t alpha1, uint32_t rgb2, uint32_t alpha2, uint32_t flags) {
@ -2269,7 +2082,6 @@ void OPTIMIZE_O3 ext_gfx_run_dl(Gfx* cmd) {
#else
gfx_sp_vertex((C0(0, 16)) / sizeof(Vtx), C0(16, 4), seg_addr(cmd->words.w1), false);
#endif
// djui_gfx_sp_simple_vertex(C0(12, 8), C0(1, 7) - C0(12, 8), seg_addr(cmd->words.w1));
break;
case G_TRI2_EXT:
djui_gfx_sp_simple_tri1(C0(16, 8) / 2, C0(8, 8) / 2, C0(0, 8) / 2);

View file

@ -2,19 +2,11 @@
#define GFX_PC_H
#include "types.h"
#include "pc/gfx/gfx.h"
struct GfxRenderingAPI;
struct GfxWindowManagerAPI;
struct GfxDimensions {
uint32_t width, height;
float aspect_ratio;
float x_adjust_ratio;
uint32_t x_adjust_4by3;
};
extern struct GfxDimensions gfx_current_dimensions;
extern Vec3f gLightingDir;
extern Color gLightingColor[2];
extern Color gVertexColor;

View file

@ -1403,11 +1403,10 @@ static struct LuaObjectField sLinearTransitionPointFields[LUA_LINEAR_TRANSITION_
{ "yaw", LVT_S16, offsetof(struct LinearTransitionPoint, yaw), false, LOT_NONE, 1, sizeof(s16) },
};
#define LUA_MARIO_ANIMATION_FIELD_COUNT 3
#define LUA_MARIO_ANIMATION_FIELD_COUNT 2
static struct LuaObjectField sMarioAnimationFields[LUA_MARIO_ANIMATION_FIELD_COUNT] = {
// { "animDmaTable", LVT_COBJECT_P, offsetof(struct MarioAnimation, animDmaTable), true, LOT_???, 1, sizeof(struct MarioAnimDmaRelatedThing*) }, <--- UNIMPLEMENTED
{ "currentAnimAddr", LVT_U8_P, offsetof(struct MarioAnimation, currentAnimAddr), true, LOT_POINTER, 1, sizeof(u8*) },
{ "padding", LVT_U8, offsetof(struct MarioAnimation, padding), false, LOT_NONE, 4, sizeof(u8) },
{ "targetAnim", LVT_COBJECT_P, offsetof(struct MarioAnimation, targetAnim), false, LOT_ANIMATION, 1, sizeof(struct Animation*) },
};
@ -1628,7 +1627,7 @@ static struct LuaObjectField sNetworkPlayerFields[LUA_NETWORK_PLAYER_FIELD_COUNT
{ "type", LVT_U8, offsetof(struct NetworkPlayer, type), true, LOT_NONE, 1, sizeof(u8) },
};
#define LUA_OBJECT_FIELD_COUNT 762
#define LUA_OBJECT_FIELD_COUNT 763
static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = {
{ "activeFlags", LVT_S16, offsetof(struct Object, activeFlags), false, LOT_NONE, 1, sizeof(s16) },
{ "allowRemoteInteractions", LVT_U8, offsetof(struct Object, allowRemoteInteractions), false, LOT_NONE, 1, sizeof(u8) },
@ -2047,6 +2046,7 @@ static struct LuaObjectField sObjectFields[LUA_OBJECT_FIELD_COUNT] = {
{ "oMarioBurnTimer", LVT_S32, offsetof(struct Object, oMarioBurnTimer), false, LOT_NONE, 1, sizeof(s32) },
{ "oMarioCannonInputYaw", LVT_S32, offsetof(struct Object, oMarioCannonInputYaw), false, LOT_NONE, 1, sizeof(s32) },
{ "oMarioCannonObjectYaw", LVT_S32, offsetof(struct Object, oMarioCannonObjectYaw), false, LOT_NONE, 1, sizeof(s32) },
{ "oMarioJumboStarCutscenePosZ", LVT_F32, offsetof(struct Object, oMarioJumboStarCutscenePosZ), false, LOT_NONE, 1, sizeof(f32) },
{ "oMarioLongJumpIsSlow", LVT_S32, offsetof(struct Object, oMarioLongJumpIsSlow), false, LOT_NONE, 1, sizeof(s32) },
{ "oMarioParticleFlags", LVT_S32, offsetof(struct Object, oMarioParticleFlags), false, LOT_NONE, 1, sizeof(s32) },
{ "oMarioPolePos", LVT_F32, offsetof(struct Object, oMarioPolePos), false, LOT_NONE, 1, sizeof(f32) },

View file

@ -19,158 +19,6 @@ char gSmluaConstants[] = ""
"__newindex = function (t,k,v)\n"
"end\n"
"}\n"
"--------------------\n"
"-- math functions --\n"
"--------------------\n"
"--- @param dest Vec3f\n"
"--- @param src Vec3f\n"
"--- @return Vec3f\n"
"function vec3f_copy(dest, src)\n"
"dest.x = src.x\n"
"dest.y = src.y\n"
"dest.z = src.z\n"
"return dest\n"
"end\n"
"--- @param dest Vec3f\n"
"--- @param x number\n"
"--- @param y number\n"
"--- @param z number\n"
"--- @return Vec3f\n"
"function vec3f_set(dest, x, y, z)\n"
"dest.x = x\n"
"dest.y = y\n"
"dest.z = z\n"
"return dest\n"
"end\n"
"--- @param dest Vec3f\n"
"--- @param a Vec3f\n"
"--- @return Vec3f\n"
"function vec3f_add(dest, a)\n"
"dest.x = dest.x + a.x\n"
"dest.y = dest.y + a.y\n"
"dest.z = dest.z + a.z\n"
"return dest\n"
"end\n"
"--- @param dest Vec3f\n"
"--- @param a Vec3f\n"
"--- @param b Vec3f\n"
"--- @return Vec3f\n"
"function vec3f_sum(dest, a, b)\n"
"dest.x = a.x + b.x\n"
"dest.y = a.y + b.y\n"
"dest.z = a.z + b.z\n"
"return dest\n"
"end\n"
"--- @param dest Vec3f\n"
"--- @param a number\n"
"--- @return Vec3f\n"
"function vec3f_mul(dest, a)\n"
"dest.x = dest.x * a\n"
"dest.y = dest.y * a\n"
"dest.z = dest.z * a\n"
"return dest\n"
"end\n"
"--- @param dest Vec3f\n"
"--- @return Vec3f\n"
"function vec3f_normalize(dest)\n"
"local divisor = math.sqrt(dest.x * dest.x + dest.y * dest.y + dest.z * dest.z)\n"
"if divisor == 0 then\n"
"return dest\n"
"end\n"
"local invsqrt = 1.0 / divisor\n"
"dest.x = dest.x * invsqrt\n"
"dest.y = dest.y * invsqrt\n"
"dest.z = dest.z * invsqrt\n"
"return dest\n"
"end\n"
"--- @param a Vec3f\n"
"--- @return number\n"
"function vec3f_length(a)\n"
"return math.sqrt(a.x * a.x + a.y * a.y + a.z * a.z)\n"
"end\n"
"--- @param a Vec3f\n"
"--- @param b Vec3f\n"
"--- @return number\n"
"function vec3f_dot(a, b)\n"
"return a.x * b.x + a.y * b.y + a.z * b.z\n"
"end\n"
"--- @param vec Vec3f\n"
"--- @param onto Vec3f\n"
"--- @return Vec3f\n"
"function vec3f_project(vec, onto)\n"
"local numerator = vec3f_dot(vec, onto)\n"
"local denominator = vec3f_dot(onto, onto)\n"
"local out = {}\n"
"vec3f_copy(out, onto)\n"
"vec3f_mul(out, numerator / denominator)\n"
"return out\n"
"end\n"
"--- @param v1 Vec3f\n"
"--- @param v2 Vec3f\n"
"--- @return number\n"
"function vec3f_dist(v1, v2)\n"
"dx = v1.x - v2.x\n"
"dy = v1.y - v2.y\n"
"dz = v1.z - v2.z\n"
"return math.sqrt(dx * dx + dy * dy + dz * dz)\n"
"end\n"
"--- @param dest Vec3s\n"
"--- @param src Vec3s\n"
"--- @return Vec3s\n"
"function vec3s_copy(dest, src)\n"
"dest.x = src.x\n"
"dest.y = src.y\n"
"dest.z = src.z\n"
"return dest\n"
"end\n"
"--- @param dest Vec3s\n"
"--- @param x number\n"
"--- @param y number\n"
"--- @param z number\n"
"--- @return Vec3s\n"
"function vec3s_set(dest, x, y, z)\n"
"dest.x = x\n"
"dest.y = y\n"
"dest.z = z\n"
"return dest\n"
"end\n"
"--- @param dest Vec3s\n"
"--- @param a Vec3s\n"
"--- @return Vec3s\n"
"function vec3s_add(dest, a)\n"
"dest.x = dest.x + a.x\n"
"dest.y = dest.y + a.y\n"
"dest.z = dest.z + a.z\n"
"return dest\n"
"end\n"
"--- @param dest Vec3s\n"
"--- @param a Vec3s\n"
"--- @param b Vec3s\n"
"--- @return Vec3s\n"
"function vec3s_sum(dest, a, b)\n"
"dest.x = a.x + b.x\n"
"dest.y = a.y + b.y\n"
"dest.z = a.z + b.z\n"
"return dest\n"
"end\n"
"--- @param dest Vec3s\n"
"--- @param a number\n"
"--- @return Vec3s\n"
"function vec3s_mul(dest, a)\n"
"dest.x = dest.x * a\n"
"dest.y = dest.y * a\n"
"dest.z = dest.z * a\n"
"return dest\n"
"end\n"
"--- @param v1 Vec3s\n"
"--- @param v2 Vec3s\n"
"--- @return number\n"
"function vec3s_dist(v1, v2)\n"
"dx = v1.x - v2.x\n"
"dy = v1.y - v2.y\n"
"dz = v1.z - v2.z\n"
"return math.sqrt(dx * dx + dy * dy + dz * dz)\n"
"end\n"
"-----------\n"
"-- sound --\n"
"-----------\n"
@ -281,7 +129,7 @@ char gSmluaConstants[] = ""
"--- @type integer\n"
"FONT_TINY = -1\n"
"--- @type integer\n"
"ANIM_FLAG_FORWARD = (1 << 1)\n"
"ANIM_FLAG_FORWARD = (1 <<\n"
"INSTANT_WARP_INDEX_START=0x00\n"
"INSTANT_WARP_INDEX_STOP=0x04\n"
"MAX_AREAS=16\n"

File diff suppressed because it is too large Load diff

View file

@ -207,19 +207,20 @@ extern const u8 texture_power_meter_three_segments[];
extern const u8 texture_power_meter_two_segments[];
extern const u8 texture_power_meter_one_segments[];
static struct TextureInfo sPowerMeterTexturesInfo[] = {
{ (u8*)texture_power_meter_left_side, "texture_power_meter_left_side", 32, 64, 8 },
{ (u8*)texture_power_meter_right_side, "texture_power_meter_right_side", 32, 64, 8 },
{ (u8*)texture_power_meter_one_segments, "texture_power_meter_one_segments", 32, 32, 8 },
{ (u8*)texture_power_meter_two_segments, "texture_power_meter_two_segments", 32, 32, 8 },
{ (u8*)texture_power_meter_three_segments, "texture_power_meter_three_segments", 32, 32, 8 },
{ (u8*)texture_power_meter_four_segments, "texture_power_meter_four_segments", 32, 32, 8 },
{ (u8*)texture_power_meter_five_segments, "texture_power_meter_five_segments", 32, 32, 8 },
{ (u8*)texture_power_meter_six_segments, "texture_power_meter_six_segments", 32, 32, 8 },
{ (u8*)texture_power_meter_seven_segments, "texture_power_meter_seven_segments", 32, 32, 8 },
{ (u8*)texture_power_meter_full, "texture_power_meter_full", 32, 32, 8 },
};
void hud_render_power_meter(s32 health, f32 x, f32 y, f32 width, f32 height) {
static struct TextureInfo sPowerMeterTexturesInfo[] = {
{ (u8*)texture_power_meter_left_side, 8, 32, 64, "texture_power_meter_left_side" },
{ (u8*)texture_power_meter_right_side, 8, 32, 64, "texture_power_meter_right_side" },
{ (u8*)texture_power_meter_one_segments, 8, 32, 32, "texture_power_meter_one_segments" },
{ (u8*)texture_power_meter_two_segments, 8, 32, 32, "texture_power_meter_two_segments" },
{ (u8*)texture_power_meter_three_segments, 8, 32, 32, "texture_power_meter_three_segments" },
{ (u8*)texture_power_meter_four_segments, 8, 32, 32, "texture_power_meter_four_segments" },
{ (u8*)texture_power_meter_five_segments, 8, 32, 32, "texture_power_meter_five_segments" },
{ (u8*)texture_power_meter_six_segments, 8, 32, 32, "texture_power_meter_six_segments" },
{ (u8*)texture_power_meter_seven_segments, 8, 32, 32, "texture_power_meter_seven_segments" },
{ (u8*)texture_power_meter_full, 8, 32, 32, "texture_power_meter_full" },
};
djui_hud_render_texture(&sPowerMeterTexturesInfo[0], x, y, width / 64, height / 64);
djui_hud_render_texture(&sPowerMeterTexturesInfo[1], x + (width - 2) / 2, y, width / 64, height / 64);
s32 numWedges = MIN(MAX(health >> 8, 0), 8);
@ -229,19 +230,6 @@ void hud_render_power_meter(s32 health, f32 x, f32 y, f32 width, f32 height) {
}
void hud_render_power_meter_interpolated(s32 health, f32 prevX, f32 prevY, f32 prevWidth, f32 prevHeight, f32 x, f32 y, f32 width, f32 height) {
static struct TextureInfo sPowerMeterTexturesInfo[] = {
{ (u8*)texture_power_meter_left_side, 8, 32, 64, "texture_power_meter_left_side" },
{ (u8*)texture_power_meter_right_side, 8, 32, 64, "texture_power_meter_right_side" },
{ (u8*)texture_power_meter_one_segments, 8, 32, 32, "texture_power_meter_one_segments" },
{ (u8*)texture_power_meter_two_segments, 8, 32, 32, "texture_power_meter_two_segments" },
{ (u8*)texture_power_meter_three_segments, 8, 32, 32, "texture_power_meter_three_segments" },
{ (u8*)texture_power_meter_four_segments, 8, 32, 32, "texture_power_meter_four_segments" },
{ (u8*)texture_power_meter_five_segments, 8, 32, 32, "texture_power_meter_five_segments" },
{ (u8*)texture_power_meter_six_segments, 8, 32, 32, "texture_power_meter_six_segments" },
{ (u8*)texture_power_meter_seven_segments, 8, 32, 32, "texture_power_meter_seven_segments" },
{ (u8*)texture_power_meter_full, 8, 32, 32, "texture_power_meter_full" },
};
djui_hud_render_texture_interpolated(&sPowerMeterTexturesInfo[0],
prevX, prevY, prevWidth / 64, prevHeight / 64,
x, y, width / 64, height / 64);