shithub: wipeout

Download patch

ref: 5a3b2d2d794a9839a0547901cda463a892574b60
parent: 41399234f6694133bbd64910b86ff61bce67367a
author: Jacob Moody <moody@posixcafe.org>
date: Fri Aug 25 18:37:54 EDT 2023

build and link

--- /dev/null
+++ b/mkfile
@@ -1,0 +1,6 @@
+</$objtype/mkfile
+
+default:VQ: all
+
+all install clean nuke test:VQ:
+	@{ cd src && mk $target }
--- a/src/input.h
+++ b/src/input.h
@@ -156,9 +156,9 @@
 typedef void(*input_capture_callback_t)
 	(void *user, button_t button, int32_t ascii_char);
 
-void input_init();
-void input_cleanup();
-void input_clear();
+void input_init(void);
+void input_cleanup(void);
+void input_clear(void);
 
 void input_bind(input_layer_t layer, button_t button, uint8_t action);
 void input_unbind(input_layer_t layer,button_t button);
--- a/src/mem.c
+++ b/src/mem.c
@@ -9,7 +9,7 @@
 static uint32_t bump_len = 0;
 static uint32_t temp_len = 0;
 
-static uint32_t temp_objects[MEM_TEMP_OBJECTS_MAX] = {};
+static uint32_t temp_objects[MEM_TEMP_OBJECTS_MAX];
 static uint32_t temp_objects_len;
 
 
--- a/src/mem.h
+++ b/src/mem.h
@@ -7,11 +7,11 @@
 #define MEM_HUNK_BYTES (4 * 1024 * 1024)
 
 void *mem_bump(uint32_t size);
-void *mem_mark();
+void *mem_mark(void);
 void mem_reset(void *p);
 
 void *mem_temp_alloc(uint32_t size);
 void mem_temp_free(void *p);
-void mem_temp_check();
+void mem_temp_check(void);
 
 #endif
--- /dev/null
+++ b/src/mkfile
@@ -1,0 +1,69 @@
+</$objtype/mkfile
+
+CFLAGS=-Fp -I/sys/include/npe -I/sys/include/npe/SDL2 -D__plan9__ -D__${objtype}__ -DRENDERER_SOFTWARE
+BIN=/$objtype/bin/games
+TARG=wipeout
+
+OFILES=\
+	race.$O \
+	camera.$O \
+	object.$O \
+	droid.$O \
+	ui.$O \
+	hud.$O \
+	image.$O \
+	game.$O \
+	menu.$O \
+	main_menu.$O \
+	ingame_menus.$O \
+	title.$O \
+	intro.$O \
+	scene.$O \
+	ship.$O \
+	ship_ai.$O \
+	ship_player.$O \
+	track.$O \
+	weapon.$O \
+	particle.$O \
+	sfx.$O \
+	utils.$O \
+	types.$O \
+	system.$O \
+	mem.$O \
+	input.$O \
+	render_software.$O \
+	platform_sdl.$O \
+
+default:V:	$O.out
+
+all:V:	$O.out
+
+$O.out: $OFILES $LIB
+	$LD $LDFLAGS -o $target $prereq
+
+%.$O:	$HFILES		# don't combine with following %.$O rules
+
+%.$O:	wipeout/%.c
+	$CC $CFLAGS $prereq
+
+%.$O:	%.c
+	$CC $CFLAGS $stem.c
+
+install:V:	$BIN/$TARG
+
+$BIN/$TARG:	$O.out
+	cp $prereq $BIN/$TARG
+
+installall:V:
+	for(objtype in $CPUS)
+		mk install
+
+allall:V:
+	for(objtype in $CPUS)
+		mk all
+
+nuke:V:
+	rm -f *.[$OS] [$OS].out y.tab.? lex.yy.c y.debug y.output *.acid $TARG $CLEANFILES
+
+clean:V:
+	rm -f *.[$OS] [$OS].out y.tab.? lex.yy.c y.debug y.output $TARG $CLEANFILES
--- a/src/platform.h
+++ b/src/platform.h
@@ -3,9 +3,9 @@
 
 #include "types.h"
 
-void platform_exit();
-vec2i_t platform_screen_size();
-double platform_now();
+void platform_exit(void);
+vec2i_t platform_screen_size(void);
+double platform_now(void);
 void platform_set_fullscreen(bool fullscreen);
 void platform_set_audio_mix_cb(void (*cb)(float *buffer, uint32_t len));
 
--- a/src/platform_sdl.c
+++ b/src/platform_sdl.c
@@ -8,57 +8,13 @@
 static bool wants_to_exit = false;
 static SDL_Window *window;
 static SDL_AudioDeviceID audio_device;
-static SDL_GameController *gamepad;
 static void (*audio_callback)(float *buffer, uint32_t len) = NULL;
 
