From 9d9a502e96a57b543235f1bd3b6a0ac8fad4f1f6 Mon Sep 17 00:00:00 2001
From: Luke Benstead <kazade@gmail.com>
Date: Mon, 13 Jun 2022 20:16:46 +0100
Subject: [PATCH] Remove old clipping

---
 CMakeLists.txt |   1 -
 GL/clip.c      | 405 -------------------------------------------------
 2 files changed, 406 deletions(-)
 delete mode 100644 GL/clip.c

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 32a7d8d..b613495 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,7 +33,6 @@ set(
     containers/aligned_vector.c
     containers/named_array.c
     containers/stack.c
-    GL/clip.c
     GL/draw.c
     GL/error.c
     GL/flush.c
diff --git a/GL/clip.c b/GL/clip.c
deleted file mode 100644
index ed051d8..0000000
--- a/GL/clip.c
+++ /dev/null
@@ -1,405 +0,0 @@
-#include <float.h>
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-#include <stdbool.h>
-#include <stdlib.h>
-
-#ifdef _arch_dreamcast
-#include <dc/pvr.h>
-#else
-#define PVR_PACK_COLOR(a, r, g, b) {}
-#endif
-
-#include "private.h"
-#include "../containers/aligned_vector.h"
-
-static unsigned char ZCLIP_ENABLED = 1;
-
-unsigned char _glIsClippingEnabled() {
-    return ZCLIP_ENABLED;
-}
-
-void _glEnableClipping(unsigned char v) {
-    ZCLIP_ENABLED = v;
-}
-
-inline float _glClipLineToNearZ(const Vertex* v1, const Vertex* v2, Vertex* vout) {
-    const float d0 = v1->w + v1->xyz[2];
-    const float d1 = v2->w + v2->xyz[2];
-
-    /* We need to shift 't' a little, to avoid the possibility that a
-     * rounding error leaves the new vertex behind the near plane. We shift
-     * according to the direction we're clipping across the plane */
-    const float epsilon = (d0 < d1) ? -0.000001 : 0.000001;
-
-    float t = MATH_Fast_Divide(d0, (d0 - d1)) + epsilon;
-
-    vout->xyz[0] = MATH_fmac(v2->xyz[0] - v1->xyz[0], t, v1->xyz[0]);
-    vout->xyz[1] = MATH_fmac(v2->xyz[1] - v1->xyz[1], t, v1->xyz[1]);
-    vout->xyz[2] = MATH_fmac(v2->xyz[2] - v1->xyz[2], t, v1->xyz[2]);
-
-    /*
-    printf(
-        "(%f, %f, %f, %f) -> %f -> (%f, %f, %f, %f) = (%f, %f, %f)\n",
-        v1->xyz[0], v1->xyz[1], v1->xyz[2], v1->w, t,
-        v2->xyz[0], v2->xyz[1], v2->xyz[2], v2->w,
-        vout->xyz[0], vout->xyz[1], vout->xyz[2]
-    );*/
-
-    return t;
-}
-
-GL_FORCE_INLINE void interpolateFloat(const float v1, const float v2, const float t, float* out) {
-    *out = MATH_fmac(v2 - v1,t, v1);
-}
-
-GL_FORCE_INLINE void interpolateVec2(const float* v1, const float* v2, const float t, float* out) {
-    interpolateFloat(v1[0], v2[0], t, &out[0]);
-    interpolateFloat(v1[1], v2[1], t, &out[1]);
-}
-
-GL_FORCE_INLINE void interpolateVec3(const float* v1, const float* v2, const float t, float* out) {
-    interpolateFloat(v1[0], v2[0], t, &out[0]);
-    interpolateFloat(v1[1], v2[1], t, &out[1]);
-    interpolateFloat(v1[2], v2[2], t, &out[2]);
-}
-
-GL_FORCE_INLINE void interpolateVec4(const float* v1, const float* v2, const float t, float* out) {
-    interpolateFloat(v1[0], v2[0], t, &out[0]);
-    interpolateFloat(v1[1], v2[1], t, &out[1]);
-    interpolateFloat(v1[2], v2[2], t, &out[2]);
-    interpolateFloat(v1[3], v2[3], t, &out[3]);
-}
-
-GL_FORCE_INLINE void interpolateColour(const uint8_t* v1, const uint8_t* v2, const float t, uint8_t* out) {
-    out[0] = v1[0] + (uint32_t) (((float) (v2[0] - v1[0])) * t);
-    out[1] = v1[1] + (uint32_t) (((float) (v2[1] - v1[1])) * t);
-    out[2] = v1[2] + (uint32_t) (((float) (v2[2] - v1[2])) * t);
-    out[3] = v1[3] + (uint32_t) (((float) (v2[3] - v1[3])) * t);
-}
-
-const uint32_t VERTEX_CMD_EOL = 0xf0000000;
-const uint32_t VERTEX_CMD = 0xe0000000;
-
-typedef struct {
-    Vertex vertex[3];
-    VertexExtra extra[3];
-    uint8_t visible;
-} Triangle;
-
-void _glClipTriangle(const Triangle* triangle, const uint8_t visible, SubmissionTarget* target, const uint8_t flatShade) {
-    Vertex* last = NULL;
-    VertexExtra* veLast = NULL;
-
-    const Vertex* vertices = triangle->vertex;
-    const VertexExtra* extras = triangle->extra;
-
-    char* bgra = (char*) vertices[2].bgra;
-
-    /* Used when flat shading is enabled */
-    uint32_t finalColour = *((uint32_t*) bgra);
-
-    Vertex tmp;
-    VertexExtra veTmp;
-
-    uint8_t pushedCount = 0;
-
-#define IS_VISIBLE(x) (visible & (1 << (2 - (x)))) > 0
-
-#define PUSH_VERT(vert, ve) \
-    last = aligned_vector_push_back(&target->output->vector, vert, 1); \
-    last->flags = VERTEX_CMD; \
-    veLast = aligned_vector_push_back(target->extras, ve, 1); \
-    ++pushedCount;
-
-#define CLIP_TO_PLANE(vert1, ve1, vert2, ve2) \
-    do { \
-        float t = _glClipLineToNearZ((vert1), (vert2), &tmp); \
-        interpolateFloat((vert1)->w, (vert2)->w, t, &tmp.w); \
-        interpolateVec2((vert1)->uv, (vert2)->uv, t, tmp.uv); \
-        interpolateVec3((ve1)->nxyz, (ve2)->nxyz, t, veTmp.nxyz); \
-        interpolateVec2((ve1)->st, (ve2)->st, t, veTmp.st); \
-        if(flatShade) { \
-            interpolateColour((const uint8_t*) &finalColour, (const uint8_t*) &finalColour, t, tmp.bgra); \
-        } else { interpolateColour((vert1)->bgra, (vert2)->bgra, t, tmp.bgra); } \
-    } while(0); \
-
-    uint8_t v0 = IS_VISIBLE(0);
-    uint8_t v1 = IS_VISIBLE(1);
-    uint8_t v2 = IS_VISIBLE(2);
-    if(v0) {
-        PUSH_VERT(&vertices[0], &extras[0]);
-    }
-
-    if(v0 != v1) {
-        CLIP_TO_PLANE(&vertices[0], &extras[0], &vertices[1], &extras[1]);
-        PUSH_VERT(&tmp, &veTmp);
-    }
-
-    if(v1) {
-        PUSH_VERT(&vertices[1], &extras[1]);
-    }
-
-    if(v1 != v2) {
-        CLIP_TO_PLANE(&vertices[1], &extras[1], &vertices[2], &extras[2]);
-        PUSH_VERT(&tmp, &veTmp);
-    }
-
-    if(v2) {
-        PUSH_VERT(&vertices[2], &extras[2]);
-    }
-
-    if(v2 != v0) {
-        CLIP_TO_PLANE(&vertices[2], &extras[2], &vertices[0], &extras[0]);
-        PUSH_VERT(&tmp, &veTmp);
-    }
-
-    if(pushedCount == 4) {
-        Vertex* prev = last - 1;
-        VertexExtra* prevVe = veLast - 1;
-
-        tmp = *prev;
-        veTmp = *prevVe;
-
-        *prev = *last;
-        *prevVe = *veLast;
-
-        *last = tmp;
-        *veLast = veTmp;
-
-        prev->flags = VERTEX_CMD;
-        last->flags = VERTEX_CMD_EOL;
-    } else {
-        /* Set the last flag to the end of the new strip */
-        last->flags = VERTEX_CMD_EOL;
-    }
-}
-
-static inline void markDead(Vertex* vert) {
-    vert->flags = VERTEX_CMD_EOL;
-
-    // If we're debugging, wipe out the xyz
-#ifndef NDEBUG
-    typedef union {
-        float* f;
-        int* i;
-    } cast;
-
-    cast v1, v2, v3;
-    v1.f = &vert->xyz[0];
-    v2.f = &vert->xyz[1];
-    v3.f = &vert->xyz[2];
-
-    *v1.i = 0xDEADBEEF;
-    *v2.i = 0xDEADBEEF;
-    *v3.i = 0xDEADBEEF;
-#endif
-}
-
-#define B000 0
-#define B111 7
-#define B100 4
-#define B010 2
-#define B001 1
-#define B101 5
-#define B011 3
-#define B110 6
-
-#define MAX_CLIP_TRIANGLES 255
-
-void _glClipTriangleStrip(SubmissionTarget* target, uint8_t fladeShade) {
-    static Triangle TO_CLIP[MAX_CLIP_TRIANGLES];
-    static uint8_t CLIP_COUNT = 0;
-
-    CLIP_COUNT = 0;
-
-    Vertex* vertex = _glSubmissionTargetStart(target);
-    const Vertex* end = _glSubmissionTargetEnd(target);
-    const Vertex* start = vertex;
-
-    int32_t triangle = -1;
-
-    /* Go to the (potential) end of the first triangle */
-    vertex++;
-
-    uint32_t vi1, vi2, vi3;
-
-    while(vertex < end) {
-        vertex++;
-        triangle++;
-
-        uint8_t even = (triangle % 2) == 0;
-        Vertex* v1 = (even) ? vertex - 2 : vertex - 1;
-        Vertex* v2 = (even) ? vertex - 1 : vertex - 2;
-        Vertex* v3 = vertex;
-
-        /* Skip ahead if we don't have a complete triangle yet */
-        if(v1->flags != VERTEX_CMD || v2->flags != VERTEX_CMD) {
-            triangle = -1;
-            continue;
-        }
-
-        /* Indexes into extras array */
-        vi1 = v1 - start;
-        vi2 = v2 - start;
-        vi3 = v3 - start;
-
-        /*
-         * A vertex is visible if it's in front of the camera (W > 0)
-         * and it's in front of the near plane (Z > -W)
-         */
-
-#define _VERT_VISIBLE(v) \
-    (v->xyz[2] > -v->w) \
-
-        uint8_t visible = (
-            (_VERT_VISIBLE(v1) ? 4 : 0) |
-            (_VERT_VISIBLE(v2) ? 2 : 0) |
-            (_VERT_VISIBLE(v3) ? 1 : 0)
-        );
-
-        switch(visible) {
-            case B111:
-                /* All visible? Do nothing */
-                continue;
-            break;
-            case B000:
-                /*
-                    It is not possible that this is any trangle except the first
-                    in a strip. That's because:
-                    - It's either the first triangle submitted
-                    - A previous triangle must have been clipped and the strip
-                      restarted behind the plane
-
-                    So, we effectively reboot the strip. We mark the first vertex
-                    as the end (so it's ignored) then mark the next two as the
-                    start of a new strip. Then if the next triangle crosses
-                    back into view, we clip correctly. This will potentially
-                    result in a bunch of pointlessly submitted vertices.
-
-                    FIXME: Skip submitting those verts
-                */
-
-                /* Even though this is always the first in the strip, it can also
-                 * be the last */
-                if(v3->flags == VERTEX_CMD_EOL) {
-                    /* Wipe out the triangle */
-                    markDead(v1);
-                    markDead(v2);
-                    markDead(v3);
-                } else {
-                    markDead(v1);
-                    swapVertex(v2, v3);
-                    triangle = -1;
-                    v2->flags = VERTEX_CMD;
-                    v3->flags = VERTEX_CMD;
-                }
-            break;
-            case B100:
-            case B010:
-            case B001:
-            case B101:
-            case B011:
-            case B110:
-                assert(CLIP_COUNT < MAX_CLIP_TRIANGLES);
-
-                /* Store the triangle for clipping */
-                TO_CLIP[CLIP_COUNT].vertex[0] = *v1;
-                TO_CLIP[CLIP_COUNT].vertex[1] = *v2;
-                TO_CLIP[CLIP_COUNT].vertex[2] = *v3;
-
-                VertexExtra* ve1 = (VertexExtra*) aligned_vector_at(target->extras, vi1);
-                VertexExtra* ve2 = (VertexExtra*) aligned_vector_at(target->extras, vi2);
-                VertexExtra* ve3 = (VertexExtra*) aligned_vector_at(target->extras, vi3);
-
-                TO_CLIP[CLIP_COUNT].extra[0] = *ve1;
-                TO_CLIP[CLIP_COUNT].extra[1] = *ve2;
-                TO_CLIP[CLIP_COUNT].extra[2] = *ve3;
-
-                TO_CLIP[CLIP_COUNT].visible = visible;
-                ++CLIP_COUNT;
-
-                /*
-                    OK so here's the clever bit. If any triangle except
-                    the first or last needs clipping, then the next one does aswell
-                    (you can't draw a plane through a single triangle in the middle of a
-                    strip, only 2+). This means we can clip in pairs which frees up two
-                    vertices in the middle of the strip, which is exactly the space
-                    we need to restart the triangle strip after the next triangle
-                */
-                if(v3->flags == VERTEX_CMD_EOL) {
-                    /* Last triangle in strip so end a vertex early */
-                    if(triangle == 0) {
-                        // Wipe out the triangle completely
-                        markDead(v1);
-                        markDead(v2);
-                    } else {
-                        // End the strip
-                        (vertex - 1)->flags = VERTEX_CMD_EOL;
-                    }
-
-                    markDead(vertex);
-
-                    triangle = -1;
-                } else if(triangle == 0) {
-                    /* First triangle in strip, remove first vertex */
-                    markDead(v1);
-
-                    v2->flags = VERTEX_CMD;
-                    v3->flags = VERTEX_CMD;
-
-                    triangle = -1;
-                } else {
-                    Vertex* v4 = v3 + 1;
-                    uint32_t vi4 = v4 - start;
-
-                    TO_CLIP[CLIP_COUNT].vertex[0] = *v3;
-                    TO_CLIP[CLIP_COUNT].vertex[1] = *v2;
-                    TO_CLIP[CLIP_COUNT].vertex[2] = *v4;
-
-                    VertexExtra* ve4 = (VertexExtra*) aligned_vector_at(target->extras, vi4);
-                    TO_CLIP[CLIP_COUNT].extra[0] = *(VertexExtra*) aligned_vector_at(target->extras, vi3);
-                    TO_CLIP[CLIP_COUNT].extra[1] = *(VertexExtra*) aligned_vector_at(target->extras, vi2);
-                    TO_CLIP[CLIP_COUNT].extra[2] = *ve4;
-
-                    visible = (_VERT_VISIBLE(v3) ? 4 : 0) |
-                              (_VERT_VISIBLE(v2) ? 2 : 0) |
-                              (_VERT_VISIBLE(v4) ? 1 : 0);
-
-                    TO_CLIP[CLIP_COUNT].visible = visible;
-                    ++CLIP_COUNT;
-
-                    // Restart strip
-                    triangle = -1;
-
-                    // Mark the second vertex as the end of the strip
-                    (vertex - 1)->flags = VERTEX_CMD_EOL;
-
-                    if(v4->flags == VERTEX_CMD_EOL) {
-                        markDead(v3);
-                        markDead(v4);
-                    } else {
-                        // Swap the next vertices to start a new strip
-                        swapVertex(v3, v4);
-                        v3->flags = VERTEX_CMD;
-                        v4->flags = VERTEX_CMD;
-
-                        /* Swap the extra data too */
-                        VertexExtra t = *ve4;
-                        *ve3 = *ve4;
-                        *ve4 = t;
-                    }
-                }
-            break;
-            default:
-                break;
-        }
-    }
-
-    /* Now, clip all the triangles and append them to the output */
-    GLushort i;
-    for(i = 0; i < CLIP_COUNT; ++i) {
-        _glClipTriangle(&TO_CLIP[i], TO_CLIP[i].visible, target, fladeShade);
-    }
-}