Getting Started
SH4ZAM is a hand-optimized, general-purpose math and linear algebra library for harnessing the floating-point power of the SH4 processor in the Sega Dreamcast. Install it, include one header, link libsh4zam.a, and make some gainz.
Install
Section titled “Install”Pick one:
- KallistiOS (Dreamcast). SH4ZAM is an official part of kos-ports. If you followed the standard KallistiOS setup, it is already installed. Otherwise run
make installfromkos-ports/sh4zam. Details: Install with KallistiOS. - CMake (any platform).
mkdir build && cd build && cmake .. && make && make installfrom the repo root. On anything that is not a Dreamcast this builds the portable software back-end. Details: Install with CMake.
Include and link
Section titled “Include and link”In order to use SH4ZAM within your project, you must do two things:
- Include the header file(s) within your code.
#include <sh4zam/shz_sh4zam.h>globally includes the whole SH4ZAM C API.#include <sh4zam/shz_sh4zam.hpp>globally includes the whole SH4ZAM C++ API.
- Link to the statically linked library,
libsh4zam.a, within your build system.
Unless you link to SH4ZAM, your project will compile correctly, yet fail to link. With a KallistiOS Makefile, add -lsh4zam:
$(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) -lsh4zamWith CMake:
target_link_libraries(MyProject PUBLIC -lsh4zam)More on this in Using Within a Project.
First program
Section titled “First program”These are the usage samples from the upstream README. Both build an XMTRX transform, store it, and transform a vector by it.
#include <sh4zam/shz_sh4zam.h>
int main(int argc, const char *argv[]) { shz_vec4_t vec1 = shz_vec4_init(2.0f, 3.0f, 4.0f, 1.0f); shz_vec4_t vec2 = shz_vec4_normalize(shz_vec4_scale(vec1, shz_sinf(SHZ_F_PI))); shz_mat4x4_t mat = {};
shz_xmtrx_init_diagonal(vec2.x, vec2.y, vec2.z, vec2.w); shz_xmtrx_apply_rotation_x(shz_vec4_dot(vec1, vec2)); shz_xmtrx_apply_translation(vec1.x, vec1.y, vec1.z); shz_xmtrx_store_4x4(&mat);
shz_vec4_t vec3 = shz_xmtrx_transform_vec4(vec2);
return 0;}Where applicable, the C API also includes type-generic routines which resolve to the proper function based on argument type. For example, shz_vec_dot() forwards to shz_vec2_dot(), shz_vec3_dot() or shz_vec4_dot() depending on the vectors passed to it.
#include <sh4zam/shz_sh4zam.hpp>
int main(int argc, const char* argv[]) { shz::vec4 vec1(2.0f, 3.0f, 4.0f, 1.0f); shz::vec4 vec2 = shz::vec4(vec1 * shz::sinf(shz::pi_f)).direction(); shz::mat4x4 mat {};
shz::xmtrx::init_diagonal(vec2.x, vec2.y, vec2.z, vec2.w); shz::xmtrx::apply_rotation_x(vec1.dot(vec2)); shz::xmtrx::apply_translation(vec1.x, vec1.y, vec1.z); shz::xmtrx::store(&mat);
shz::vec4 vec3 = shz::xmtrx::transform(vec2);
return 0;}Upstream's README passes vec2.y, vec2.z to apply_translation() in the C++ version; it is fixed to match the C version here. C++ can still use the C API by design, and every C++ type is also compatible with its corresponding C type and the C API, so you can mix and match.
The C sample uses {} empty initialization, which is C23. With an older C standard, write shz_mat4x4_t mat = {0};.
Run Bruce's Balls
Section titled “Run Bruce's Balls”At this point it is advised that you check out and attempt to run the examples provided with SH4ZAM. If you installed through kos-ports they live in kos-ports/examples/sh4zam; type make in an example's folder to build it. You can quickly verify the integrity of your SH4ZAM install by playing with Bruce's Balls, which renders 93 high-polygon spheres and reports polygons per second. See Examples for a walkthrough of what it does.
- Matrix Transforms: where the easiest gainz usually are.
- Naming and Suffixes: what
_fsrra,_safe,_unalignedand friends mean. - Conventions: column-major matrices,
<W, X, Y, Z>quaternions, radians.