ref: 7cfaff0c7b618e8150bd97ad43fca9899f4a5514
dir: /src/wipeout/object.c/
#include "../types.h" #include "../mem.h" #include "../render.h" #include "../utils.h" #include "object.h" #include "track.h" #include "ship.h" #include "weapon.h" #include "droid.h" #include "camera.h" #include "object.h" #include "scene.h" #include "hud.h" #include "object.h" static rgba_t int32_to_rgba(uint32_t v) { return rgba( ((v >> 24) & 0xff), ((v >> 16) & 0xff), ((v >> 8) & 0xff), 255 ); } Object *objects_load(char *name, texture_list_t tl) { uint32_t length = 0; uint8_t *bytes = file_load(name, &length); if (!bytes) { die("Failed to load file %s\n", name); } printf("load: %s\n", name); Object *objectList = mem_mark(); Object *prevObject = NULL; uint32_t p = 0; while (p < length) { Object *object = mem_bump(sizeof(Object)); if (prevObject) { prevObject->next = object; } prevObject = object; for (int i = 0; i < 16; i++) { object->name[i] = get_i8(bytes, &p); } object->mat = mat4_identity(); object->vertices_len = get_i16(bytes, &p); p += 2; object->vertices = NULL; get_i32(bytes, &p); object->normals_len = get_i16(bytes, &p); p += 2; object->normals = NULL; get_i32(bytes, &p); object->primitives_len = get_i16(bytes, &p); p += 2; object->primitives = NULL; get_i32(bytes, &p); get_i32(bytes, &p); get_i32(bytes, &p); get_i32(bytes, &p); // Skeleton ref object->extent = get_i32(bytes, &p); object->flags = get_i16(bytes, &p); p += 2; object->next = NULL; get_i32(bytes, &p); p += 3 * 3 * 2; // relative rot matrix p += 2; // padding object->origin.x = get_i32(bytes, &p); object->origin.y = get_i32(bytes, &p); object->origin.z = get_i32(bytes, &p); p += 3 * 3 * 2; // absolute rot matrix p += 2; // padding p += 3 * 4; // absolute translation matrix p += 2; // skeleton update flag p += 2; // padding p += 4; // skeleton super p += 4; // skeleton sub p += 4; // skeleton next object->vertices = mem_bump(object->vertices_len * sizeof(vec3_t)); for (int i = 0; i < object->vertices_len; i++) { object->vertices[i].x = get_i16(bytes, &p); object->vertices[i].y = get_i16(bytes, &p); object->vertices[i].z = get_i16(bytes, &p); p += 2; // padding } object->normals = mem_bump(object->normals_len * sizeof(vec3_t)); for (int i = 0; i < object->normals_len; i++) { object->normals[i].x = get_i16(bytes, &p); object->normals[i].y = get_i16(bytes, &p); object->normals[i].z = get_i16(bytes, &p); p += 2; // padding } object->primitives = mem_mark(); for (int i = 0; i < object->primitives_len; i++) { Prm prm; int16_t prm_type = get_i16(bytes, &p); int16_t prm_flag = get_i16(bytes, &p); switch (prm_type) { case PRM_TYPE_F3: prm.ptr = mem_bump(sizeof(F3)); prm.f3->coords[0] = get_i16(bytes, &p); prm.f3->coords[1] = get_i16(bytes, &p); prm.f3->coords[2] = get_i16(bytes, &p); prm.f3->pad1 = get_i16(bytes, &p); prm.f3->colour = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_F4: prm.ptr = mem_bump(sizeof(F4)); prm.f4->coords[0] = get_i16(bytes, &p); prm.f4->coords[1] = get_i16(bytes, &p); prm.f4->coords[2] = get_i16(bytes, &p); prm.f4->coords[3] = get_i16(bytes, &p); prm.f4->colour = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_FT3: prm.ptr = mem_bump(sizeof(FT3)); prm.ft3->coords[0] = get_i16(bytes, &p); prm.ft3->coords[1] = get_i16(bytes, &p); prm.ft3->coords[2] = get_i16(bytes, &p); prm.ft3->texture = texture_from_list(tl, get_i16(bytes, &p)); prm.ft3->cba = get_i16(bytes, &p); prm.ft3->tsb = get_i16(bytes, &p); prm.ft3->u0 = get_i8(bytes, &p); prm.ft3->v0 = get_i8(bytes, &p); prm.ft3->u1 = get_i8(bytes, &p); prm.ft3->v1 = get_i8(bytes, &p); prm.ft3->u2 = get_i8(bytes, &p); prm.ft3->v2 = get_i8(bytes, &p); prm.ft3->pad1 = get_i16(bytes, &p); prm.ft3->colour = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_FT4: prm.ptr = mem_bump(sizeof(FT4)); prm.ft4->coords[0] = get_i16(bytes, &p); prm.ft4->coords[1] = get_i16(bytes, &p); prm.ft4->coords[2] = get_i16(bytes, &p); prm.ft4->coords[3] = get_i16(bytes, &p); prm.ft4->texture = texture_from_list(tl, get_i16(bytes, &p)); prm.ft4->cba = get_i16(bytes, &p); prm.ft4->tsb = get_i16(bytes, &p); prm.ft4->u0 = get_i8(bytes, &p); prm.ft4->v0 = get_i8(bytes, &p); prm.ft4->u1 = get_i8(bytes, &p); prm.ft4->v1 = get_i8(bytes, &p); prm.ft4->u2 = get_i8(bytes, &p); prm.ft4->v2 = get_i8(bytes, &p); prm.ft4->u3 = get_i8(bytes, &p); prm.ft4->v3 = get_i8(bytes, &p); prm.ft4->pad1 = get_i16(bytes, &p); prm.ft4->colour = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_G3: prm.ptr = mem_bump(sizeof(G3)); prm.g3->coords[0] = get_i16(bytes, &p); prm.g3->coords[1] = get_i16(bytes, &p); prm.g3->coords[2] = get_i16(bytes, &p); prm.g3->pad1 = get_i16(bytes, &p); prm.g3->colour[0] = int32_to_rgba(get_i32(bytes, &p)); prm.g3->colour[1] = int32_to_rgba(get_i32(bytes, &p)); prm.g3->colour[2] = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_G4: prm.ptr = mem_bump(sizeof(G4)); prm.g4->coords[0] = get_i16(bytes, &p); prm.g4->coords[1] = get_i16(bytes, &p); prm.g4->coords[2] = get_i16(bytes, &p); prm.g4->coords[3] = get_i16(bytes, &p); prm.g4->colour[0] = int32_to_rgba(get_i32(bytes, &p)); prm.g4->colour[1] = int32_to_rgba(get_i32(bytes, &p)); prm.g4->colour[2] = int32_to_rgba(get_i32(bytes, &p)); prm.g4->colour[3] = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_GT3: prm.ptr = mem_bump(sizeof(GT3)); prm.gt3->coords[0] = get_i16(bytes, &p); prm.gt3->coords[1] = get_i16(bytes, &p); prm.gt3->coords[2] = get_i16(bytes, &p); prm.gt3->texture = texture_from_list(tl, get_i16(bytes, &p)); prm.gt3->cba = get_i16(bytes, &p); prm.gt3->tsb = get_i16(bytes, &p); prm.gt3->u0 = get_i8(bytes, &p); prm.gt3->v0 = get_i8(bytes, &p); prm.gt3->u1 = get_i8(bytes, &p); prm.gt3->v1 = get_i8(bytes, &p); prm.gt3->u2 = get_i8(bytes, &p); prm.gt3->v2 = get_i8(bytes, &p); prm.gt3->pad1 = get_i16(bytes, &p); prm.gt3->colour[0] = int32_to_rgba(get_i32(bytes, &p)); prm.gt3->colour[1] = int32_to_rgba(get_i32(bytes, &p)); prm.gt3->colour[2] = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_GT4: prm.ptr = mem_bump(sizeof(GT4)); prm.gt4->coords[0] = get_i16(bytes, &p); prm.gt4->coords[1] = get_i16(bytes, &p); prm.gt4->coords[2] = get_i16(bytes, &p); prm.gt4->coords[3] = get_i16(bytes, &p); prm.gt4->texture = texture_from_list(tl, get_i16(bytes, &p)); prm.gt4->cba = get_i16(bytes, &p); prm.gt4->tsb = get_i16(bytes, &p); prm.gt4->u0 = get_i8(bytes, &p); prm.gt4->v0 = get_i8(bytes, &p); prm.gt4->u1 = get_i8(bytes, &p); prm.gt4->v1 = get_i8(bytes, &p); prm.gt4->u2 = get_i8(bytes, &p); prm.gt4->v2 = get_i8(bytes, &p); prm.gt4->u3 = get_i8(bytes, &p); prm.gt4->v3 = get_i8(bytes, &p); prm.gt4->pad1 = get_i16(bytes, &p); prm.gt4->colour[0] = int32_to_rgba(get_i32(bytes, &p)); prm.gt4->colour[1] = int32_to_rgba(get_i32(bytes, &p)); prm.gt4->colour[2] = int32_to_rgba(get_i32(bytes, &p)); prm.gt4->colour[3] = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_LSF3: prm.ptr = mem_bump(sizeof(LSF3)); prm.lsf3->coords[0] = get_i16(bytes, &p); prm.lsf3->coords[1] = get_i16(bytes, &p); prm.lsf3->coords[2] = get_i16(bytes, &p); prm.lsf3->normal = get_i16(bytes, &p); prm.lsf3->colour = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_LSF4: prm.ptr = mem_bump(sizeof(LSF4)); prm.lsf4->coords[0] = get_i16(bytes, &p); prm.lsf4->coords[1] = get_i16(bytes, &p); prm.lsf4->coords[2] = get_i16(bytes, &p); prm.lsf4->coords[3] = get_i16(bytes, &p); prm.lsf4->normal = get_i16(bytes, &p); prm.lsf4->pad1 = get_i16(bytes, &p); prm.lsf4->colour = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_LSFT3: prm.ptr = mem_bump(sizeof(LSFT3)); prm.lsft3->coords[0] = get_i16(bytes, &p); prm.lsft3->coords[1] = get_i16(bytes, &p); prm.lsft3->coords[2] = get_i16(bytes, &p); prm.lsft3->normal = get_i16(bytes, &p); prm.lsft3->texture = texture_from_list(tl, get_i16(bytes, &p)); prm.lsft3->cba = get_i16(bytes, &p); prm.lsft3->tsb = get_i16(bytes, &p); prm.lsft3->u0 = get_i8(bytes, &p); prm.lsft3->v0 = get_i8(bytes, &p); prm.lsft3->u1 = get_i8(bytes, &p); prm.lsft3->v1 = get_i8(bytes, &p); prm.lsft3->u2 = get_i8(bytes, &p); prm.lsft3->v2 = get_i8(bytes, &p); prm.lsft3->colour = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_LSFT4: prm.ptr = mem_bump(sizeof(LSFT4)); prm.lsft4->coords[0] = get_i16(bytes, &p); prm.lsft4->coords[1] = get_i16(bytes, &p); prm.lsft4->coords[2] = get_i16(bytes, &p); prm.lsft4->coords[3] = get_i16(bytes, &p); prm.lsft4->normal = get_i16(bytes, &p); prm.lsft4->texture = texture_from_list(tl, get_i16(bytes, &p)); prm.lsft4->cba = get_i16(bytes, &p); prm.lsft4->tsb = get_i16(bytes, &p); prm.lsft4->u0 = get_i8(bytes, &p); prm.lsft4->v0 = get_i8(bytes, &p); prm.lsft4->u1 = get_i8(bytes, &p); prm.lsft4->v1 = get_i8(bytes, &p); prm.lsft4->u2 = get_i8(bytes, &p); prm.lsft4->v2 = get_i8(bytes, &p); prm.lsft4->u3 = get_i8(bytes, &p); prm.lsft4->v3 = get_i8(bytes, &p); prm.lsft4->colour = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_LSG3: prm.ptr = mem_bump(sizeof(LSG3)); prm.lsg3->coords[0] = get_i16(bytes, &p); prm.lsg3->coords[1] = get_i16(bytes, &p); prm.lsg3->coords[2] = get_i16(bytes, &p); prm.lsg3->normals[0] = get_i16(bytes, &p); prm.lsg3->normals[1] = get_i16(bytes, &p); prm.lsg3->normals[2] = get_i16(bytes, &p); prm.lsg3->colour[0] = int32_to_rgba(get_i32(bytes, &p)); prm.lsg3->colour[1] = int32_to_rgba(get_i32(bytes, &p)); prm.lsg3->colour[2] = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_LSG4: prm.ptr = mem_bump(sizeof(LSG4)); prm.lsg4->coords[0] = get_i16(bytes, &p); prm.lsg4->coords[1] = get_i16(bytes, &p); prm.lsg4->coords[2] = get_i16(bytes, &p); prm.lsg4->coords[3] = get_i16(bytes, &p); prm.lsg4->normals[0] = get_i16(bytes, &p); prm.lsg4->normals[1] = get_i16(bytes, &p); prm.lsg4->normals[2] = get_i16(bytes, &p); prm.lsg4->normals[3] = get_i16(bytes, &p); prm.lsg4->colour[0] = int32_to_rgba(get_i32(bytes, &p)); prm.lsg4->colour[1] = int32_to_rgba(get_i32(bytes, &p)); prm.lsg4->colour[2] = int32_to_rgba(get_i32(bytes, &p)); prm.lsg4->colour[3] = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_LSGT3: prm.ptr = mem_bump(sizeof(LSGT3)); prm.lsgt3->coords[0] = get_i16(bytes, &p); prm.lsgt3->coords[1] = get_i16(bytes, &p); prm.lsgt3->coords[2] = get_i16(bytes, &p); prm.lsgt3->normals[0] = get_i16(bytes, &p); prm.lsgt3->normals[1] = get_i16(bytes, &p); prm.lsgt3->normals[2] = get_i16(bytes, &p); prm.lsgt3->texture = texture_from_list(tl, get_i16(bytes, &p)); prm.lsgt3->cba = get_i16(bytes, &p); prm.lsgt3->tsb = get_i16(bytes, &p); prm.lsgt3->u0 = get_i8(bytes, &p); prm.lsgt3->v0 = get_i8(bytes, &p); prm.lsgt3->u1 = get_i8(bytes, &p); prm.lsgt3->v1 = get_i8(bytes, &p); prm.lsgt3->u2 = get_i8(bytes, &p); prm.lsgt3->v2 = get_i8(bytes, &p); prm.lsgt3->colour[0] = int32_to_rgba(get_i32(bytes, &p)); prm.lsgt3->colour[1] = int32_to_rgba(get_i32(bytes, &p)); prm.lsgt3->colour[2] = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_LSGT4: prm.ptr = mem_bump(sizeof(LSGT4)); prm.lsgt4->coords[0] = get_i16(bytes, &p); prm.lsgt4->coords[1] = get_i16(bytes, &p); prm.lsgt4->coords[2] = get_i16(bytes, &p); prm.lsgt4->coords[3] = get_i16(bytes, &p); prm.lsgt4->normals[0] = get_i16(bytes, &p); prm.lsgt4->normals[1] = get_i16(bytes, &p); prm.lsgt4->normals[2] = get_i16(bytes, &p); prm.lsgt4->normals[3] = get_i16(bytes, &p); prm.lsgt4->texture = texture_from_list(tl, get_i16(bytes, &p)); prm.lsgt4->cba = get_i16(bytes, &p); prm.lsgt4->tsb = get_i16(bytes, &p); prm.lsgt4->u0 = get_i8(bytes, &p); prm.lsgt4->v0 = get_i8(bytes, &p); prm.lsgt4->u1 = get_i8(bytes, &p); prm.lsgt4->v1 = get_i8(bytes, &p); prm.lsgt4->u2 = get_i8(bytes, &p); prm.lsgt4->v2 = get_i8(bytes, &p); prm.lsgt4->pad1 = get_i16(bytes, &p); prm.lsgt4->colour[0] = int32_to_rgba(get_i32(bytes, &p)); prm.lsgt4->colour[1] = int32_to_rgba(get_i32(bytes, &p)); prm.lsgt4->colour[2] = int32_to_rgba(get_i32(bytes, &p)); prm.lsgt4->colour[3] = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_TSPR: case PRM_TYPE_BSPR: prm.ptr = mem_bump(sizeof(SPR)); prm.spr->coord = get_i16(bytes, &p); prm.spr->width = get_i16(bytes, &p); prm.spr->height = get_i16(bytes, &p); prm.spr->texture = texture_from_list(tl, get_i16(bytes, &p)); prm.spr->colour = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_SPLINE: prm.ptr = mem_bump(sizeof(Spline)); prm.spline->control1.x = get_i32(bytes, &p); prm.spline->control1.y = get_i32(bytes, &p); prm.spline->control1.z = get_i32(bytes, &p); p += 4; // padding prm.spline->position.x = get_i32(bytes, &p); prm.spline->position.y = get_i32(bytes, &p); prm.spline->position.z = get_i32(bytes, &p); p += 4; // padding prm.spline->control2.x = get_i32(bytes, &p); prm.spline->control2.y = get_i32(bytes, &p); prm.spline->control2.z = get_i32(bytes, &p); p += 4; // padding prm.spline->colour = int32_to_rgba(get_i32(bytes, &p)); break; case PRM_TYPE_POINT_LIGHT: prm.ptr = mem_bump(sizeof(PointLight)); prm.pointLight->position.x = get_i32(bytes, &p); prm.pointLight->position.y = get_i32(bytes, &p); prm.pointLight->position.z = get_i32(bytes, &p); p += 4; // padding prm.pointLight->colour = int32_to_rgba(get_i32(bytes, &p)); prm.pointLight->startFalloff = get_i16(bytes, &p); prm.pointLight->endFalloff = get_i16(bytes, &p); break; case PRM_TYPE_SPOT_LIGHT: prm.ptr = mem_bump(sizeof(SpotLight)); prm.spotLight->position.x = get_i32(bytes, &p); prm.spotLight->position.y = get_i32(bytes, &p); prm.spotLight->position.z = get_i32(bytes, &p); p += 4; // padding prm.spotLight->direction.x = get_i16(bytes, &p); prm.spotLight->direction.y = get_i16(bytes, &p); prm.spotLight->direction.z = get_i16(bytes, &p); p += 2; // padding prm.spotLight->colour = int32_to_rgba(get_i32(bytes, &p)); prm.spotLight->startFalloff = get_i16(bytes, &p); prm.spotLight->endFalloff = get_i16(bytes, &p); prm.spotLight->coneAngle = get_i16(bytes, &p); prm.spotLight->spreadAngle = get_i16(bytes, &p); break; case PRM_TYPE_INFINITE_LIGHT: prm.ptr = mem_bump(sizeof(InfiniteLight)); prm.infiniteLight->direction.x = get_i16(bytes, &p); prm.infiniteLight->direction.y = get_i16(bytes, &p); prm.infiniteLight->direction.z = get_i16(bytes, &p); p += 2; // padding prm.infiniteLight->colour = int32_to_rgba(get_i32(bytes, &p)); break; default: die("bad primitive type %x \n", prm_type); } // switch prm.f3->type = prm_type; prm.f3->flag = prm_flag; } // each prim } // each object mem_temp_free(bytes); return objectList; } void object_draw(Object *object, mat4_t *mat) { vec3_t *vertex = object->vertices; Prm poly = {.primitive = object->primitives}; int primitives_len = object->primitives_len; render_set_model_mat(mat); // TODO: check for PRM_SINGLE_SIDED for (int i = 0; i < primitives_len; i++) { int coord0; int coord1; int coord2; int coord3; switch (poly.primitive->type) { case PRM_TYPE_GT3: coord0 = poly.gt3->coords[0]; coord1 = poly.gt3->coords[1]; coord2 = poly.gt3->coords[2]; 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; case PRM_TYPE_GT4: coord0 = poly.gt4->coords[0]; coord1 = poly.gt4->coords[1]; 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); poly.gt4 += 1; break; case PRM_TYPE_FT3: coord0 = poly.ft3->coords[0]; 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); poly.ft3 += 1; break; case PRM_TYPE_FT4: coord0 = poly.ft4->coords[0]; coord1 = poly.ft4->coords[1]; 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); poly.ft4 += 1; break; case PRM_TYPE_G3: coord0 = poly.g3->coords[0]; 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); poly.g3 += 1; break; case PRM_TYPE_G4: coord0 = poly.g4->coords[0]; coord1 = poly.g4->coords[1]; 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); poly.g4 += 1; break; case PRM_TYPE_F3: coord0 = poly.f3->coords[0]; 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); poly.f3 += 1; break; case PRM_TYPE_F4: coord0 = poly.f4->coords[0]; coord1 = poly.f4->coords[1]; 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); poly.f4 += 1; break; case PRM_TYPE_TSPR: case PRM_TYPE_BSPR: coord0 = poly.spr->coord; render_push_sprite( vec3( vertex[coord0].x, vertex[coord0].y + ((poly.primitive->type == PRM_TYPE_TSPR ? poly.spr->height : -poly.spr->height) >> 1), vertex[coord0].z ), vec2i(poly.spr->width, poly.spr->height), poly.spr->colour, poly.spr->texture ); poly.spr += 1; break; default: break; } } }