diff --git a/GL/clip.c b/GL/clip.c index 5b0a120..bc0684d 100644 --- a/GL/clip.c +++ b/GL/clip.c @@ -287,9 +287,13 @@ void _glClipTriangleStrip(SubmissionTarget* target, uint8_t fladeShade) { TO_CLIP[CLIP_COUNT].vertex[1] = *v2; TO_CLIP[CLIP_COUNT].vertex[2] = *v3; - TO_CLIP[CLIP_COUNT].extra[0] = *(VertexExtra*) aligned_vector_at(target->extras, vi1); - TO_CLIP[CLIP_COUNT].extra[1] = *(VertexExtra*) aligned_vector_at(target->extras, vi2); - TO_CLIP[CLIP_COUNT].extra[2] = *(VertexExtra*) aligned_vector_at(target->extras, vi3); + 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; @@ -325,21 +329,18 @@ void _glClipTriangleStrip(SubmissionTarget* target, uint8_t fladeShade) { triangle = -1; } else { - /* FIXME: ? - * This situation doesn't actually seem possible, we always clip from one end - * of the triangle strip to the other, so we're never going to hit the plane in the - * middle of the strip (with previous/next unhandled tris). - * - * Uncomment if this actually happens */ - assert(0 && "Not Implemented (see comment)"); - - /* - ClipVertex* v4 = vertex + 1; + 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 = ((v3->w > 0) ? 4 : 0) | ((v2->w > 0) ? 2 : 0) | ((v4->w > 0) ? 1 : 0); TO_CLIP[CLIP_COUNT].visible = visible; @@ -352,17 +353,19 @@ void _glClipTriangleStrip(SubmissionTarget* target, uint8_t fladeShade) { (vertex - 1)->flags = VERTEX_CMD_EOL; if(v4->flags == VERTEX_CMD_EOL) { - markDead(vertex); + markDead(v3); markDead(v4); } else { // Swap the next vertices to start a new strip - ClipVertex tmp = *vertex; - *vertex = *v4; - *v4 = tmp; - - vertex->flags = VERTEX_CMD; + 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: diff --git a/GL/draw.c b/GL/draw.c index 05058ed..f1fe8a9 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -536,34 +536,6 @@ static inline void transformNormalToEyeSpace(GLfloat* normal) { mat_trans_normal3(normal[0], normal[1], normal[2]); } - -/* FIXME: SH4 has a swap.w instruction, we should leverage it here! */ -#define _SWAP32(x, y) \ -do { \ - uint32_t t = *((uint32_t*) &x); \ - *((uint32_t*) &x) = *((uint32_t*) &y); \ - *((uint32_t*) &y) = t; \ -} while(0) - -/* - *((uint32_t*) &x) = *((uint32_t*) &x) ^ *((uint32_t*) &y); \ - *((uint32_t*) &y) = *((uint32_t*) &x) ^ *((uint32_t*) &y); \ - *((uint32_t*) &x) = *((uint32_t*) &x) ^ *((uint32_t*) &y); */ - - -#define swapVertex(a, b) \ -do { \ - _SWAP32(a->flags, b->flags); \ - _SWAP32(a->xyz[0], b->xyz[0]); \ - _SWAP32(a->xyz[1], b->xyz[1]); \ - _SWAP32(a->xyz[2], b->xyz[2]); \ - _SWAP32(a->uv[0], b->uv[0]); \ - _SWAP32(a->uv[1], b->uv[1]); \ - _SWAP32(a->bgra, b->bgra); \ - _SWAP32(a->w, b->w); \ -} while(0) - - PVRHeader* _glSubmissionTargetHeader(SubmissionTarget* target) { return aligned_vector_at(&target->output->vector, target->header_offset); } diff --git a/GL/private.h b/GL/private.h index bdae752..53528be 100644 --- a/GL/private.h +++ b/GL/private.h @@ -105,6 +105,32 @@ typedef struct { float w; } Vertex; +/* FIXME: SH4 has a swap.w instruction, we should leverage it here! */ +#define _SWAP32(x, y) \ +do { \ + uint32_t t = *((uint32_t*) &x); \ + *((uint32_t*) &x) = *((uint32_t*) &y); \ + *((uint32_t*) &y) = t; \ +} while(0) + +/* + *((uint32_t*) &x) = *((uint32_t*) &x) ^ *((uint32_t*) &y); \ + *((uint32_t*) &y) = *((uint32_t*) &x) ^ *((uint32_t*) &y); \ + *((uint32_t*) &x) = *((uint32_t*) &x) ^ *((uint32_t*) &y); */ + + +#define swapVertex(a, b) \ +do { \ + _SWAP32(a->flags, b->flags); \ + _SWAP32(a->xyz[0], b->xyz[0]); \ + _SWAP32(a->xyz[1], b->xyz[1]); \ + _SWAP32(a->xyz[2], b->xyz[2]); \ + _SWAP32(a->uv[0], b->uv[0]); \ + _SWAP32(a->uv[1], b->uv[1]); \ + _SWAP32(a->bgra, b->bgra); \ + _SWAP32(a->w, b->w); \ +} while(0) + /* ClipVertex doesn't have room for these, so we need to parse them * out separately. Potentially 'w' will be housed here if we support oargb */ typedef struct {