-
-uint8_t platform_sdl_gamepad_map[] = {
-	[SDL_CONTROLLER_BUTTON_A] = INPUT_GAMEPAD_A,
-	[SDL_CONTROLLER_BUTTON_B] = INPUT_GAMEPAD_B,
-	[SDL_CONTROLLER_BUTTON_X] = INPUT_GAMEPAD_X,
-	[SDL_CONTROLLER_BUTTON_Y] = INPUT_GAMEPAD_Y,
-	[SDL_CONTROLLER_BUTTON_BACK] = INPUT_GAMEPAD_SELECT,
-	[SDL_CONTROLLER_BUTTON_GUIDE] = INPUT_GAMEPAD_HOME,
-	[SDL_CONTROLLER_BUTTON_START] = INPUT_GAMEPAD_START,
-	[SDL_CONTROLLER_BUTTON_LEFTSTICK] = INPUT_GAMEPAD_L_STICK_PRESS,
-	[SDL_CONTROLLER_BUTTON_RIGHTSTICK] = INPUT_GAMEPAD_R_STICK_PRESS,
-	[SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = INPUT_GAMEPAD_L_SHOULDER,
-	[SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = INPUT_GAMEPAD_R_SHOULDER,
-	[SDL_CONTROLLER_BUTTON_DPAD_UP] = INPUT_GAMEPAD_DPAD_UP,
-	[SDL_CONTROLLER_BUTTON_DPAD_DOWN] = INPUT_GAMEPAD_DPAD_DOWN,
-	[SDL_CONTROLLER_BUTTON_DPAD_LEFT] = INPUT_GAMEPAD_DPAD_LEFT,
-	[SDL_CONTROLLER_BUTTON_DPAD_RIGHT] = INPUT_GAMEPAD_DPAD_RIGHT,
-	[SDL_CONTROLLER_BUTTON_MAX] = INPUT_INVALID
-};
-
-
-uint8_t platform_sdl_axis_map[] = {
-	[SDL_CONTROLLER_AXIS_LEFTX] = INPUT_GAMEPAD_L_STICK_LEFT,
-	[SDL_CONTROLLER_AXIS_LEFTY] = INPUT_GAMEPAD_L_STICK_UP,
-	[SDL_CONTROLLER_AXIS_RIGHTX] = INPUT_GAMEPAD_R_STICK_LEFT,
-	[SDL_CONTROLLER_AXIS_RIGHTY] = INPUT_GAMEPAD_R_STICK_UP,
-	[SDL_CONTROLLER_AXIS_TRIGGERLEFT] = INPUT_GAMEPAD_L_TRIGGER,
-	[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] = INPUT_GAMEPAD_R_TRIGGER,
-	[SDL_CONTROLLER_AXIS_MAX] = INPUT_INVALID
-};
-
-
 void platform_exit() {
 	wants_to_exit = true;
 }
 
-SDL_GameController *platform_find_gamepad() {
-	for (int i = 0; i < SDL_NumJoysticks(); i++) {
-		if (SDL_IsGameController(i)) {
-			return SDL_GameControllerOpen(i);
-		}
-	}
-
-	return NULL;
-}
-
-
-void platform_pump_events() {
+void platform_pump_events(void) {
 	SDL_Event ev;
 	while (SDL_PollEvent(&ev)) {
 		// Input Keyboard
@@ -77,55 +33,6 @@
 		else if (ev.type == SDL_TEXTINPUT) {
 			input_textinput(ev.text.text[0]);
 		}
-
-		// Gamepads connect/disconnect
-		else if (ev.type == SDL_CONTROLLERDEVICEADDED) {
-			gamepad = SDL_GameControllerOpen(ev.cdevice.which);
-		}
-		else if (ev.type == SDL_CONTROLLERDEVICEREMOVED) {
-			if (gamepad && ev.cdevice.which == SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamepad))) {
-				SDL_GameControllerClose(gamepad);
-				gamepad = platform_find_gamepad();
-			}
-		}
-
-		// Input Gamepad Buttons
-		else if (
-			ev.type == SDL_CONTROLLERBUTTONDOWN || 
-			ev.type == SDL_CONTROLLERBUTTONUP
-		) {
-			if (ev.cbutton.button < SDL_CONTROLLER_BUTTON_MAX) {
-				button_t button = platform_sdl_gamepad_map[ev.cbutton.button];
-				if (button != INPUT_INVALID) {
-					float state = ev.type == SDL_CONTROLLERBUTTONDOWN ? 1.0 : 0.0;
-					input_set_button_state(button, state);
-				}
-			}
-		}
-
-		// Input Gamepad Axis
-		else if (ev.type == SDL_CONTROLLERAXISMOTION) {
-			float state = (float)ev.caxis.value / 32767.0;
-
-			if (ev.caxis.axis < SDL_CONTROLLER_AXIS_MAX) {
-				int code = platform_sdl_axis_map[ev.caxis.axis];
-				if (
-					code == INPUT_GAMEPAD_L_TRIGGER || 
-					code == INPUT_GAMEPAD_R_TRIGGER
-				) {
-					input_set_button_state(code, state);
-				}
-				else if (state > 0) {
-					input_set_button_state(code, 0.0);
-					input_set_button_state(code+1, state);
-				}
-				else {
-					input_set_button_state(code, -state);
-					input_set_button_state(code+1, 0.0);
-				}
-			}
-		}
-
 		// Mouse buttons
 		else if (
 			ev.type == SDL_MOUSEBUTTONDOWN ||
@@ -180,7 +87,8 @@
 }
 
 void platform_set_fullscreen(bool fullscreen) {
-	if (fullscreen) {
+	if (0) {
+	/*
 		int32_t display = SDL_GetWindowDisplayIndex(window);
 		
 		SDL_DisplayMode mode;
@@ -188,6 +96,7 @@
 		SDL_SetWindowDisplayMode(window, &mode);
 		SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
 		SDL_ShowCursor(SDL_DISABLE);
+	*/
 	}
 	else {
 		SDL_SetWindowFullscreen(window, 0);
@@ -250,32 +159,33 @@
 	static SDL_Texture *screenbuffer = NULL;
 	static void *screenbuffer_pixels = NULL;
 	static int screenbuffer_pitch;
-	static vec2i_t screenbuffer_size = vec2i(0, 0);
-	static vec2i_t screen_size = vec2i(0, 0);
+	static vec2i_t screenbuffer_size;
+	static vec2i_t screen_size;
 
-
-	void platform_video_init() {
+	void platform_video_init(void) {
+		screenbuffer_size = vec2i(0, 0);
+		screen_size = vec2i(0, 0);
 		renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
 	}
 
-	void platform_video_cleanup() {
+	void platform_video_cleanup(void) {
 		
 	}
 
-	void platform_prepare_frame() {
+	void platform_prepare_frame(void) {
 		if (screen_size.x != screenbuffer_size.x || screen_size.y != screenbuffer_size.y) {
 			if (screenbuffer) {
 				SDL_DestroyTexture(screenbuffer);
 			}
-			screenbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, screen_size.x, screen_size.y);
+			screenbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, screen_size.x, screen_size.y);
 			screenbuffer_size = screen_size;
 		}
-		SDL_LockTexture(screenbuffer, NULL, &screenbuffer_pixels, &screenbuffer_pitch);
+		//SDL_LockTexture(screenbuffer, NULL, &screenbuffer_pixels, &screenbuffer_pitch);
 	}
 
-	void platform_end_frame() {
+	void platform_end_frame(void) {
 		screenbuffer_pixels = NULL;
-		SDL_UnlockTexture(screenbuffer);
+		//SDL_UnlockTexture(screenbuffer);
 		SDL_RenderCopy(renderer, screenbuffer, NULL, NULL);
 		SDL_RenderPresent(renderer);
 	}
@@ -285,7 +195,7 @@
 		return screenbuffer_pixels;
 	}
 
-	vec2i_t platform_screen_size() {
+	vec2i_t platform_screen_size(void) {
 		int width, height;
 		SDL_GetWindowSize(window, &width, &height);
 
@@ -302,25 +212,17 @@
 
 
 int main(int argc, char *argv[]) {
-	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
+	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
 
-	int gcdb_res = SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt");
-	if (gcdb_res < 0) {
-		printf("Failed to load gamecontrollerdb.txt\n");
-	}
-	else {
-		printf("load gamecontrollerdb.txt\n");
-	}
-
-	audio_device = SDL_OpenAudioDevice(NULL, 0, &(SDL_AudioSpec){
+	SDL_AudioSpec spec = {
 		.freq = 44100,
 		.format = AUDIO_F32,
 		.channels = 2,
 		.samples = 1024,
 		.callback = platform_audio_callback
-	}, NULL, 0);
+	};
 
-	gamepad = platform_find_gamepad();
+	audio_device = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0);
 
 	perf_freq = SDL_GetPerformanceFrequency();
 
--- a/src/render.h
+++ b/src/render.h
@@ -28,18 +28,18 @@
 extern uint16_t RENDER_NO_TEXTURE;
 
 void render_init(vec2i_t screen_size);
-void render_cleanup();
+void render_cleanup(void);
 
 void render_set_screen_size(vec2i_t size);
 void render_set_resolution(render_resolution_t res);
 void render_set_post_effect(render_post_effect_t post);
-vec2i_t render_size();
+vec2i_t render_size(void);
 
-void render_frame_prepare();
-void render_frame_end();
+void render_frame_prepare(void);
+void render_frame_end(void);
 
 void render_set_view(vec3_t pos, vec3_t angles);
-void render_set_view_2d();
+void render_set_view_2d(void);
 void render_set_model_mat(mat4_t *m);
 void render_set_depth_write(bool enabled);
 void render_set_depth_test(bool enabled);
@@ -57,7 +57,7 @@
 uint16_t render_texture_create(uint32_t width, uint32_t height, rgba_t *pixels);
 vec2i_t render_texture_size(uint16_t texture_index);
 void render_texture_replace_pixels(int16_t texture_index, rgba_t *pixels);
-uint16_t render_textures_len();
+uint16_t render_textures_len(void);
 void render_textures_reset(uint16_t len);
 void render_textures_dump(const char *path);
 
--- a/src/render_software.c
+++ b/src/render_software.c
@@ -21,10 +21,11 @@
 static int32_t screen_ppr;
 static vec2i_t screen_size;
 
-static mat4_t view_mat = mat4_identity();
-static mat4_t mvp_mat = mat4_identity();
-static mat4_t projection_mat = mat4_identity();
-static mat4_t sprite_mat = mat4_identity();
+/* TODO(moody): FIX */
+static mat4_t view_mat;
+static mat4_t mvp_mat;
+static mat4_t projection_mat;
+static mat4_t sprite_mat;
 
 static render_texture_t textures[TEXTURES_MAX];
 static uint32_t textures_len;
@@ -89,7 +90,8 @@
 	mat4_translate(&view_mat, vec3_inv(pos));
 	mat4_set_yaw_pitch_roll(&sprite_mat, vec3(-angles.x, angles.y - M_PI, 0));
 
-	render_set_model_mat(&mat4_identity());
+	mat4_t _mat = mat4_identity();
+	render_set_model_mat(&_mat);
 }
 
 void render_set_view_2d() {
@@ -146,8 +148,12 @@
 	color.as_rgba.r = min(color.as_rgba.r * 2, 255);
 	color.as_rgba.g = min(color.as_rgba.g * 2, 255);
 	color.as_rgba.b = min(color.as_rgba.b * 2, 255);
-	color.as_rgba.a = clamp(color.as_rgba.a * (1.0-p0.z) * FAR_PLANE * (2.0/255.0), 0, 255);
 
+	float _v = color.as_rgba.a * (1.0-p0.z) * FAR_PLANE * (2.0/255.0);
+	float _min = 0;
+	float _max = 1;
+	color.as_rgba.a = _v > _max ? _max : _v < _min ? _min : _v;
+
 	line(sc0, sc1, color);
 	line(sc1, sc2, color);
 	line(sc2, sc0, color);
@@ -154,6 +160,7 @@
 }
 
 void render_push_sprite(vec3_t pos, vec2i_t size, rgba_t color, uint16_t texture_index) {
+	tris_t _tris;
 	error_if(texture_index >= textures_len, "Invalid texture %d", texture_index);
 
 	vec3_t p0 = vec3_add(pos, vec3_transform(vec3(-size.x * 0.5, -size.y * 0.5, 0), &sprite_mat));
@@ -162,20 +169,15 @@
 	vec3_t p3 = vec3_add(pos, vec3_transform(vec3( size.x * 0.5,  size.y * 0.5, 0), &sprite_mat));
 
 	render_texture_t *t = &textures[texture_index];
-	render_push_tris((tris_t){
-		.vertices = {
-			{.pos = p0, .uv = {0, 0}, .color = color},
-			{.pos = p1, .uv = {0 + t->size.x ,0}, .color = color},
-			{.pos = p2, .uv = {0, 0 + t->size.y}, .color = color},
-		}
-	}, texture_index);
-	render_push_tris((tris_t){
-		.vertices = {
-			{.pos = p2, .uv = {0, 0 + t->size.y}, .color = color},
-			{.pos = p1, .uv = {0 + t->size.x, 0}, .color = color},
-			{.pos = p3, .uv = {0 + t->size.x, 0 + t->size.y}, .color = color},
-		}
-	}, texture_index);
+	_tris.vertices[0] = (vertex_t){p0, (vec2_t){0, 0}, color};
+	_tris.vertices[1] = (vertex_t){p1, (vec2_t){0 + t->size.x ,0}, color};
+	_tris.vertices[2] = (vertex_t){p2, (vec2_t){0, 0 + t->size.y}, color};
+	render_push_tris(_tris, texture_index);
+
+	_tris.vertices[0] = (vertex_t){p2, (vec2_t){0, 0 + t->size.y}, color};
+	_tris.vertices[1] = (vertex_t){p1, (vec2_t){0 + t->size.x, 0}, color};
+	_tris.vertices[2] = (vertex_t){p3, (vec2_t){0 + t->size.x, 0 + t->size.y}, color};
+	render_push_tris(_tris, texture_index);
 }
 
 void render_push_2d(vec2i_t pos, vec2i_t size, rgba_t color, uint16_t texture_index) {
@@ -183,22 +185,18 @@
 }
 
 void render_push_2d_tile(vec2i_t pos, vec2i_t uv_offset, vec2i_t uv_size, vec2i_t size, rgba_t color, uint16_t texture_index) {
+	tris_t _tris;
 	error_if(texture_index >= textures_len, "Invalid texture %d", texture_index);
-	render_push_tris((tris_t){
-		.vertices = {
-			{.pos = {pos.x, pos.y + size.y, 0}, .uv = {uv_offset.x , uv_offset.y + uv_size.y}, .color = color},
-			{.pos = {pos.x + size.x, pos.y, 0}, .uv = {uv_offset.x +  uv_size.x, uv_offset.y}, .color = color},
-			{.pos = {pos.x, pos.y, 0}, .uv = {uv_offset.x , uv_offset.y}, .color = color},
-		}
-	}, texture_index);
 
-	render_push_tris((tris_t){
-		.vertices = {
-			{.pos = {pos.x + size.x, pos.y + size.y, 0}, .uv = {uv_offset.x + uv_size.x, uv_offset.y + uv_size.y}, .color = color},
-			{.pos = {pos.x + size.x, pos.y, 0}, .uv = {uv_offset.x + uv_size.x, uv_offset.y}, .color = color},
-			{.pos = {pos.x, pos.y + size.y, 0}, .uv = {uv_offset.x , uv_offset.y + uv_size.y}, .color = color},
-		}
-	}, texture_index);
+	_tris.vertices[0] = (vertex_t){(vec3_t){pos.x, pos.y + size.y, 0}, (vec2_t){uv_offset.x , uv_offset.y + uv_size.y}, color};
+	_tris.vertices[1] = (vertex_t){(vec3_t){pos.x + size.x, pos.y, 0}, (vec2_t){uv_offset.x +  uv_size.x, uv_offset.y}, color};
+	_tris.vertices[2] = (vertex_t){(vec3_t){pos.x, pos.y, 0}, (vec2_t){uv_offset.x , uv_offset.y}, color};
+	render_push_tris(_tris, texture_index);
+
+	_tris.vertices[0] = (vertex_t){(vec3_t){pos.x + size.x, pos.y + size.y, 0}, (vec2_t){uv_offset.x + uv_size.x, uv_offset.y + uv_size.y}, color};
+	_tris.vertices[1] = (vertex_t){(vec3_t){pos.x + size.x, pos.y, 0}, (vec2_t){uv_offset.x + uv_size.x, uv_offset.y}, color};
+	_tris.vertices[2] = (vertex_t){(vec3_t){pos.x, pos.y + size.y, 0}, (vec2_t){uv_offset.x , uv_offset.y + uv_size.y}, color};
+	render_push_tris(_tris, texture_index);
 }
 
 
@@ -208,7 +206,7 @@
 	uint32_t byte_size = width * height * sizeof(rgba_t);
 	uint16_t texture_index = textures_len;
 	
-	textures[texture_index] = (render_texture_t){{width, height}, NULL};
+	textures[texture_index] = (render_texture_t){(vec2i_t){width, height}, NULL};
 	// textures[texture_index] = (render_texture_t){{width, height}, mem_bump(byte_size)};
 	// memcpy(textures[texture_index].pixels, pixels, byte_size);
 
@@ -242,11 +240,28 @@
 
 // -----------------------------------------------------------------------------
 
+
+#define lerp(a, b, t) ({ \
+		__typeof__(a) _a = a; \
+		_a + ((b) - _a) * (t); \
+	})
+
 static inline rgba_t color_mix(rgba_t in, rgba_t out) {
+	uint8_t _a, _za, _zb, _zc;
+ 
+	_a = in.as_rgba.r;
+	_za = _a + ((out.as_rgba.r) - _a) * (out.as_rgba.a/255.0);
+
+	_a = in.as_rgba.g;
+	_zb = _a + ((out.as_rgba.g) - _a) * (out.as_rgba.a/255.0);
+
+	_a = in.as_rgba.b;
+	_zc = _a + ((out.as_rgba.b) - _a) * (out.as_rgba.a/255.0);
+
 	return rgba(
-		lerp(in.as_rgba.r, out.as_rgba.r, out.as_rgba.a/255.0),
-		lerp(in.as_rgba.g, out.as_rgba.g, out.as_rgba.a/255.0),
-		lerp(in.as_rgba.b, out.as_rgba.b, out.as_rgba.a/255.0),
+		_za,
+		_zb,
+		_zc,
 		1
 	);
 }
@@ -331,13 +346,24 @@
 	// Bresenham's line algorithm
 	bool steep = false; 
 	if (abs(p0.x - p1.x) < abs(p0.y - p1.y)) {
-		swap(p0.x, p0.y); 
-		swap(p1.x, p1.y); 
+		int32_t tmp = p0.x;
+		p0.x = p0.y;
+		p0.y = tmp;
+
+		tmp = p1.x;
+		p1.x = p1.y;
+		p1.y = tmp;
 		steep = true;
 	} 
 	if (p0.x > p1.x) { 
-		swap(p0.x, p1.x); 
-		swap(p0.y, p1.y); 
+
+		int32_t tmp = p0.x;
+		p0.x = p1.x;
+		p1.x = tmp;
+
+		tmp = p0.y;
+		p0.y = p1.y;
+		p1.y = tmp; 
 	} 
 	int32_t dx = p1.x - p0.x; 
 	int32_t dy = p1.y - p0.y; 
--- a/src/system.h
+++ b/src/system.h
@@ -7,17 +7,17 @@
 #define SYSTEM_WINDOW_WIDTH 1280
 #define SYSTEM_WINDOW_HEIGHT 720
 
-void system_init();
-void system_update();
-void system_cleanup();
-void system_exit();
+void system_init(void);
+void system_update(void);
+void system_cleanup(void);
+void system_exit(void);
 void system_resize(vec2i_t size);
 
-double system_time();
-double system_tick();
-double system_cycle_time();
-void system_reset_cycle_time();
-double system_time_scale_get();
+double system_time(void);
+double system_tick(void);
+double system_cycle_time(void);
+void system_reset_cycle_time(void);
+double system_time_scale_get(void);
 void system_time_scale_set(double ts);
 
 #endif
--- a/src/types.c
+++ b/src/types.c
@@ -14,7 +14,12 @@
 	float cosine = (magnitude == 0)
 		? 1
 		: vec3_dot(a, b) / magnitude;
-	return acos(clamp(cosine, -1, 1));
+
+	float _v = cosine;
+	float _min = -1;
+	float _max = 1;
+	
+	return acos(_v > _max ? _max : _v < _min ? _min : _v);
 }
 
 vec3_t vec3_transform(vec3_t a, mat4_t *mat) {
--- a/src/types.h
+++ b/src/types.h
@@ -45,13 +45,65 @@
 } tris_t;
 
 
-#define rgba(R, G, B, A) ((rgba_t){.as_rgba = {.r = R, .g = G, .b = B, .a = A}})
-#define vec2(X, Y) ((vec2_t){.x = X, .y = Y})
-#define vec3(X, Y, Z) ((vec3_t){.x = X, .y = Y, .z = Z})
-#define vec2i(X, Y) ((vec2i_t){.x = X, .y = Y})
+#define vec2(X, Y) ((vec2_t){X, Y})
+#define vec3(X, Y, Z) ((vec3_t){X, Y, Z})
+#define vec2i(X, Y) ((vec2i_t){X, Y})
 
+#ifdef __plan9__
+
+static rgba_t
+rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
+{
+	rgba_t x;
+
+	x.as_rgba.r = r;
+	x.as_rgba.g = g;
+	x.as_rgba.b = b;
+	x.as_rgba.a = a;
+	return x;
+}
+
+static mat4_t
+mat4(float m0,float m1,float m2,float m3,float m4,float m5,float m6,float m7,float m8,float m9,float m10,float m11,float m12,float m13,float m14, float m15)
+{
+	mat4_t r;
+
+	r.m[0] = m0;
+	r.m[1] = m1;
+	r.m[2] = m2;
+	r.m[3] = m3;
+	r.m[4] = m4;
+	r.m[5] = m5;
+	r.m[6] = m6;
+	r.m[7] = m7;
+	r.m[8] = m8;
+	r.m[9] = m9;
+	r.m[10] = m10;
+	r.m[11] = m11;
+	r.m[12] = m12;
+	r.m[13] = m13;
+	r.m[14] = m14;
+	r.m[15] = m15;
+	return r;
+}
+
+static mat4_t
+mat4_identity(void)
+{
+	return mat4(
+		1, 0, 0, 0,
+		0, 1, 0, 0,
+		0, 0, 1, 0,
+		0, 0, 0, 1
+	);
+}
+
+#else
+
+#define rgba(R, G, B, A) ((rgba_t){{R, G, B, A}})
+
 #define mat4(m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15) \
-	(mat4_t){.m = { \
+	(mat4_t){{ \
 		m0,   m1,  m2,  m3, \
 		m4,   m5,  m6,  m7, \
 		m8,   m9, m10, m11, \
@@ -64,6 +116,8 @@
 		0, 0, 1, 0, \
 		0, 0, 0, 1 \
 	)
+
+#endif
 
 static inline vec2_t vec2_mulf(vec2_t a, float f) {
 	return vec2(
--- a/src/utils.h
+++ b/src/utils.h
@@ -10,6 +10,22 @@
 #endif
 #define member_size(type, member) sizeof(((type *)0)->member)
 
+#ifdef __plan9__
+
+static int
+max(int a, int b)
+{
+	return a > b ? a : b;
+}
+
+static int
+min(int a, int b)
+{
+	return a < b ? a : b;
+}
+
+#else
+
 #define max(a,b) ({ \
 		__typeof__ (a) _a = (a); \
 		__typeof__ (b) _b = (b); \
@@ -39,6 +55,8 @@
 		_a + ((b) - _a) * (t); \
 	})
 
+#endif
+
 #define len(A) (sizeof(A) / sizeof(A[0]))
 #define clear(A) memset(A, 0, sizeof(A))
 
@@ -75,7 +93,10 @@
 uint8_t *file_load(char *path, uint32_t *bytes_read);
 uint32_t file_store(char *path, void *bytes, int32_t len);
 
+#ifdef __plan9__
 
+#else
+
 #define sort(LIST, LEN, COMPARE_FUNC) \
 	for (uint32_t sort_i = 1, sort_j; sort_i < (LEN); sort_i++) { \
 		sort_j = sort_i; \
@@ -92,6 +113,8 @@
 		int j = rand_int(0, i+1); \
 		swap((LIST)[i], (LIST)[j]); \
 	}
+
+#endif
 
 
 static inline uint8_t get_u8(uint8_t *bytes, uint32_t *p) {
--- a/src/wipeout/droid.h
+++ b/src/wipeout/droid.h
@@ -29,7 +29,7 @@
 
 void droid_draw(droid_t *droid);
 
-void droid_load();
+void droid_load(void);
 void droid_init(droid_t *droid, ship_t *ship);
 void droid_update(droid_t *droid, ship_t *ship);
 void droid_update_intro(droid_t *droid, ship_t *ship);
--- a/src/wipeout/game.c
+++ b/src/wipeout/game.c
@@ -487,8 +487,8 @@
 
 
 struct {
-	void (*init)();
-	void (*update)();
+	void (*init)(void);
+	void (*update)(void);
 } game_scenes[] = {
 	[GAME_SCENE_INTRO] = {intro_init, intro_update},
 	[GAME_SCENE_TITLE] = {title_init, title_update},
--- a/src/wipeout/game.h
+++ b/src/wipeout/game.h
@@ -262,9 +262,9 @@
 extern game_t g;
 extern save_t save;
 
-void game_init();
+void game_init(void);
 void game_set_scene(game_scene_t scene);
-void game_reset_championship();
-void game_update();
+void game_reset_championship(void);
+void game_update(void);
 
 #endif
--- a/src/wipeout/hud.c
+++ b/src/wipeout/hud.c
@@ -31,22 +31,26 @@
 } speedo = {
 	.width = 121,
 	.skew = 2,
-	.bars = {
-		{{.x =   6, .y = 12}, .height = 10, .color = rgba( 66,  16,  49, 255)},
-		{{.x =  13, .y = 12}, .height = 10, .color = rgba(115,  33,  90, 255)},
-		{{.x =  20, .y = 12}, .height = 10, .color = rgba(132,  58, 164, 255)},
-		{{.x =  27, .y = 12}, .height = 10, .color = rgba( 99,  90, 197, 255)},
-		{{.x =  34, .y = 12}, .height = 10, .color = rgba( 74, 148, 181, 255)},
-		{{.x =  41, .y = 12}, .height = 10, .color = rgba( 66, 173, 115, 255)},
-		{{.x =  50, .y = 10}, .height = 12, .color = rgba( 99, 206,  58, 255)},
-		{{.x =  59, .y =  8}, .height = 12, .color = rgba(189, 206,  41, 255)},
-		{{.x =  69, .y =  5}, .height = 13, .color = rgba(247, 140,  33, 255)},
-		{{.x =  81, .y =  2}, .height = 15, .color = rgba(255, 197,  49, 255)},
-		{{.x =  95, .y =  1}, .height = 16, .color = rgba(255, 222, 115, 255)},
-		{{.x = 110, .y =  1}, .height = 16, .color = rgba(255, 239, 181, 255)},
-		{{.x = 126, .y =  1}, .height = 16, .color = rgba(255, 255, 255, 255)}
-	}
 };
+
+static void
+initspeedo(void)
+{
+	speedo.bars[0] = (speedo_bar_t){(vec2i_t){6, 12}, 10, rgba( 66,  16,  49, 255)};
+	speedo.bars[1] = (speedo_bar_t){(vec2i_t){13, 12}, 10, rgba(115,  33,  90, 255)};
+	speedo.bars[2] = (speedo_bar_t){(vec2i_t){20, 12}, 10, rgba(132,  58, 164, 255)};
+	speedo.bars[3] = (speedo_bar_t){(vec2i_t){27, 12}, 10, rgba( 99,  90, 197, 255)};
+	speedo.bars[4] = (speedo_bar_t){(vec2i_t){34, 12}, 10, rgba( 74, 148, 181, 255)};
+	speedo.bars[5] = (speedo_bar_t){(vec2i_t){41, 12}, 10, rgba( 66, 173, 115, 255)};
+	speedo.bars[6] = (speedo_bar_t){(vec2i_t){50, 10}, 12, rgba( 99, 206,  58, 255)};
+	speedo.bars[7] = (speedo_bar_t){(vec2i_t){59, 8}, 12, rgba(189, 206,  41, 255)};
+	speedo.bars[8] = (speedo_bar_t){(vec2i_t){ 69, 5}, 13, rgba(247, 140,  33, 255)};
+	speedo.bars[9] = (speedo_bar_t){(vec2i_t){81, 2}, 15, rgba(255, 197,  49, 255)};
+	speedo.bars[10] = (speedo_bar_t){(vec2i_t){95, 1}, 16, rgba(255, 222, 115, 255)};
+	speedo.bars[11] = (speedo_bar_t){(vec2i_t){110, 1}, 16, rgba(255, 239, 181, 255)};
+	speedo.bars[12] = (speedo_bar_t){(vec2i_t){126, 1}, 16, rgba(255, 255, 255, 255)};
+}
+
 
 static uint16_t speedo_facia_texture;
 
@@ -58,6 +62,7 @@
 
 static void hud_draw_speedo_bar(vec2i_t *pos, const speedo_bar_t *a, const speedo_bar_t *b, float f, rgba_t color_override) {
 	rgba_t left_color, right_color;
+	tris_t _tris;
 	if (color_override.as_uint32 > 0) {
 		left_color = color_override;
 		right_color = color_override;
@@ -64,19 +69,50 @@
 	}
 	else {
 		left_color = a->color;
+		float _za, _zb, _zc, _zd;
+		uint8_t _a;
+		_a = a->color.as_rgba.r;
+		_za = _a + (b->color.as_rgba.r - _a) * f;
+
+		_a = a->color.as_rgba.g;
+		_zb = _a + (b->color.as_rgba.g - _a) * f;
+
+		_a = a->color.as_rgba.b;
+		_zc = _a + (b->color.as_rgba.b - _a) * f;
+
+		_a = a->color.as_rgba.a;
+		_zd = _a + (b->color.as_rgba.a - _a) * f;
 		right_color = rgba(
-			lerp(a->color.as_rgba.r, b->color.as_rgba.r, f),
-			lerp(a->color.as_rgba.g, b->color.as_rgba.g, f),
-			lerp(a->color.as_rgba.b, b->color.as_rgba.b, f),
-			lerp(a->color.as_rgba.a, b->color.as_rgba.a, f)
+			_za,
+			_zb,
+			_zc,
+			_zd
 		);
 	}
 
-	float right_h = lerp(a->height, b->height, f);
+	float right_h;
+	{
+		uint16_t _a;
+		float _za;
+		_a = a->height;
+		_za = _a + (b->height - _a) * f;
+		right_h = _za;
+	}
+
 	vec2i_t top_left     = vec2i(a->offset.x + 1, a->offset.y);
 	vec2i_t bottom_left  = vec2i(a->offset.x + 1 - a->height / speedo.skew, a->offset.y + a->height);
-	vec2i_t top_right    = vec2i(lerp(a->offset.x + 1, b->offset.x, f), lerp(a->offset.y, b->offset.y, f));
-	vec2i_t bottom_right = vec2i(top_right.x - right_h / speedo.skew, top_right.y + right_h);
+	vec2i_t top_right, bottom_right;
+	{
+		uint32_t _a;
+		float _za, _zb;
+		_a = a->offset.x + 1;
+		_za = _a + (b->offset.x - _a) * f;
+
+		_a = a->offset.y;
+		_zb = _a + (b->offset.y - _a) * f;
+		top_right    = vec2i(_za, _zb);
+		bottom_right = vec2i(top_right.x - right_h / speedo.skew, top_right.y + right_h);
+	}
 
 	top_left     = ui_scaled(top_left);
 	bottom_left  = ui_scaled(bottom_left);
@@ -83,48 +119,43 @@
 	top_right    = ui_scaled(top_right);
 	bottom_right = ui_scaled(bottom_right);
 
-	render_push_tris((tris_t) {
-		.vertices = {
-			{
-				.pos = {pos->x + bottom_left.x, pos->y + bottom_left.y, 0},
-				.uv = {0, 0},
-				.color = left_color
-			},
-			{
-				.pos = {pos->x + top_right.x, pos->y + top_right.y, 0},
-				.uv = {0, 0},
-				.color = right_color
-			},
-			{
-				.pos = {pos->x + top_left.x, pos->y + top_left.y, 0},
-				.uv = {0, 0},
-				.color = left_color
-			},
-		}
-	}, RENDER_NO_TEXTURE);
+	_tris.vertices[0] = (vertex_t) {
+		(vec3_t){pos->x + bottom_left.x, pos->y + bottom_left.y, 0},
+		(vec2_t){0, 0},
+		left_color,
+	};
+	_tris.vertices[1] = (vertex_t) {
+		(vec3_t){pos->x + top_right.x, pos->y + top_right.y, 0},
+		(vec2_t){0, 0},
+		right_color,
+	};
+	_tris.vertices[2] = (vertex_t) {
+		(vec3_t){pos->x + top_left.x, pos->y + top_left.y, 0},
+		(vec2_t){0, 0},
+		left_color,
+	};
+	render_push_tris(_tris, RENDER_NO_TEXTURE);
 
-	render_push_tris((tris_t) {
-		.vertices = {
-			{
-				.pos = {pos->x + bottom_right.x, pos->y + bottom_right.y, 0},
-				.uv = {0, 0},
-				.color = right_color
-			},
-			{
-				.pos = {pos->x + top_right.x, pos->y + top_right.y, 0},
-				.uv = {0, 0},
-				.color = right_color
-			},
-			{
-				.pos = {pos->x + bottom_left.x, pos->y + bottom_left.y, 0},
-				.uv = {0, 0},
-				.color = left_color
-			},
-		}
-	}, RENDER_NO_TEXTURE);
+	_tris.vertices[0] = (vertex_t) {
+		(vec3_t){pos->x + bottom_right.x, pos->y + bottom_right.y, 0},
+		(vec2_t){0, 0},
+		right_color
+	};
+	_tris.vertices[1] = (vertex_t) {
+		(vec3_t){pos->x + top_right.x, pos->y + top_right.y, 0},
+		(vec2_t){0, 0},
+		right_color
+	};
+	_tris.vertices[2] = (vertex_t) {
+		(vec3_t){pos->x + bottom_left.x, pos->y + bottom_left.y, 0},
+		(vec2_t){0, 0},
+		left_color
+	};
+	render_push_tris(_tris, RENDER_NO_TEXTURE);
 }
 
 static void hud_draw_speedo_bars(vec2i_t *pos, float f, rgba_t color_override) {
+	static int donespeedoinit = 0;
 	if (f <= 0) {
 		return;
 	}
@@ -136,6 +167,10 @@
 		f = 13;
 	}
 
+	if(!donespeedoinit){
+		initspeedo();
+		donespeedoinit = 1;
+	}
 	int bars = f;
 	for (int i = 1; i < bars; i++) {
 		hud_draw_speedo_bar(pos, &speedo.bars[i - 1], &speedo.bars[i], 1, color_override);
--- a/src/wipeout/hud.h
+++ b/src/wipeout/hud.h
@@ -3,7 +3,7 @@
 
 #include "ship.h"
 
-void hud_load();
+void hud_load(void);
 void hud_draw(ship_t *ship);
 
-#endif
\ No newline at end of file
+#endif
--- a/src/wipeout/image.h
+++ b/src/wipeout/image.h
@@ -31,4 +31,4 @@
 texture_list_t image_get_compressed_textures(char *name);
 uint16_t texture_from_list(texture_list_t tl, uint16_t index);
 
-#endif
\ No newline at end of file
+#endif
--- a/src/wipeout/ingame_menus.h
+++ b/src/wipeout/ingame_menus.h
@@ -3,11 +3,11 @@
 
 #include "menu.h"
 
-void ingame_menus_load();
+void ingame_menus_load(void);
 
-menu_t *pause_menu_init();
-menu_t *game_over_menu_init();
-menu_t *race_stats_menu_init();
+menu_t *pause_menu_init(void);
+menu_t *game_over_menu_init(void);
+menu_t *race_stats_menu_init(void);
 menu_t *text_scroll_menu_init(char * const *lines, int len);
 
 #endif
--- a/src/wipeout/intro.c
+++ b/src/wipeout/intro.c
@@ -33,7 +33,7 @@
 static void video_cb(plm_t *plm, plm_frame_t *frame, void *user);
 static void audio_cb(plm_t *plm, plm_samples_t *samples, void *user);
 static void audio_mix(float *samples, uint32_t len);
-static void intro_end();
+static void intro_end(void);
 
 void intro_init() {
 	plm = plm_create_with_filename("wipeout/intro.mpeg");
@@ -62,12 +62,12 @@
 	audio_buffer_write_pos = 0;
 }
 
-static void intro_end() {
+static void intro_end(void) {
 	sfx_set_external_mix_cb(NULL);
 	game_set_scene(GAME_SCENE_TITLE);
 }
 
-void intro_update() {
+void intro_update(void) {
 	if (!plm) {
 		return;
 	}
--- a/src/wipeout/intro.h
+++ b/src/wipeout/intro.h
@@ -5,4 +5,4 @@
 void intro_update();
 void intro_cleanup();
 
-#endif
\ No newline at end of file
+#endif
--- a/src/wipeout/main_menu.c
+++ b/src/wipeout/main_menu.c
@@ -134,7 +134,7 @@
 // -----------------------------------------------------------------------------
 // Options Controls
 
-static const char *button_names[NUM_GAME_ACTIONS][2] = {};
+static const char *button_names[NUM_GAME_ACTIONS][2];
 static int control_current_action;
 static float await_input_deadline;
 
@@ -169,7 +169,11 @@
 	float remaining = await_input_deadline - platform_now();
 
 	menu_page_t *page = &menu->pages[menu->index];
-	char remaining_text[2] = { '0' + (uint8_t)clamp(remaining + 1, 0, 3), '\0'};
+	float _v = remaining+1;
+	float _min = 0;
+	float _max = 3;
+	
+	char remaining_text[2] = { '0' + (uint8_t)(_v > _max ? _max : _v < _min ? _min : _v), '\0'};
 	vec2i_t pos = vec2i(page->items_pos.x, page->items_pos.y + 24);
 	ui_draw_text_centered(remaining_text, ui_scaled_pos(page->items_anchor, pos), UI_SIZE_16, UI_COLOR_DEFAULT);
 
--- a/src/wipeout/menu.c
+++ b/src/wipeout/menu.c
@@ -7,7 +7,7 @@
 #include "ui.h"
 #include "sfx.h"
 
-bool blink() {
+bool blink(void) {
 	// blink 30 times per second
 	return fmod(system_cycle_time(), 1.0/15.0) < 1.0/30.0;
 }
--- a/src/wipeout/object.c
+++ b/src/wipeout/object.c
@@ -452,6 +452,7 @@
 
 void object_draw(Object *object, mat4_t *mat) {
 	vec3_t *vertex = object->vertices;
+	tris_t _tris;
 
 	Prm poly = {.primitive = object->primitives};
 	int primitives_len = object->primitives_len;
@@ -470,27 +471,24 @@
 			coord0 = poly.gt3->coords[0];
 			coord1 = poly.gt3->coords[1];
 			coord2 = poly.gt3->coords[2];
+
+			_tris.vertices[0] = (vertex_t){
+				vertex[coord2],
+				(vec2_t){poly.gt3->u2, poly.gt3->v2},
+				poly.gt3->colour[2]
+			};
+			_tris.vertices[1] = (vertex_t){
+				vertex[coord1],
+				(vec2_t){poly.gt3->u1, poly.gt3->v1},
+				poly.gt3->colour[1]
+			};
+			_tris.vertices[2] =  (vertex_t){
+				vertex[coord0],
+				(vec2_t){poly.gt3->u0, poly.gt3->v0},
+				poly.gt3->colour[0]
+			};
+			render_push_tris(_tris, poly.gt3->texture);
 
-			render_push_tris((tris_t) {
-				.vertices = {
-					{
-						.pos = vertex[coord2],
-						.uv = {poly.gt3->u2, poly.gt3->v2},
-						.color = poly.gt3->colour[2]
-					},
-					{
-						.pos = vertex[coord1],
-						.uv = {poly.gt3->u1, poly.gt3->v1},
-						.color = poly.gt3->colour[1]
-					},
-					{
-						.pos = vertex[coord0],
-						.uv = {poly.gt3->u0, poly.gt3->v0},
-						.color = poly.gt3->colour[0]
-					},
-				}
-			}, poly.gt3->texture);
-
 			poly.gt3 += 1;
 			break;
 
@@ -500,44 +498,40 @@
 			coord2 = poly.gt4->coords[2];
 			coord3 = poly.gt4->coords[3];
 
-			render_push_tris((tris_t) {
-				.vertices = {
-					{
-						.pos = vertex[coord2],
-						.uv = {poly.gt4->u2, poly.gt4->v2},
-						.color = poly.gt4->colour[2]
-					},
-					{
-						.pos = vertex[coord1],
-						.uv = {poly.gt4->u1, poly.gt4->v1},
-						.color = poly.gt4->colour[1]
-					},
-					{
-						.pos = vertex[coord0],
-						.uv = {poly.gt4->u0, poly.gt4->v0},
-						.color = poly.gt4->colour[0]
-					},
-				}
-			}, poly.gt4->texture);
-			render_push_tris((tris_t) {
-				.vertices = {
-					{
-						.pos = vertex[coord2],
-						.uv = {poly.gt4->u2, poly.gt4->v2},
-						.color = poly.gt4->colour[2]
-					},
-					{
-						.pos = vertex[coord3],
-						.uv = {poly.gt4->u3, poly.gt4->v3},
-						.color = poly.gt4->colour[3]
-					},
-					{
-						.pos = vertex[coord1],
-						.uv = {poly.gt4->u1, poly.gt4->v1},
-						.color = poly.gt4->colour[1]
-					},
-				}
-			}, poly.gt4->texture);
+			_tris.vertices[0] = (vertex_t) {
+				vertex[coord2],
+				(vec2_t) {poly.gt4->u2, poly.gt4->v2},
+				poly.gt4->colour[2]
+			};
+			_tris.vertices[1] = (vertex_t) {
+				vertex[coord1],
+				(vec2_t) {poly.gt4->u1, poly.gt4->v1},
+				poly.gt4->colour[1]
+			};
+			_tris.vertices[2] = (vertex_t) {
+				vertex[coord0],
+				(vec2_t) {poly.gt4->u0, poly.gt4->v0},
+				poly.gt4->colour[0]
+			};
+			render_push_tris(_tris, poly.gt4->texture);
+
+			_tris.vertices[0] = (vertex_t) {
+				vertex[coord2],
+				(vec2_t){poly.gt4->u2, poly.gt4->v2},
+				poly.gt4->colour[2]
+			};
+			_tris.vertices[1] = (vertex_t) {
+				vertex[coord3],
+				(vec2_t){poly.gt4->u3, poly.gt4->v3},
+				poly.gt4->colour[3]
+			};
+			_tris.vertices[2] = (vertex_t) {
+				vertex[coord1],
+				(vec2_t){poly.gt4->u1, poly.gt4->v1},
+				poly.gt4->colour[1]
+			};
+			
+			render_push_tris(_tris, poly.gt4->texture);
 
 			poly.gt4 += 1;
 			break;
@@ -547,25 +541,22 @@
 			coord1 = poly.ft3->coords[1];
 			coord2 = poly.ft3->coords[2];
 
-			render_push_tris((tris_t) {
-				.vertices = {
-					{
-						.pos = vertex[coord2],
-						.uv = {poly.ft3->u2, poly.ft3->v2},
-						.color = poly.ft3->colour
-					},
-					{
-						.pos = vertex[coord1],
-						.uv = {poly.ft3->u1, poly.ft3->v1},
-						.color = poly.ft3->colour
-					},
-					{
-						.pos = vertex[coord0],
-						.uv = {poly.ft3->u0, poly.ft3->v0},
-						.color = poly.ft3->colour
-					},
-				}
-			}, poly.ft3->texture);
+			_tris.vertices[0] = (vertex_t) {
+				vertex[coord2],
+				(vec2_t){poly.ft3->u2, poly.ft3->v2},
+				poly.ft3->colour
+			};
+			_tris.vertices[1] = (vertex_t) {
+				vertex[coord1],
+				(vec2_t){poly.ft3->u1, poly.ft3->v1},
+				poly.ft3->colour
+			};
+			_tris.vertices[2] = (vertex_t) {
+				vertex[coord0],
+				(vec2_t){poly.ft3->u0, poly.ft3->v0},
+				poly.ft3->colour
+			};
+			render_push_tris(_tris, poly.ft3->texture);
 
 			poly.ft3 += 1;
 			break;
@@ -576,44 +567,39 @@
 			coord2 = poly.ft4->coords[2];
 			coord3 = poly.ft4->coords[3];
 
-			render_push_tris((tris_t) {
-				.vertices = {
-					{
-						.pos = vertex[coord2],
-						.uv = {poly.ft4->u2, poly.ft4->v2},
-						.color = poly.ft4->colour
-					},
-					{
-						.pos = vertex[coord1],
-						.uv = {poly.ft4->u1, poly.ft4->v1},
-						.color = poly.ft4->colour
-					},
-					{
-						.pos = vertex[coord0],
-						.uv = {poly.ft4->u0, poly.ft4->v0},
-						.color = poly.ft4->colour
-					},
-				}
-			}, poly.ft4->texture);
-			render_push_tris((tris_t) {
-				.vertices = {
-					{
-						.pos = vertex[coord2],
-						.uv = {poly.ft4->u2, poly.ft4->v2},
-						.color = poly.ft4->colour
-					},
-					{
-						.pos = vertex[coord3],
-						.uv = {poly.ft4->u3, poly.ft4->v3},
-						.color = poly.ft4->colour
-					},
-					{
-						.pos = vertex[coord1],
-						.uv = {poly.ft4->u1, poly.ft4->v1},
-						.color = poly.ft4->colour
-					},
-				}
-			}, poly.ft4->texture);
+			_tris.vertices[0] = (vertex_t) {
+				vertex[coord2],
+				(vec2_t){poly.ft4->u2, poly.ft4->v2},
+				poly.ft4->colour
+			};
+			_tris.vertices[1] = (vertex_t) {
+				vertex[coord1],
+				(vec2_t){poly.ft4->u1, poly.ft4->v1},
+				poly.ft4->colour
+			};
+			_tris.vertices[2] = (vertex_t) {
+				vertex[coord0],
+				(vec2_t){poly.ft4->u0, poly.ft4->v0},
+				poly.ft4->colour
+			};
+			render_push_tris(_tris, poly.ft4->texture);
+
+			_tris.vertices[0] = (vertex_t) {
+				vertex[coord2],
+				(vec2_t){poly.ft4->u2, poly.ft4->v2},
+				poly.ft4->colour
+			};
+			_tris.vertices[1] = (vertex_t) {
+				vertex[coord3],
+				(vec2_t){poly.ft4->u3, poly.ft4->v3},
+				poly.ft4->colour
+			};
+			_tris.vertices[2] = (vertex_t) {
+				vertex[coord1],
+				(vec2_t){poly.ft4->u1, poly.ft4->v1},
+				poly.ft4->colour
+			};
+			render_push_tris(_tris, poly.ft4->texture);
 
 			poly.ft4 += 1;
 			break;
@@ -623,22 +609,22 @@
 			coord1 = poly.g3->coords[1];
 			coord2 = poly.g3->coords[2];
 
-			render_push_tris((tris_t) {
-				.vertices = {
-					{
-						.pos = vertex[coord2],
-						.color = poly.g3->colour[2]
-					},
-					{
-						.pos = vertex[coord1],
-						.color = poly.g3->colour[1]
-					},
-					{
-						.pos = vertex[coord0],
-						.color = poly.g3->colour[0]
-					},
-				}
-			}, RENDER_NO_TEXTURE);
+			_tris.vertices[0] = (vertex_t) {
+				vertex[coord2],
+				(vec2_t){0, 0},
+				poly.g3->colour[2]
+			};
+			_tris.vertices[1] = (vertex_t) {
+				vertex[coord1],
+				(vec2_t){0, 0},
+				poly.g3->colour[1]
+			};
+			_tris.vertices[2] = (vertex_t) {
+				vertex[coord0],
+				(vec2_t){0, 0},
+				poly.g3->colour[0]
+			};
+			render_push_tris(_tris, RENDER_NO_TEXTURE);
 
 			poly.g3 += 1;
 			break;
@@ -649,38 +635,39 @@
 			coord2 = poly.g4->coords[2];
 			coord3 = poly.g4->coords[3];
 
-			render_push_tris((tris_t) {
-				.vertices = {
-					{
-						.pos = vertex[coord2],
-						.color = poly.g4->colour[2]
-					},
-					{
-						.pos = vertex[coord1],
-						.color = poly.g4->colour[1]
-					},
-					{
-						.pos = vertex[coord0],
-						.color = poly.g4->colour[0]
-					},
-				}
-			}, RENDER_NO_TEXTURE);
-			render_push_tris((tris_t) {
-				.vertices = {
-					{
-						.pos = vertex[coord2],
-						.color = poly.g4->colour[2]
-					},
-					{
-						.pos = vertex[coord3],
-						.color = poly.g4->colour[3]
-					},
-					{
-						.pos = vertex[coord1],
-						.color = poly.g4->colour[1]
-					},
-				}
-			}, RENDER_NO_TEXTURE);
+			_tris.vertices[0] = (vertex_t) {
+				vertex[coord2],
+				(vec2_t){0, 0},
+				poly.g4->colour[2]
+			};
+			_tris.vertices[1] = (vertex_t) {
+				vertex[coord1],
+				(vec2_t){0, 0},
+				poly.g4->colour[1]
+			};
+			_tris.vertices[2] = (vertex_t) {
+				vertex[coord0],
+				(vec2_t){0, 0},
+				poly.g4->colour[0]
+			};
+			render_push_tris(_tris, RENDER_NO_TEXTURE);
+
+			_tris.vertices[0] = (vertex_t) {
+				vertex[coord2],
+				(vec2_t){0, 0},
+				poly.g4->colour[2]
+			};
+			_tris.vertices[1] = (vertex_t) {
+				vertex[coord3],
+				(vec2_t){0, 0},
+				poly.g4->colour[3]
+			};
+			_tris.vertices[2] = (vertex_t) {
+				vertex[coord1],
+				(vec2_t){0, 0},
+				poly.g4->colour[1]
+			};
+			render_push_tris(_tris, RENDER_NO_TEXTURE);
 
 			poly.g4 += 1;
 			break;
@@ -690,22 +677,22 @@
 			coord1 = poly.f3->coords[1];
 			coord2 = poly.f3->coords[2];
 
-			render_push_tris((tris_t) {
-				.vertices = {
-					{
-						.pos = vertex[coord2],
-						.color = poly.f3->colour
-					},
-					{
-						.pos = vertex[coord1],
-						.color = poly.f3->colour
-					},
-					{
-						.pos = vertex[coord0],
-						.color = poly.f3->colour
-					},
-				}
-			}, RENDER_NO_TEXTURE);
+			_tris.vertices[0] = (vertex_t) {
+				vertex[coord2],
+				(vec2_t){0, 0},
+				poly.f3->colour
+			};
+			_tris.vertices[1] = (vertex_t) {
+				vertex[coord1],
+				(vec2_t){0, 0},
+				poly.f3->colour
+			};
+			_tris.vertices[2] = (vertex_t) {
+				vertex[coord0],
+				(vec2_t){0, 0},
+				poly.f3->colour
+			};
+			render_push_tris(_tris, RENDER_NO_TEXTURE);
 
 			poly.f3 += 1;
 			break;
@@ -716,38 +703,39 @@
 			coord2 = poly.f4->coords[2];
 			coord3 = poly.f4->coords[3];
 
-			render_push_tris((tris_t) {
-				.vertices = {
-					{
-						.pos = vertex[coord2],
-						.color = poly.f4->colour
-					},
-					{
-						.pos = vertex[coord1],
-						.color = poly.f4->colour
-					},
-					{
-						.pos = vertex[coord0],
-						.color = poly.f4->colour
-					},
-				}
-			}, RENDER_NO_TEXTURE);
-			render_push_tris((tris_t) {
-				.vertices = {
-					{
-						.pos = vertex[coord2],
-						.color = poly.f4->colour
-					},
-					{
-						.pos = vertex[coord3],
-						.color = poly.f4->colour
-					},
-					{
-						.pos = vertex[coord1],
-						.color = poly.f4->colour
-					},
-				}
-			}, RENDER_NO_TEXTURE);
+			_tris.vertices[0] = (vertex_t) {
+				vertex[coord2],
+				(vec2_t){0, 0},
+				poly.f4->colour
+			};
+			_tris.vertices[1] = (vertex_t) {
+				vertex[coord1],
+				(vec2_t){0, 0},
+				poly.f4->colour
+			};
+			_tris.vertices[2] = (vertex_t) {
+				vertex[coord0],
+				(vec2_t){0, 0},
+				poly.f4->colour
+			};
+			render_push_tris(_tris, RENDER_NO_TEXTURE);
+
+			_tris.vertices[0] = (vertex_t) {
+				vertex[coord2],
+				(vec2_t){0, 0},
+				poly.f4->colour
+			};
+			_tris.vertices[1] = (vertex_t) {
+				vertex[coord3],
+				(vec2_t){0, 0},
+				poly.f4->colour
+			};
+			_tris.vertices[2] = (vertex_t) {
+				vertex[coord1],
+				(vec2_t){0, 0},
+				poly.f4->colour
+			};
+			render_push_tris(_tris, RENDER_NO_TEXTURE);
 
 			poly.f4 += 1;
 			break;
--- a/src/wipeout/object.h
+++ b/src/wipeout/object.h
@@ -380,4 +380,4 @@
 Object *objects_load(char *name, texture_list_t tl);
 void object_draw(Object *object, mat4_t *mat);
 
-#endif
\ No newline at end of file
+#endif
--- a/src/wipeout/particle.c
+++ b/src/wipeout/particle.c
@@ -34,11 +34,13 @@
 }
 
 void particles_draw() {
+	mat4_t _mat;
 	if (particles_active == 0) {
 		return;
 	}
 
-	render_set_model_mat(&mat4_identity());
+	_mat = mat4_identity();
+	render_set_model_mat(&_mat);
 	render_set_depth_write(false);
 	render_set_blend_mode(RENDER_BLEND_LIGHTER);
 	render_set_depth_offset(-32.0);
--- a/src/wipeout/particle.h
+++ b/src/wipeout/particle.h
@@ -23,10 +23,10 @@
 	uint16_t texture;
 } particle_t;
 
-void particles_load();
-void particles_init();
+void particles_load(void);
+void particles_init(void);
 void particles_spawn(vec3_t position, uint16_t type, vec3_t velocity, int size);
-void particles_draw();
-void particles_update();
+void particles_draw(void);
+void particles_update(void);
 
-#endif
\ No newline at end of file
+#endif
--- a/src/wipeout/race.c
+++ b/src/wipeout/race.c
@@ -216,7 +216,18 @@
 				}
 			}
 		}
-		sort(g.championship_ranks, len(g.championship_ranks), sort_points_compare);
+
+		for (uint32_t sort_i = 1, sort_j; sort_i < (len(g.championship_ranks)); sort_i++) {
+			sort_j = sort_i;
+			pilot_points_t sort_temp = (g.championship_ranks)[sort_j];
+			while (sort_j > 0 && sort_points_compare(&(g.championship_ranks)[sort_j-1], &sort_temp)) {
+				(g.championship_ranks)[sort_j] = (g.championship_ranks)[sort_j-1];
+				sort_j--;
+			} 
+			(g.championship_ranks)[sort_j] = sort_temp; 
+		}
+
+		//sort(g.championship_ranks, len(g.championship_ranks), sort_points_compare);
 	}
 
 	active_menu = race_stats_menu_init();
--- a/src/wipeout/race.h
+++ b/src/wipeout/race.h
@@ -1,14 +1,14 @@
 #ifndef RACE_H
 #define RACE_H
 
-void race_init();
-void race_update();
-void race_start();
-void race_restart();
-void race_pause();
-void race_unpause();
-void race_end();
-void race_next();
-void race_release_control();
+void race_init(void);
+void race_update(void);
+void race_start(void);
+void race_restart(void);
+void race_pause(void);
+void race_unpause(void);
+void race_end(void);
+void race_next(void);
+void race_release_control(void);
 
 #endif
--- a/src/wipeout/scene.c
+++ b/src/wipeout/scene.c
@@ -47,7 +47,7 @@
 
 void scene_pulsate_red_light(Object *obj);
 void scene_move_oil_pump(Object *obj);
-void scene_update_aurora_borealis();
+void scene_update_aurora_borealis(void);
 
 void scene_load(const char *base_path, float sky_y_offset) {
 	texture_list_t scene_textures = image_get_compressed_textures(get_path(base_path, "scene.cmp"));
@@ -85,7 +85,7 @@
 			str_starts_with(obj->name, "newstad_")
 		) {
 			error_if(stands_len >= SCENE_STANDS_MAX, "SCENE_STANDS_MAX reached");
-			stands[stands_len++] = (scene_stand_t){.sfx = NULL, .pos = obj->origin};
+			stands[stands_len++] = (scene_stand_t){NULL, obj->origin};
 		}
 		obj = obj->next;
 	}
@@ -179,7 +179,10 @@
 
 
 void scene_pulsate_red_light(Object *obj) {
-	uint8_t r = clamp(sin(system_cycle_time() * M_PI * 2) * 128 + 128, 0, 255);
+	float _v = sin(system_cycle_time() * M_PI * 2) * 128 + 128;
+	float _min = 0;
+	float _max = 255;
+	uint8_t r = _v > _max ? _max : _v < _min ? _min : _v;
 	Prm libPoly = {.primitive = obj->primitives};
 
 	for (int v = 0; v < 4; v++) {
@@ -231,7 +234,7 @@
 	}
 }
 
-void scene_update_aurora_borealis() {
+void scene_update_aurora_borealis(void) {
 	float phase = system_time() / 30.0;
 	for (int i = 0; i < 80; i++) {
 		int16_t *coords = aurora_borealis.coords[i];
--- a/src/wipeout/scene.h
+++ b/src/wipeout/scene.h
@@ -6,10 +6,9 @@
 
 void scene_load(const char *path, float sky_y_offset);
 void scene_draw(camera_t *camera);
-void scene_init();
+void scene_init(void);
 void scene_set_start_booms(int num_lights);
-void scene_init_aurora_borealis();
-void scene_update();
-void scene_draw();
+void scene_init_aurora_borealis(void);
+void scene_update(void);
 
 #endif
--- a/src/wipeout/sfx.c
+++ b/src/wipeout/sfx.c
@@ -50,7 +50,7 @@
 static music_decoder_t *music;
 static void (*external_mix_cb)(float *, uint32_t len) = NULL;
 
-void sfx_load() {
+void sfx_load(void) {
 	// Init decode buffer for music
 	uint32_t channels = 2;
 	music = mem_bump(sizeof(music_decoder_t));
@@ -80,8 +80,12 @@
 		uint8_t header = vb[p++];
 		uint8_t flags = vb[p++];
 		uint8_t shift = header & 0x0f;
-		uint8_t predictor = clamp(header >> 4, 0, 4);
 
+		uint8_t _v = header >> 4;
+		uint8_t _min = 0;
+		uint8_t _max = 4;
+		uint8_t predictor = _v > _max ? _max : _v < _min ? _min : _v;
+
 		if (flags_is(flags, VAG_REGION_END)) {
 			mem_bump(sizeof(sfx_data_t));
 			sources[num_sources].samples = &sample_buffer[sample_index];
@@ -103,7 +107,11 @@
 				sample += (history[0] * vag_tab[predictor][0] + history[1] * vag_tab[predictor][1]) >> 14;
 				history[1] = history[0];
 				history[0] = sample;
-				sample_buffer[sample_index++] = clamp(sample, -32768, 32767);
+
+				int32_t _v = sample;
+				int32_t _min = -32768;
+				int32_t _max = 32767;
+				sample_buffer[sample_index++] = _v > _max ? _max : _v < _min ? _min : _v;
 			}
 		}
 
@@ -118,7 +126,7 @@
 	platform_set_audio_mix_cb(sfx_stero_mix);
 }
 
-void sfx_reset() {
+void sfx_reset(void) {
 	for (int i = 0; i < SFX_MAX; i++) {
 		if (flags_is(nodes[i].flags, SFX_LOOP)) {
 			flags_set(nodes[i].flags, SFX_NONE);
@@ -126,7 +134,7 @@
 	}
 }
 
-void sfx_unpause() {
+void sfx_unpause(void) {
 	for (int i = 0; i < SFX_MAX; i++) {
 		if (flags_is(nodes[i].flags, SFX_LOOP_PAUSE)) {
 			flags_rm(nodes[i].flags, SFX_LOOP_PAUSE);
@@ -135,7 +143,7 @@
 	}
 }
 
-void sfx_pause() {
+void sfx_pause(void) {
 	for (int i = 0; i < SFX_MAX; i++) {
 		if (flags_is(nodes[i].flags, SFX_PLAY | SFX_LOOP)) {
 			flags_rm(nodes[i].flags, SFX_PLAY);
@@ -209,12 +217,19 @@
 	return sfx;
 }
 
+
 void sfx_set_position(sfx_t *sfx, vec3_t pos, vec3_t vel, float volume) {
 	vec3_t relative_position = vec3_sub(g.camera.position, pos);
 	vec3_t relative_velocity = vec3_sub(g.camera.real_velocity, vel);
 	float distance = vec3_len(relative_position);
 
-	sfx->volume = clamp(scale(distance, 512, 32768, 1, 0), 0, 1) * volume;
+	float _in_min = 512, _out_min = 1;
+	float _scale = _out_min + ((0) - _out_min) * (((distance) - _in_min) / ((32768) - _in_min));
+
+	float _v = _scale;
+	float _min = 0;
+	float _max = 1;
+	sfx->volume = _v > _max ? _max : _v < _min ? _min : _v;
 	sfx->pan = -sin(atan2(g.camera.position.x - pos.x, g.camera.position.z - pos.z)+g.camera.angle.y);
 
 	// Doppler effect
@@ -227,7 +242,7 @@
 
 // Music
 
-uint32_t sfx_music_decode_frame() {
+uint32_t sfx_music_decode_frame(void) {
 	if (!music->file) {
 		return 0;
 	}
@@ -240,7 +255,7 @@
 	return frame_len;
 }
 
-void sfx_music_rewind() {
+void sfx_music_rewind(void) {
 	fseek(music->file, music->first_frame_pos, SEEK_SET);
 	music->sample_data_len = 0;
 	music->sample_data_pos = 0;
@@ -348,8 +363,14 @@
 
 			sfx_data_t *source = &sources[sfx->source];
 			float sample = (float)source->samples[(int)sfx->position] / 32768.0;
-			left += sample * sfx->current_volume * clamp(1.0 - sfx->current_pan, 0, 1);
-			right += sample * sfx->current_volume * clamp(1.0 + sfx->current_pan, 0, 1);
+
+			float _v = 1.0 - sfx->current_pan;
+			float _min = 0;
+			float _max = 1;
+			left += sample * sfx->current_volume * (_v > _max ? _max : _v < _min ? _min : _v);
+
+			_v = 1.0 + sfx->current_pan;
+			right += sample * sfx->current_volume * (_v > _max ? _max : _v < _min ? _min : _v);
 
 			sfx->position += sfx->pitch;
 			if (sfx->position >= source->len) {
--- a/src/wipeout/sfx.h
+++ b/src/wipeout/sfx.h
@@ -58,12 +58,12 @@
 #define SFX_MAX 64
 #define SFX_MAX_ACTIVE 16
 
-void sfx_load();
+void sfx_load(void);
 void sfx_stero_mix(float *buffer, uint32_t len);
 void sfx_set_external_mix_cb(void (*cb)(float *, uint32_t len));
-void sfx_reset();
-void sfx_pause();
-void sfx_unpause();
+void sfx_reset(void);
+void sfx_pause(void);
+void sfx_unpause(void);
 
 sfx_t *sfx_play(sfx_source_t source_index);
 sfx_t *sfx_play_at(sfx_source_t source_index, vec3_t pos, vec3_t vel, float volume);
@@ -77,9 +77,9 @@
 	SFX_MUSIC_LOOP
 } sfx_music_mode_t;
 
-void sfx_music_next();
+void sfx_music_next(void);
 void sfx_music_play(uint32_t index);
 void sfx_music_mode(sfx_music_mode_t);
-void sfx_music_pause();
+void sfx_music_pause(void);
 
-#endif
\ No newline at end of file
+#endif
--- a/src/wipeout/ship.c
+++ b/src/wipeout/ship.c
@@ -51,7 +51,6 @@
 	}
 }
 
-
 void ships_init(section_t *section) {
 	section_t *start_sections[len(g.ships)];
 
@@ -64,7 +63,12 @@
 
 	// Randomize order for single race or new championship
 	if (g.race_type != RACE_TYPE_CHAMPIONSHIP || g.circut == CIRCUT_ALTIMA_VII) {
-		shuffle(ranks_to_pilots, len(ranks_to_pilots));
+		for (int i = len(ranks_to_pilots) - 1; i > 0; i--) {
+			int j = rand_int(0, i+1);
+			int tmp = (ranks_to_pilots)[i];
+			(ranks_to_pilots)[i] = (ranks_to_pilots)[j];
+			(ranks_to_pilots)[j] = tmp;
+		}
 	}
 
 	// Randomize some tiers in an ongoing championship
@@ -72,15 +76,27 @@
 		// Initialize with current championship order
 		for (int i = 0; i < len(g.ships); i++) {
 			ranks_to_pilots[i] = g.championship_ranks[i].pilot;
-		}		
-		shuffle(ranks_to_pilots, 2); // shuffle 0..1
-		shuffle(ranks_to_pilots + 4, len(ranks_to_pilots)-5); // shuffle 4..len-1
+		}
+		for (int i = 2 - 1; i > 0; i--) {
+			int j = rand_int(0, i+1);
+			int tmp = (ranks_to_pilots)[i];
+			(ranks_to_pilots)[i] = (ranks_to_pilots)[j];
+			(ranks_to_pilots)[j] = tmp;
+		}
+		for (int i = (len(ranks_to_pilots)-5) - 1; i > 0; i--) {
+			int j = rand_int(0, i+1);
+			int tmp = (ranks_to_pilots + 4)[i];
+			(ranks_to_pilots + 4)[i] = (ranks_to_pilots + 4)[j];
+			(ranks_to_pilots + 4)[j] = tmp;
+		}
 	}
 
 	// player is always last
 	for (int i = 0; i < len(ranks_to_pilots)-1; i++) {
 		if (ranks_to_pilots[i] == g.pilot) {
-			swap(ranks_to_pilots[i], ranks_to_pilots[i+1]);
+			int tmp = (ranks_to_pilots)[i];
+			(ranks_to_pilots)[i] = (ranks_to_pilots)[i+1];
+			(ranks_to_pilots)[i+1] = tmp;
 		}
 	}
 
@@ -135,7 +151,15 @@
 		}
 
 		if (flags_is(g.ships[g.pilot].flags, SHIP_RACING)) {
-			sort(g.race_ranks, len(g.race_ranks), sort_rank_compare);
+			for (uint32_t sort_i = 1, sort_j; sort_i < (len(g.race_ranks)); sort_i++) {
+				sort_j = sort_i;
+				pilot_points_t sort_temp = (g.race_ranks)[sort_j];
+				while (sort_j > 0 && sort_rank_compare(&(g.race_ranks)[sort_j-1], &sort_temp)) {
+					(g.race_ranks)[sort_j] = (g.race_ranks)[sort_j-1]; 
+					sort_j--;
+				}
+				(g.race_ranks)[sort_j] = sort_temp;
+			}
 			for (int32_t i = 0; i < len(g.ships); i++) {
 				g.ships[g.race_ranks[i].pilot].position_rank = i + 1;
 			}
@@ -146,6 +170,7 @@
 
 
 void ships_draw() {
+	mat4_t _mat4;
 	// Ship models
 	for (int i = 0; i < len(g.ships); i++) {
 		if (
@@ -160,7 +185,8 @@
 
 
 	// Shadows
-	render_set_model_mat(&mat4_identity());
+	_mat4 = mat4_identity();
+	render_set_model_mat(&_mat4);
 
 	render_set_depth_write(false);
 	render_set_depth_offset(-32.0);
@@ -394,7 +420,8 @@
 	object_draw(self->model, &self->mat);
 }
 
-void ship_draw_shadow(ship_t *self) {	
+void ship_draw_shadow(ship_t *self) {
+	tris_t _tris;
 	track_face_t *face = track_section_get_base_face(self->section);
 
 	vec3_t face_point = face->tris[0].vertices[0].pos;
@@ -407,25 +434,22 @@
 	wngr = vec3_sub(wngr, vec3_mulf(face->normal, vec3_distance_to_plane(wngr, face_point, face->normal)));
 	
 	rgba_t color = rgba(0 , 0 , 0, 128);
-	render_push_tris((tris_t) {
-		.vertices = {
-			{
-				.pos = {wngl.x, wngl.y, wngl.z},
-				.uv = {0, 256},
-				.color = color,
-			},
-			{
-				.pos = {wngr.x, wngr.y, wngr.z},
-				.uv = {128, 256},
-				.color = color
-			},
-			{
-				.pos = {nose.x, nose.y, nose.z},
-				.uv = {64, 0},
-				.color = color
-			},
-		}
-	}, self->shadow_texture);
+	_tris.vertices[0] = (vertex_t) {
+		(vec3_t){wngl.x, wngl.y, wngl.z},
+		(vec2_t){0, 256},
+		color,
+	},
+	_tris.vertices[1] = (vertex_t) {
+		(vec3_t){wngr.x, wngr.y, wngr.z},
+		(vec2_t){128, 256},
+		color
+	},
+	_tris.vertices[2] = (vertex_t) {
+		(vec3_t){nose.x, nose.y, nose.z},
+		(vec2_t){64, 0},
+		color
+	},
+	render_push_tris(_tris, self->shadow_texture);
 }
 
 void ship_update(ship_t *self) {
--- a/src/wipeout/ship.h
+++ b/src/wipeout/ship.h
@@ -146,10 +146,10 @@
 	sfx_t *sfx_shield;
 } ship_t;
 
-void ships_load();
+void ships_load(void);
 void ships_init(section_t *section);
-void ships_draw();
-void ships_update();
+void ships_draw(void);
+void ships_update(void);
 
 void ship_init(ship_t *self, section_t *section, int pilot, int position);
 void ship_init_exhaust_plume(ship_t *self);
@@ -165,4 +165,4 @@
 vec3_t ship_wing_right(ship_t *self);
 
 
-#endif
\ No newline at end of file
+#endif
--- a/src/wipeout/ship_ai.c
+++ b/src/wipeout/ship_ai.c
@@ -533,4 +533,4 @@
 	}
 
 	sfx_set_position(self->sfx_engine_thrust, self->position, self->velocity, 0.5);
-}
\ No newline at end of file
+}
--- a/src/wipeout/ship_player.c
+++ b/src/wipeout/ship_player.c
@@ -28,7 +28,12 @@
 
 void ship_player_update_sfx(ship_t *self) {
 	float speedf = self->speed * 0.000015;
-	self->sfx_engine_intake->volume = clamp(speedf, 0, 0.5);
+
+	float _v = speedf;
+	float _min = 0;
+	float _max = 0.5;
+	
+	self->sfx_engine_intake->volume = _v > _max ? _max : _v < _min ? _min : _v;
 	self->sfx_engine_intake->pitch = 0.5 + speedf * 1.25;
 
 	self->sfx_engine_thrust->volume = 0.05 + 0.025 * (self->thrust_mag / self->thrust_max);
@@ -124,7 +129,10 @@
 		self->thrust_mag -= SHIP_THRUST_RATE * system_tick();
 	}
 
-	self->thrust_mag = clamp(self->thrust_mag, 0, self->thrust_max);
+	float _v = self->thrust_mag;
+	float _min = 0;
+	float _max = self->thrust_max;
+	self->thrust_mag = _v > _max ? _max : _v < _min ? _min : _v;
 
 	// View
 	if (input_pressed(A_CHANGE_VIEW)) {
@@ -229,8 +237,12 @@
 	else {
 		self->thrust_mag -= SHIP_THRUST_FALLOFF * system_tick();
 	}
-	self->thrust_mag = clamp(self->thrust_mag, 0, self->current_thrust_max);
 
+	float _v = self->thrust_mag;
+	float _min = 0;
+	float _max = self->current_thrust_max;
+	self->thrust_mag = _v > _max ? _max : _v < _min ? _min : _v;
+
 	if (flags_is(self->flags, SHIP_ELECTROED) && rand_int(0, 80) == 0) {
 		self->thrust_mag -= self->thrust_mag * 0.25; // FIXME: 60fps
 	}
@@ -242,8 +254,13 @@
 	else if (self->brake_right > 0) {
 		self->brake_right -= SHIP_BRAKE_RATE * system_tick();
 	}
-	self->brake_right = clamp(self->brake_right, 0, 256);
 
+	_v = self->brake_right;
+	_min = 0;
+	_max = 256;
+
+	self->brake_right = _v > _max ? _max : _v < _min ? _min : _v;
+
 	if (input_state(A_BRAKE_LEFT))	{
 		self->brake_left += SHIP_BRAKE_RATE * system_tick();
 	}
@@ -250,8 +267,12 @@
 	else if (self->brake_left > 0) {
 		self->brake_left -= SHIP_BRAKE_RATE * system_tick();
 	}
-	self->brake_left = clamp(self->brake_left, 0, 256);
 
+	_v = self->brake_left;
+	_min = 0;
+	_max = 256;
+	self->brake_left = _v > _max ? _max : _v < _min ? _min : _v;
+
 	// View
 	if (input_pressed(A_CHANGE_VIEW)) {
 		if (flags_not(self->flags, SHIP_VIEW_INTERNAL)) {
@@ -447,7 +468,11 @@
 	}
 
 	self->angular_velocity = vec3_add(self->angular_velocity, vec3_mulf(self->angular_acceleration, system_tick()));
-	self->angular_velocity.y = clamp(self->angular_velocity.y, -self->turn_rate_max, self->turn_rate_max);
+
+	_v = self->angular_velocity.y;
+	_min = -self->turn_rate_max;
+	_max = self->turn_rate_max;
+	self->angular_velocity.y = _v > _max ? _max : _v < _min ? _min : _v;
 	
 	float brake_dir = (self->brake_left - self->brake_right) * (0.125 / 4096.0);
 	self->angle.y += brake_dir * self->speed * 0.000030517578125 * M_PI * 2 * 30 * system_tick();
--- a/src/wipeout/title.h
+++ b/src/wipeout/title.h
@@ -1,8 +1,8 @@
 #ifndef TITLE_H
 #define TITLE_H
 
-void title_init();
-void title_update();
-void title_cleanup();
+void title_init(void);
+void title_update(void);
+void title_cleanup(void);
 
 #endif
--- a/src/wipeout/track.c
+++ b/src/wipeout/track.c
@@ -172,20 +172,13 @@
 		rgba_t color = {.as_uint32 = get_i32_le(bytes, &p) | 0xff000000};
 		const vec2_t *uv = track_uv[flags_is(tf->flags, FACE_FLIP_TEXTURE) ? 1 : 0];
 
-		tf->tris[0] = (tris_t){
-			.vertices = {
-				{.pos = v0, .uv = uv[0], .color = color},
-				{.pos = v1, .uv = uv[1], .color = color},
-				{.pos = v2, .uv = uv[2], .color = color},
-			}
-		};
-		tf->tris[1] = (tris_t){
-			.vertices = {
-				{.pos = v3, .uv = uv[3], .color = color},
-				{.pos = v0, .uv = uv[0], .color = color},
-				{.pos = v2, .uv = uv[2], .color = color},
-			}
-		};
+		tf->tris[0].vertices[0] = (vertex_t){v0, uv[0], color};
+		tf->tris[0].vertices[1] = (vertex_t){v1, uv[1], color};
+		tf->tris[0].vertices[2] = (vertex_t){v2, uv[2], color};
+
+		tf->tris[1].vertices[0] = (vertex_t){v3, uv[3], color};
+		tf->tris[1].vertices[1] = (vertex_t){v0, uv[0], color};
+		tf->tris[1].vertices[2] = (vertex_t){v2, uv[2], color};
 
 		tf++;
 	}
@@ -265,7 +258,9 @@
 }
 
 void track_draw(camera_t *camera) {	
-	render_set_model_mat(&mat4_identity());	
+	mat4_t _mat;
+	_mat = mat4_identity();
+	render_set_model_mat(&_mat);	
 	
 	float max_dist_sq = RENDER_FADEOUT_FAR * RENDER_FADEOUT_FAR;
 	vec3_t cam_pos = camera->position;
--- a/src/wipeout/track.h
+++ b/src/wipeout/track.h
@@ -99,6 +99,6 @@
 struct camera_t;
 void track_draw(struct camera_t *camera);
 
-void track_cycle_pickups();
+void track_cycle_pickups(void);
 
-#endif
\ No newline at end of file
+#endif
--- a/src/wipeout/ui.h
+++ b/src/wipeout/ui.h
@@ -32,13 +32,13 @@
 	UI_POS_BOTTOM = 1 << 5,
 } ui_pos_t;
 
-void ui_load();
-void ui_cleanup();
+void ui_load(void);
+void ui_cleanup(void);
 
-int ui_get_scale();
+int ui_get_scale(void);
 void ui_set_scale(int scale);
 vec2i_t ui_scaled(vec2i_t v);
-vec2i_t ui_scaled_screen();
+vec2i_t ui_scaled_screen(void);
 vec2i_t ui_scaled_pos(ui_pos_t anchor, vec2i_t offset);
 
 int ui_char_width(char c, ui_text_size_t size);
--- a/src/wipeout/weapon.c
+++ b/src/wipeout/weapon.c
@@ -75,6 +75,7 @@
 void invert_shield_polys(Object *shield);
 
 void weapons_load() {
+	int16_t tmp;
 	weapons = mem_bump(sizeof(weapon_t) * WEAPONS_MAX);
 	weapon_assets.reticle = image_get_texture("wipeout/textures/target2.tim");
 
@@ -92,12 +93,16 @@
 	for (int k = 0; k < primitives_len; k++) {
 		switch (poly.primitive->type) {
 		case PRM_TYPE_G3 :
-			swap(poly.g3->coords[0], poly.g3->coords[2]);
+			tmp = poly.g3->coords[0];
+			poly.g3->coords[0] = poly.g3->coords[2];
+			poly.g3->coords[2] = tmp;
 			poly.g3 += 1;
 			break;
 
 		case PRM_TYPE_G4 :
-			swap(poly.g4->coords[0], poly.g4->coords[3]);
+			tmp = poly.g4->coords[0];
+			poly.g4->coords[0] = poly.g4->coords[3];
+			poly.g4->coords[3] = tmp;
 			poly.g4 += 1;
 			break;
 		}
@@ -684,6 +689,7 @@
 	}
 	else {
 		die("Unknown WEAPON_CLASS_ %d", type_class);
+		return -1;
 	}
 }
 
--- a/src/wipeout/weapon.h
+++ b/src/wipeout/weapon.h
@@ -40,12 +40,12 @@
 #define WEAPON_CLASS_PROJECTILE 2
 
 
-void weapons_load();
-void weapons_init();
+void weapons_load(void);
+void weapons_init(void);
 void weapons_fire(ship_t *ship, int weapon_type);
 void weapons_fire_delayed(ship_t *ship, int weapon_type);
-void weapons_update();
-void weapons_draw();
+void weapons_update(void);
+void weapons_draw(void);
 int weapon_get_random_type(int type_class);
 
 #endif