Search
lxdream.org :: lxdream :: r222:541d9d899aba
lxdream 0.9.1
released Jun 29
Download Now
changeset222:541d9d899aba
parent221:cf5c6d326162
child223:f6c28fa9076b
authornkeynes
dateTue Sep 12 11:54:19 2006 +0000 (13 years ago)
Bug #0005 Implement translucent poly sorting
Implement quick-and-dirty sorting based on min-z. It's not remotely complete
but damn that looks so much better ^_^
src/Makefile.am
src/Makefile.in
src/pvr2/pvr2.h
src/pvr2/rendcore.c
src/pvr2/render.c
src/pvr2/rendsort.c
1.1 --- a/src/Makefile.am Tue Sep 12 08:38:38 2006 +0000
1.2 +++ b/src/Makefile.am Tue Sep 12 11:54:19 2006 +0000
1.3 @@ -22,7 +22,7 @@
1.4 aica/armcore.c aica/armcore.h aica/armdasm.c aica/armmem.c \
1.5 aica/aica.c aica/aica.h aica/audio.c aica/audio.h \
1.6 pvr2/pvr2.c pvr2/pvr2.h \
1.7 - pvr2/tacore.c pvr2/render.c pvr2/rendcore.c pvr2/rendbkg.c \
1.8 + pvr2/tacore.c pvr2/render.c pvr2/rendcore.c pvr2/rendbkg.c pvr2/rendsort.c \
1.9 pvr2/texcache.c \
1.10 maple/maple.c maple/maple.h \
1.11 maple/controller.c maple/controller.h \
2.1 --- a/src/Makefile.in Tue Sep 12 08:38:38 2006 +0000
2.2 +++ b/src/Makefile.in Tue Sep 12 11:54:19 2006 +0000
2.3 @@ -150,7 +150,7 @@
2.4 aica/armcore.c aica/armcore.h aica/armdasm.c aica/armmem.c \
2.5 aica/aica.c aica/aica.h aica/audio.c aica/audio.h \
2.6 pvr2/pvr2.c pvr2/pvr2.h \
2.7 - pvr2/tacore.c pvr2/render.c pvr2/rendcore.c pvr2/rendbkg.c \
2.8 + pvr2/tacore.c pvr2/render.c pvr2/rendcore.c pvr2/rendbkg.c pvr2/rendsort.c \
2.9 pvr2/texcache.c \
2.10 maple/maple.c maple/maple.h \
2.11 maple/controller.c maple/controller.h \
2.12 @@ -186,13 +186,13 @@
2.13 scif.$(OBJEXT) armcore.$(OBJEXT) armdasm.$(OBJEXT) \
2.14 armmem.$(OBJEXT) aica.$(OBJEXT) audio.$(OBJEXT) pvr2.$(OBJEXT) \
2.15 tacore.$(OBJEXT) render.$(OBJEXT) rendcore.$(OBJEXT) \
2.16 - rendbkg.$(OBJEXT) texcache.$(OBJEXT) maple.$(OBJEXT) \
2.17 - controller.$(OBJEXT) support.$(OBJEXT) interface.$(OBJEXT) \
2.18 - callbacks.$(OBJEXT) gui.$(OBJEXT) mmr_win.$(OBJEXT) \
2.19 - debug_win.$(OBJEXT) dump_win.$(OBJEXT) loader.$(OBJEXT) \
2.20 - bootstrap.$(OBJEXT) util.$(OBJEXT) display.$(OBJEXT) \
2.21 - audio_null.$(OBJEXT) audio_esd.$(OBJEXT) video_null.$(OBJEXT) \
2.22 - video_gtk.$(OBJEXT) video_x11.$(OBJEXT)
2.23 + rendbkg.$(OBJEXT) rendsort.$(OBJEXT) texcache.$(OBJEXT) \
2.24 + maple.$(OBJEXT) controller.$(OBJEXT) support.$(OBJEXT) \
2.25 + interface.$(OBJEXT) callbacks.$(OBJEXT) gui.$(OBJEXT) \
2.26 + mmr_win.$(OBJEXT) debug_win.$(OBJEXT) dump_win.$(OBJEXT) \
2.27 + loader.$(OBJEXT) bootstrap.$(OBJEXT) util.$(OBJEXT) \
2.28 + display.$(OBJEXT) audio_null.$(OBJEXT) audio_esd.$(OBJEXT) \
2.29 + video_null.$(OBJEXT) video_gtk.$(OBJEXT) video_x11.$(OBJEXT)
2.30 lxdream_OBJECTS = $(am_lxdream_OBJECTS)
2.31 lxdream_DEPENDENCIES =
2.32 lxdream_LDFLAGS =
2.33 @@ -217,14 +217,14 @@
2.34 @AMDEP_TRUE@ ./$(DEPDIR)/mmr_win.Po ./$(DEPDIR)/nrg.Po \
2.35 @AMDEP_TRUE@ ./$(DEPDIR)/pvr2.Po ./$(DEPDIR)/rendbkg.Po \
2.36 @AMDEP_TRUE@ ./$(DEPDIR)/rendcore.Po ./$(DEPDIR)/render.Po \
2.37 -@AMDEP_TRUE@ ./$(DEPDIR)/scif.Po ./$(DEPDIR)/sh4core.Po \
2.38 -@AMDEP_TRUE@ ./$(DEPDIR)/sh4dasm.Po ./$(DEPDIR)/sh4mem.Po \
2.39 -@AMDEP_TRUE@ ./$(DEPDIR)/sh4mmio.Po ./$(DEPDIR)/support.Po \
2.40 -@AMDEP_TRUE@ ./$(DEPDIR)/syscall.Po ./$(DEPDIR)/tacore.Po \
2.41 -@AMDEP_TRUE@ ./$(DEPDIR)/texcache.Po ./$(DEPDIR)/timer.Po \
2.42 -@AMDEP_TRUE@ ./$(DEPDIR)/util.Po ./$(DEPDIR)/video_gtk.Po \
2.43 -@AMDEP_TRUE@ ./$(DEPDIR)/video_null.Po ./$(DEPDIR)/video_x11.Po \
2.44 -@AMDEP_TRUE@ ./$(DEPDIR)/watch.Po
2.45 +@AMDEP_TRUE@ ./$(DEPDIR)/rendsort.Po ./$(DEPDIR)/scif.Po \
2.46 +@AMDEP_TRUE@ ./$(DEPDIR)/sh4core.Po ./$(DEPDIR)/sh4dasm.Po \
2.47 +@AMDEP_TRUE@ ./$(DEPDIR)/sh4mem.Po ./$(DEPDIR)/sh4mmio.Po \
2.48 +@AMDEP_TRUE@ ./$(DEPDIR)/support.Po ./$(DEPDIR)/syscall.Po \
2.49 +@AMDEP_TRUE@ ./$(DEPDIR)/tacore.Po ./$(DEPDIR)/texcache.Po \
2.50 +@AMDEP_TRUE@ ./$(DEPDIR)/timer.Po ./$(DEPDIR)/util.Po \
2.51 +@AMDEP_TRUE@ ./$(DEPDIR)/video_gtk.Po ./$(DEPDIR)/video_null.Po \
2.52 +@AMDEP_TRUE@ ./$(DEPDIR)/video_x11.Po ./$(DEPDIR)/watch.Po
2.53 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
2.54 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
2.55 CCLD = $(CC)
2.56 @@ -310,6 +310,7 @@
2.57 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rendbkg.Po@am__quote@
2.58 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rendcore.Po@am__quote@
2.59 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/render.Po@am__quote@
2.60 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rendsort.Po@am__quote@
2.61 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scif.Po@am__quote@
2.62 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4core.Po@am__quote@
2.63 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4dasm.Po@am__quote@
2.64 @@ -832,6 +833,28 @@
2.65 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.66 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rendbkg.obj `if test -f 'pvr2/rendbkg.c'; then $(CYGPATH_W) 'pvr2/rendbkg.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/rendbkg.c'; fi`
2.67
2.68 +rendsort.o: pvr2/rendsort.c
2.69 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rendsort.o -MD -MP -MF "$(DEPDIR)/rendsort.Tpo" \
2.70 +@am__fastdepCC_TRUE@ -c -o rendsort.o `test -f 'pvr2/rendsort.c' || echo '$(srcdir)/'`pvr2/rendsort.c; \
2.71 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/rendsort.Tpo" "$(DEPDIR)/rendsort.Po"; \
2.72 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/rendsort.Tpo"; exit 1; \
2.73 +@am__fastdepCC_TRUE@ fi
2.74 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/rendsort.c' object='rendsort.o' libtool=no @AMDEPBACKSLASH@
2.75 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/rendsort.Po' tmpdepfile='$(DEPDIR)/rendsort.TPo' @AMDEPBACKSLASH@
2.76 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.77 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rendsort.o `test -f 'pvr2/rendsort.c' || echo '$(srcdir)/'`pvr2/rendsort.c
2.78 +
2.79 +rendsort.obj: pvr2/rendsort.c
2.80 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rendsort.obj -MD -MP -MF "$(DEPDIR)/rendsort.Tpo" \
2.81 +@am__fastdepCC_TRUE@ -c -o rendsort.obj `if test -f 'pvr2/rendsort.c'; then $(CYGPATH_W) 'pvr2/rendsort.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/rendsort.c'; fi`; \
2.82 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/rendsort.Tpo" "$(DEPDIR)/rendsort.Po"; \
2.83 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/rendsort.Tpo"; exit 1; \
2.84 +@am__fastdepCC_TRUE@ fi
2.85 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/rendsort.c' object='rendsort.obj' libtool=no @AMDEPBACKSLASH@
2.86 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/rendsort.Po' tmpdepfile='$(DEPDIR)/rendsort.TPo' @AMDEPBACKSLASH@
2.87 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.88 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rendsort.obj `if test -f 'pvr2/rendsort.c'; then $(CYGPATH_W) 'pvr2/rendsort.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/rendsort.c'; fi`
2.89 +
2.90 texcache.o: pvr2/texcache.c
2.91 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT texcache.o -MD -MP -MF "$(DEPDIR)/texcache.Tpo" \
2.92 @am__fastdepCC_TRUE@ -c -o texcache.o `test -f 'pvr2/texcache.c' || echo '$(srcdir)/'`pvr2/texcache.c; \
3.1 --- a/src/pvr2/pvr2.h Tue Sep 12 08:38:38 2006 +0000
3.2 +++ b/src/pvr2/pvr2.h Tue Sep 12 11:54:19 2006 +0000
3.3 @@ -1,5 +1,5 @@
3.4 /**
3.5 - * $Id: pvr2.h,v 1.17 2006-09-12 08:38:38 nkeynes Exp $
3.6 + * $Id: pvr2.h,v 1.18 2006-09-12 11:54:19 nkeynes Exp $
3.7 *
3.8 * PVR2 (video chip) functions and macros.
3.9 *
3.10 @@ -56,6 +56,11 @@
3.11 #define PVR2_RAM_PAGES (PVR2_RAM_SIZE>>12)
3.12 #define PVR2_RAM_MASK 0x7FFFFF
3.13
3.14 +#define RENDER_ZONLY 0
3.15 +#define RENDER_NORMAL 1 /* Render non-modified polygons */
3.16 +#define RENDER_CHEAPMOD 2 /* Render cheap-modified polygons */
3.17 +#define RENDER_FULLMOD 3 /* Render the fully-modified version of the polygons */
3.18 +
3.19 void pvr2_next_frame( void );
3.20 void pvr2_set_base_address( uint32_t );
3.21 int pvr2_get_frame_count( void );
4.1 --- a/src/pvr2/rendcore.c Tue Sep 12 08:38:38 2006 +0000
4.2 +++ b/src/pvr2/rendcore.c Tue Sep 12 11:54:19 2006 +0000
4.3 @@ -1,5 +1,5 @@
4.4 /**
4.5 - * $Id: rendcore.c,v 1.4 2006-09-12 08:38:38 nkeynes Exp $
4.6 + * $Id: rendcore.c,v 1.5 2006-09-12 11:54:19 nkeynes Exp $
4.7 *
4.8 * PVR2 renderer core.
4.9 *
4.10 @@ -37,11 +37,6 @@
4.11 COLFMT_RGB888, COLFMT_ARGB8888, COLFMT_ARGB8888, COLFMT_ARGB4444 };
4.12
4.13
4.14 -#define RENDER_ZONLY 0
4.15 -#define RENDER_NORMAL 1 /* Render non-modified polygons */
4.16 -#define RENDER_CHEAPMOD 2 /* Render cheap-modified polygons */
4.17 -#define RENDER_FULLMOD 3 /* Render the fully-modified version of the polygons */
4.18 -
4.19 #define CULL_NONE 0
4.20 #define CULL_SMALL 1
4.21 #define CULL_CCW 2
4.22 @@ -246,11 +241,6 @@
4.23 } while( 1 );
4.24 }
4.25
4.26 -void render_autosort_tile( pvraddr_t tile_entry, int render_mode, gboolean cheap_modifier_mode ) {
4.27 - //WARN( "Autosort not implemented yet" );
4.28 - render_tile( tile_entry, render_mode, cheap_modifier_mode );
4.29 -}
4.30 -
4.31 void pvr2_render_tilebuffer( int width, int height, int clipx1, int clipy1,
4.32 int clipx2, int clipy2 ) {
4.33
4.34 @@ -262,7 +252,7 @@
4.35 int isp_config = MMIO_READ( PVR2, RENDER_ISPCFG );
4.36 int shadow_cfg = MMIO_READ( PVR2, RENDER_SHADOW );
4.37
4.38 - if( obj_config & 0x00200000 ) {
4.39 + if( (obj_config & 0x00200000) == 0 ) {
4.40 if( isp_config & 1 ) {
4.41 tile_sort = 0;
4.42 } else {
4.43 @@ -314,7 +304,8 @@
4.44 if( (segment->transmod_ptr & NO_POINTER) == 0 ) {
4.45 /* TODO */
4.46 }
4.47 - if( tile_sort == 2 || (tile_sort == 1 && (segment->control & SEGMENT_SORT_TRANS)) ) {
4.48 + if( tile_sort == 2 ||
4.49 + (tile_sort == 1 && ((segment->control & SEGMENT_SORT_TRANS)==0)) ) {
4.50 render_autosort_tile( segment->trans_ptr, RENDER_NORMAL, cheap_shadow );
4.51 } else {
4.52 render_tile( segment->trans_ptr, RENDER_NORMAL, cheap_shadow );
5.1 --- a/src/pvr2/render.c Tue Sep 12 08:38:38 2006 +0000
5.2 +++ b/src/pvr2/render.c Tue Sep 12 11:54:19 2006 +0000
5.3 @@ -1,5 +1,5 @@
5.4 /**
5.5 - * $Id: render.c,v 1.14 2006-09-12 08:38:38 nkeynes Exp $
5.6 + * $Id: render.c,v 1.15 2006-09-12 11:54:19 nkeynes Exp $
5.7 *
5.8 * PVR2 Renderer support. This part is primarily
5.9 *
5.10 @@ -213,10 +213,6 @@
5.11 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
5.12 }
5.13
5.14 -
5.15 -#define MIN3( a,b,c ) ((a) < (b) ? ( (a) < (c) ? (a) : (c) ) : ((b) < (c) ? (b) : (c)) )
5.16 -#define MAX3( a,b,c ) ((a) > (b) ? ( (a) > (c) ? (a) : (c) ) : ((b) > (c) ? (b) : (c)) )
5.17 -
5.18 /**
5.19 * Render a complete scene into the OpenGL back buffer.
5.20 * Note: this will probably need to be broken up eventually once timings are
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/src/pvr2/rendsort.c Tue Sep 12 11:54:19 2006 +0000
6.3 @@ -0,0 +1,243 @@
6.4 +/**
6.5 + * $Id: rendsort.c,v 1.1 2006-09-12 11:54:19 nkeynes Exp $
6.6 + *
6.7 + * PVR2 renderer routines for depth sorted polygons
6.8 + *
6.9 + * Copyright (c) 2005 Nathan Keynes.
6.10 + *
6.11 + * This program is free software; you can redistribute it and/or modify
6.12 + * it under the terms of the GNU General Public License as published by
6.13 + * the Free Software Foundation; either version 2 of the License, or
6.14 + * (at your option) any later version.
6.15 + *
6.16 + * This program is distributed in the hope that it will be useful,
6.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.19 + * GNU General Public License for more details.
6.20 + */
6.21 +#include <sys/time.h>
6.22 +#include "pvr2/pvr2.h"
6.23 +#include "asic.h"
6.24 +
6.25 +extern char *video_base;
6.26 +
6.27 +#define MIN3( a,b,c ) ((a) < (b) ? ( (a) < (c) ? (a) : (c) ) : ((b) < (c) ? (b) : (c)) )
6.28 +#define MAX3( a,b,c ) ((a) > (b) ? ( (a) > (c) ? (a) : (c) ) : ((b) > (c) ? (b) : (c)) )
6.29 +
6.30 +struct pvr_vertex {
6.31 + float x,y,z;
6.32 + uint32_t detail[1];
6.33 +};
6.34 +
6.35 +struct render_triangle {
6.36 + uint32_t *polygon;
6.37 + int vertex_length;
6.38 + float minx,miny,minz;
6.39 + float maxx,maxy,maxz;
6.40 + float *vertexes[3];
6.41 +};
6.42 +
6.43 +/**
6.44 + * Count the number of triangles in the list starting at the given
6.45 + * pvr memory address.
6.46 + */
6.47 +int render_count_triangles( pvraddr_t tile_entry ) {
6.48 + uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);
6.49 + int count = 0;
6.50 + while(1) {
6.51 + uint32_t entry = *tile_list++;
6.52 + if( entry >> 28 == 0x0F ) {
6.53 + break;
6.54 + } else if( entry >> 28 == 0x0E ) {
6.55 + tile_list = (uint32_t *)(video_base+(entry&0x007FFFFF));
6.56 + } else if( entry >> 29 == 0x04 ) { /* Triangle array */
6.57 + count += ((entry >> 25) & 0x0F)+1;
6.58 + } else if( entry >> 29 == 0x05 ) { /* Quad array */
6.59 + count += ((((entry >> 25) & 0x0F)+1)<<1);
6.60 + } else { /* Polygon */
6.61 + int i;
6.62 + for( i=0; i<6; i++ ) {
6.63 + if( entry & (0x40000000>>i) ) {
6.64 + count++;
6.65 + }
6.66 + }
6.67 + }
6.68 + }
6.69 + return count;
6.70 +}
6.71 +
6.72 +static void compute_triangle_boxes( struct render_triangle *triangle, int num_triangles )
6.73 +{
6.74 + int i;
6.75 + for( i=0; i<num_triangles; i++ ) {
6.76 + triangle[i].minx = MIN3(triangle[i].vertexes[0][0],triangle[i].vertexes[1][0],triangle[i].vertexes[2][0]);
6.77 + triangle[i].maxx = MAX3(triangle[i].vertexes[0][0],triangle[i].vertexes[1][0],triangle[i].vertexes[2][0]);
6.78 + triangle[i].miny = MIN3(triangle[i].vertexes[0][1],triangle[i].vertexes[1][1],triangle[i].vertexes[2][1]);
6.79 + triangle[i].maxy = MAX3(triangle[i].vertexes[0][1],triangle[i].vertexes[1][1],triangle[i].vertexes[2][1]);
6.80 + triangle[i].minz = MIN3(triangle[i].vertexes[0][2],triangle[i].vertexes[1][2],triangle[i].vertexes[2][2]);
6.81 + triangle[i].maxz = MAX3(triangle[i].vertexes[0][2],triangle[i].vertexes[1][2],triangle[i].vertexes[2][2]);
6.82 + }
6.83 +}
6.84 +
6.85 +void render_extract_triangles( pvraddr_t tile_entry, gboolean cheap_modifier_mode,
6.86 + struct render_triangle *triangles )
6.87 +{
6.88 + uint32_t poly_bank = MMIO_READ(PVR2,RENDER_POLYBASE);
6.89 + uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);
6.90 + int count = 0;
6.91 + while(1) {
6.92 + uint32_t entry = *tile_list++;
6.93 + if( entry >> 28 == 0x0F ) {
6.94 + break;
6.95 + } else if( entry >> 28 == 0x0E ) {
6.96 + tile_list = (uint32_t *)(video_base+(entry&0x007FFFFF));
6.97 + } else {
6.98 + uint32_t *polygon = (uint32_t *)(video_base + poly_bank + ((entry & 0x000FFFFF) << 2));
6.99 + int is_modified = entry & 0x01000000;
6.100 + int vertex_length = (entry >> 21) & 0x07;
6.101 + int context_length = 3;
6.102 + if( is_modified && !cheap_modifier_mode ) {
6.103 + context_length = 5;
6.104 + vertex_length *= 2 ;
6.105 + }
6.106 + vertex_length += 3;
6.107 +
6.108 + if( (entry & 0xE0000000) == 0x80000000 ) {
6.109 + /* Triangle(s) */
6.110 + int strip_count = ((entry >> 25) & 0x0F)+1;
6.111 + int polygon_length = 3 * vertex_length + context_length;
6.112 + int i;
6.113 + for( i=0; i<strip_count; i++ ) {
6.114 + float *vertex = (float *)(polygon+context_length);
6.115 + triangles[count].polygon = polygon;
6.116 + triangles[count].vertex_length = vertex_length;
6.117 + triangles[count].vertexes[0] = vertex;
6.118 + vertex+=vertex_length;
6.119 + triangles[count].vertexes[1] = vertex;
6.120 + vertex+=vertex_length;
6.121 + triangles[count].vertexes[2] = vertex;
6.122 + polygon += polygon_length;
6.123 + count++;
6.124 + }
6.125 + } else if( (entry & 0xE0000000) == 0xA0000000 ) {
6.126 + /* Sprite(s) */
6.127 + int strip_count = (entry >> 25) & 0x0F;
6.128 + int polygon_length = 4 * vertex_length + context_length;
6.129 + int i;
6.130 + for( i=0; i<strip_count; i++ ) {
6.131 + float *vertex = (float *)(polygon+context_length);
6.132 + triangles[count].polygon = polygon;
6.133 + triangles[count].vertex_length = vertex_length;
6.134 + triangles[count].vertexes[0] = vertex;
6.135 + vertex+=vertex_length;
6.136 + triangles[count].vertexes[1] = vertex;
6.137 + vertex+=vertex_length;
6.138 + triangles[count].vertexes[2] = vertex;
6.139 + count++;
6.140 + /* Preserve face direction */
6.141 + triangles[count].polygon = polygon;
6.142 + triangles[count].vertex_length = vertex_length;
6.143 + triangles[count].vertexes[0] = vertex;
6.144 + triangles[count].vertexes[1] = vertex - vertex_length;
6.145 + triangles[count].vertexes[2] = vertex + vertex_length;
6.146 + count++;
6.147 + polygon += polygon_length;
6.148 + }
6.149 + } else {
6.150 + /* Polygon */
6.151 + int i, first=-1, last = -1;
6.152 + float *vertex = (float *)polygon+context_length;
6.153 + for( i=0; i<6; i++ ) {
6.154 + if( entry & (0x40000000>>i) ) {
6.155 + triangles[count].polygon = polygon;
6.156 + triangles[count].vertex_length = vertex_length;
6.157 + if( i&1 ) {
6.158 + triangles[count].vertexes[0] = vertex + vertex_length;
6.159 + triangles[count].vertexes[1] = vertex;
6.160 + triangles[count].vertexes[2] = vertex + (vertex_length<<1);
6.161 + } else {
6.162 + triangles[count].vertexes[0] = vertex;
6.163 + triangles[count].vertexes[1] = vertex + vertex_length;
6.164 + triangles[count].vertexes[2] = vertex + (vertex_length<<1);
6.165 + }
6.166 + count++;
6.167 + }
6.168 + vertex += vertex_length;
6.169 + }
6.170 + }
6.171 + }
6.172 + }
6.173 +}
6.174 +
6.175 +void render_triangles( struct render_triangle *triangles, int num_triangles,
6.176 + int render_mode )
6.177 +{
6.178 + int i,j, m = 0;
6.179 + for( i=0; i<num_triangles; i++ ) {
6.180 + render_set_context( triangles[i].polygon, render_mode );
6.181 + if( render_mode == RENDER_FULLMOD ) {
6.182 + m = (triangles[i].vertex_length - 3)/2;
6.183 + }
6.184 +
6.185 + glBegin( GL_TRIANGLE_STRIP );
6.186 +
6.187 + for( j=0; j<3; j++ ) {
6.188 + uint32_t *vertexes = (uint32_t *)triangles[i].vertexes[j];
6.189 + float *vertexf = (float *)vertexes;
6.190 + uint32_t argb;
6.191 + if( POLY1_TEXTURED(*triangles[i].polygon) ) {
6.192 + if( POLY1_UV16(*triangles[i].polygon) ) {
6.193 + glTexCoord2f( halftofloat(vertexes[m+3]>>16),
6.194 + halftofloat(vertexes[m+3]) );
6.195 + argb = vertexes[m+4];
6.196 + } else {
6.197 + glTexCoord2f( vertexf[m+3], vertexf[m+4] );
6.198 + argb = vertexes[m+5];
6.199 + }
6.200 + } else {
6.201 + argb = vertexes[m+3];
6.202 + }
6.203 +
6.204 + glColor4ub( (GLubyte)(argb >> 16), (GLubyte)(argb >> 8),
6.205 + (GLubyte)argb, (GLubyte)(argb >> 24) );
6.206 + glVertex3f( vertexf[0], vertexf[1], vertexf[2] );
6.207 + }
6.208 + glEnd();
6.209 + }
6.210 +
6.211 +
6.212 +}
6.213 +
6.214 +int compare_triangles( void *a, void *b )
6.215 +{
6.216 + struct render_triangle *tri1 = a;
6.217 + struct render_triangle *tri2 = b;
6.218 + if( tri1->minz < tri2->minz ) {
6.219 + return -1;
6.220 + } else if( tri1->minz > tri2->minz ) {
6.221 + return 1;
6.222 + } else {
6.223 + return 0;
6.224 + }
6.225 +}
6.226 +
6.227 +void sort_triangles( struct render_triangle *triangles, int num_triangles )
6.228 +{
6.229 + qsort( triangles, num_triangles, sizeof(struct render_triangle), compare_triangles );
6.230 +}
6.231 +
6.232 +void render_autosort_tile( pvraddr_t tile_entry, int render_mode, gboolean cheap_modifier_mode )
6.233 +{
6.234 + int num_triangles = render_count_triangles(tile_entry);
6.235 + if( num_triangles == 0 ) {
6.236 + return; /* nothing to do */
6.237 + } else if( num_triangles == 1 ) { /* Triangle can hardly overlap with itself */
6.238 + render_tile( tile_entry, render_mode, cheap_modifier_mode );
6.239 + } else { /* Ooh boy here we go... */
6.240 + struct render_triangle triangles[num_triangles];
6.241 + render_extract_triangles(tile_entry, cheap_modifier_mode, triangles);
6.242 + compute_triangle_boxes(triangles, num_triangles);
6.243 + sort_triangles( triangles, num_triangles );
6.244 + render_triangles(triangles, num_triangles, render_mode);
6.245 + }
6.246 +}
.