Search
lxdream.org :: lxdream/src/pvr2/scene.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/scene.c
changeset 687:6bdc2b7032ea
prev677:3ee62740ff8f
next690:1e8fd13a67ef
author nkeynes
date Sat Jun 14 11:54:15 2008 +0000 (12 years ago)
permissions -rw-r--r--
last change Change colour params to float
Convert background processing over to scene structure (fixes some depth issues as well)
Add color unclamp when supported
file annotate diff log raw
1.1 --- a/src/pvr2/scene.c Thu May 29 10:50:25 2008 +0000
1.2 +++ b/src/pvr2/scene.c Sat Jun 14 11:54:15 2008 +0000
1.3 @@ -27,6 +27,13 @@
1.4 #include "pvr2/glutil.h"
1.5 #include "pvr2/scene.h"
1.6
1.7 +static void unpack_bgra(uint32_t bgra, float *rgba)
1.8 +{
1.9 + rgba[0] = ((float)(((bgra&0x00FF0000)>>16) + 1)) / 256.0;
1.10 + rgba[1] = ((float)(((bgra&0x0000FF00)>>8) + 1)) / 256.0;
1.11 + rgba[2] = ((float)((bgra&0x000000FF) + 1)) / 256.0;
1.12 + rgba[3] = ((float)(((bgra&0xFF000000)>>24) + 1)) / 256.0;
1.13 +}
1.14
1.15 static inline uint32_t bgra_to_rgba(uint32_t bgra)
1.16 {
1.17 @@ -117,7 +124,8 @@
1.18 void *vertex_buffer_map()
1.19 {
1.20 glGetError();
1.21 - uint32_t size = pvr2_scene.vertex_count * sizeof(struct vertex_struct);
1.22 + // Allow 8 vertexes for the background (4+4)
1.23 + uint32_t size = (pvr2_scene.vertex_count + 8) * sizeof(struct vertex_struct);
1.24 #ifdef ENABLE_VERTEX_BUFFER
1.25 if( vbo_supported ) {
1.26 glBindBufferARB( GL_ARRAY_BUFFER_ARB, pvr2_scene.vbo_id );
1.27 @@ -158,26 +166,26 @@
1.28 }
1.29
1.30 static struct polygon_struct *scene_add_polygon( pvraddr_t poly_idx, int vertex_count,
1.31 - gboolean is_modified )
1.32 + gboolean is_modified )
1.33 {
1.34 int vert_mul = is_modified ? 2 : 1;
1.35
1.36 if( pvr2_scene.buf_to_poly_map[poly_idx] != NULL ) {
1.37 - if( vertex_count > pvr2_scene.buf_to_poly_map[poly_idx]->vertex_count ) {
1.38 - pvr2_scene.vertex_count += (vertex_count - pvr2_scene.buf_to_poly_map[poly_idx]->vertex_count) * vert_mul;
1.39 - pvr2_scene.buf_to_poly_map[poly_idx]->vertex_count = vertex_count;
1.40 - }
1.41 - return pvr2_scene.buf_to_poly_map[poly_idx];
1.42 + if( vertex_count > pvr2_scene.buf_to_poly_map[poly_idx]->vertex_count ) {
1.43 + pvr2_scene.vertex_count += (vertex_count - pvr2_scene.buf_to_poly_map[poly_idx]->vertex_count) * vert_mul;
1.44 + pvr2_scene.buf_to_poly_map[poly_idx]->vertex_count = vertex_count;
1.45 + }
1.46 + return pvr2_scene.buf_to_poly_map[poly_idx];
1.47 } else {
1.48 - struct polygon_struct *poly = &pvr2_scene.poly_array[pvr2_scene.poly_count++];
1.49 - poly->context = (uint32_t *)(video_base + MMIO_READ(PVR2,RENDER_POLYBASE) + (poly_idx<<2));
1.50 - poly->vertex_count = vertex_count;
1.51 - poly->vertex_index = -1;
1.52 - poly->mod_vertex_index = -1;
1.53 - poly->next = NULL;
1.54 - pvr2_scene.buf_to_poly_map[poly_idx] = poly;
1.55 - pvr2_scene.vertex_count += (vertex_count * vert_mul);
1.56 - return poly;
1.57 + struct polygon_struct *poly = &pvr2_scene.poly_array[pvr2_scene.poly_count++];
1.58 + poly->context = &pvr2_scene.pvr2_pbuf[poly_idx];
1.59 + poly->vertex_count = vertex_count;
1.60 + poly->vertex_index = -1;
1.61 + poly->mod_vertex_index = -1;
1.62 + poly->next = NULL;
1.63 + pvr2_scene.buf_to_poly_map[poly_idx] = poly;
1.64 + pvr2_scene.vertex_count += (vertex_count * vert_mul);
1.65 + return poly;
1.66 }
1.67 }
1.68
1.69 @@ -197,69 +205,70 @@
1.70 {
1.71 gboolean force_alpha = !POLY2_ALPHA_ENABLE(poly2);
1.72 union pvr2_data_type {
1.73 - uint32_t *ival;
1.74 - float *fval;
1.75 + uint32_t *ival;
1.76 + float *fval;
1.77 } data;
1.78
1.79 data.ival = pvr2_data;
1.80 -
1.81 +
1.82 vert->x = *data.fval++;
1.83 vert->y = *data.fval++;
1.84
1.85 float z = *data.fval++;
1.86 if( !isfinite(z) ) {
1.87 - z = 0;
1.88 + z = 0;
1.89 } else if( z != 0 ) {
1.90 - z = 1/z;
1.91 + z = 1/z;
1.92 }
1.93 if( z > pvr2_scene.bounds[5] ) {
1.94 - pvr2_scene.bounds[5] = z;
1.95 + pvr2_scene.bounds[5] = z;
1.96 } else if( z < pvr2_scene.bounds[4] && z != 0 ) {
1.97 - pvr2_scene.bounds[4] = z;
1.98 + pvr2_scene.bounds[4] = z;
1.99 }
1.100 vert->z = z;
1.101 data.ival += modify_offset;
1.102
1.103 -
1.104 +
1.105 if( POLY1_TEXTURED(poly1) ) {
1.106 - if( POLY1_UV16(poly1) ) {
1.107 - vert->u = halftofloat( *data.ival>>16 );
1.108 - vert->v = halftofloat( *data.ival );
1.109 - data.ival++;
1.110 - } else {
1.111 - vert->u = *data.fval++;
1.112 - vert->v = *data.fval++;
1.113 - }
1.114 - if( POLY2_TEX_BLEND(poly2) == 1 ) {
1.115 - force_alpha = TRUE;
1.116 - }
1.117 + if( POLY1_UV16(poly1) ) {
1.118 + vert->u = halftofloat( *data.ival>>16 );
1.119 + vert->v = halftofloat( *data.ival );
1.120 + data.ival++;
1.121 + } else {
1.122 + vert->u = *data.fval++;
1.123 + vert->v = *data.fval++;
1.124 + }
1.125 + if( POLY2_TEX_BLEND(poly2) == 1 ) {
1.126 + force_alpha = TRUE;
1.127 + }
1.128 }
1.129 + unpack_bgra(*data.ival++, vert->rgba);
1.130 + if( POLY1_SPECULAR(poly1) ) {
1.131 + unpack_bgra(*data.ival++, vert->offset_rgba);
1.132 + vert->offset_rgba[3] = 1.0;
1.133 + } else {
1.134 + vert->offset_rgba[0] = 0.0;
1.135 + vert->offset_rgba[1] = 0.0;
1.136 + vert->offset_rgba[2] = 0.0;
1.137 + vert->offset_rgba[3] = 0.0;
1.138 + }
1.139 +
1.140 if( force_alpha ) {
1.141 - vert->rgba = bgra_to_rgba((*data.ival++) | 0xFF000000);
1.142 - if( POLY1_SPECULAR(poly1) ) {
1.143 - vert->offset_rgba = bgra_to_rgba((*data.ival++) | 0xFF000000);
1.144 - } else {
1.145 - vert->offset_rgba = 0;
1.146 - }
1.147 - } else {
1.148 - vert->rgba = bgra_to_rgba(*data.ival++);
1.149 - if( POLY1_SPECULAR(poly1) ) {
1.150 - vert->offset_rgba = bgra_to_rgba(*data.ival++);
1.151 - } else {
1.152 - vert->offset_rgba = 0;
1.153 - }
1.154 + vert->rgba[3] = 1.0;
1.155 + vert->offset_rgba[3] = 1.0;
1.156 }
1.157 }
1.158
1.159 /**
1.160 - * Compute texture, colour, and z values for a result point by interpolating from
1.161 - * a set of 3 input points. The result point must define its x,y.
1.162 + * Compute texture, colour, and z values for 1 or more result points by interpolating from
1.163 + * a set of 3 input points. The result point(s) must define their x,y.
1.164 */
1.165 -static void scene_compute_vertex( struct vertex_struct *result,
1.166 - struct vertex_struct *input,
1.167 - gboolean is_solid_shaded )
1.168 +static void scene_compute_vertexes( struct vertex_struct *result,
1.169 + int result_count,
1.170 + struct vertex_struct *input,
1.171 + gboolean is_solid_shaded )
1.172 {
1.173 - int i;
1.174 + int i,j;
1.175 float sx = input[2].x - input[1].x;
1.176 float sy = input[2].y - input[1].y;
1.177 float tx = input[0].x - input[1].x;
1.178 @@ -267,18 +276,18 @@
1.179
1.180 float detxy = ((sy) * (tx)) - ((ty) * (sx));
1.181 if( detxy == 0 ) {
1.182 - result->z = input[2].z;
1.183 - result->u = input[2].u;
1.184 - result->v = input[2].v;
1.185 - result->rgba = input[2].rgba;
1.186 - result->offset_rgba = input[2].offset_rgba;
1.187 - return;
1.188 + // If the input points fall on a line, they don't define a usable
1.189 + // polygon - the PVR2 takes the last input point as the result in
1.190 + // this case.
1.191 + for( i=0; i<result_count; i++ ) {
1.192 + float x = result[i].x;
1.193 + float y = result[i].y;
1.194 + memcpy( &result[i], &input[2], sizeof(struct vertex_struct) );
1.195 + result[i].x = x;
1.196 + result[i].y = y;
1.197 + }
1.198 + return;
1.199 }
1.200 - float t = ((result->x - input[1].x) * sy -
1.201 - (result->y - input[1].y) * sx) / detxy;
1.202 - float s = ((result->y - input[1].y) * tx -
1.203 - (result->x - input[1].x) * ty) / detxy;
1.204 -
1.205 float sz = input[2].z - input[1].z;
1.206 float tz = input[0].z - input[1].z;
1.207 float su = input[2].u - input[1].u;
1.208 @@ -286,41 +295,42 @@
1.209 float sv = input[2].v - input[1].v;
1.210 float tv = input[0].v - input[1].v;
1.211
1.212 - float rz = input[1].z + (t*tz) + (s*sz);
1.213 - if( rz > pvr2_scene.bounds[5] ) {
1.214 - pvr2_scene.bounds[5] = rz;
1.215 - } else if( rz < pvr2_scene.bounds[4] ) {
1.216 - pvr2_scene.bounds[4] = rz;
1.217 + for( i=0; i<result_count; i++ ) {
1.218 + float t = ((result[i].x - input[1].x) * sy -
1.219 + (result[i].y - input[1].y) * sx) / detxy;
1.220 + float s = ((result[i].y - input[1].y) * tx -
1.221 + (result[i].x - input[1].x) * ty) / detxy;
1.222 +
1.223 + float rz = input[1].z + (t*tz) + (s*sz);
1.224 + if( rz > pvr2_scene.bounds[5] ) {
1.225 + pvr2_scene.bounds[5] = rz;
1.226 + } else if( rz < pvr2_scene.bounds[4] ) {
1.227 + pvr2_scene.bounds[4] = rz;
1.228 + }
1.229 + result[i].z = rz;
1.230 + result[i].u = input[1].u + (t*tu) + (s*su);
1.231 + result[i].v = input[1].v + (t*tv) + (s*sv);
1.232 +
1.233 + if( is_solid_shaded ) {
1.234 + memcpy( result->rgba, input[2].rgba, sizeof(result->rgba) );
1.235 + memcpy( result->offset_rgba, input[2].offset_rgba, sizeof(result->offset_rgba) );
1.236 + } else {
1.237 + float *rgba0 = input[0].rgba;
1.238 + float *rgba1 = input[1].rgba;
1.239 + float *rgba2 = input[2].rgba;
1.240 + float *rgba3 = result[i].rgba;
1.241 + for( j=0; j<8; j++ ) {
1.242 + float tc = *rgba0++ - *rgba1;
1.243 + float sc = *rgba2++ - *rgba1;
1.244 + float rc = *rgba1++ + (t*tc) + (s*sc);
1.245 + *rgba3++ = rc;
1.246 + }
1.247 + }
1.248 }
1.249 - result->z = rz;
1.250 - result->u = input[1].u + (t*tu) + (s*su);
1.251 - result->v = input[1].v + (t*tv) + (s*sv);
1.252 -
1.253 - if( is_solid_shaded ) {
1.254 - result->rgba = input[2].rgba;
1.255 - result->offset_rgba = input[2].offset_rgba;
1.256 - } else {
1.257 - uint8_t *rgba0 = (uint8_t *)&input[0].rgba;
1.258 - uint8_t *rgba1 = (uint8_t *)&input[1].rgba;
1.259 - uint8_t *rgba2 = (uint8_t *)&input[2].rgba;
1.260 - uint8_t *rgba3 = (uint8_t *)&result->rgba;
1.261 - for( i=0; i<8; i++ ) { // note: depends on rgba & offset_rgba being adjacent
1.262 - float tc = *rgba0++ - *rgba1;
1.263 - float sc = *rgba2++ - *rgba1;
1.264 - float rc = *rgba1++ + (t*tc) + (s*sc);
1.265 - if( rc < 0 ) {
1.266 - rc = 0;
1.267 - } else if( rc > 255 ) {
1.268 - rc = 255;
1.269 - }
1.270 - *rgba3++ = rc;
1.271 - }
1.272 - }
1.273 -
1.274 }
1.275
1.276 static void scene_add_vertexes( pvraddr_t poly_idx, int vertex_length,
1.277 - gboolean is_modified )
1.278 + gboolean is_modified )
1.279 {
1.280 struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[poly_idx];
1.281 uint32_t *ptr = &pvr2_scene.pvr2_pbuf[poly_idx];
1.282 @@ -328,25 +338,25 @@
1.283 unsigned int i;
1.284
1.285 if( poly->vertex_index == -1 ) {
1.286 - ptr += (is_modified ? 5 : 3 );
1.287 - poly->vertex_index = pvr2_scene.vertex_index;
1.288 -
1.289 - assert( poly != NULL );
1.290 - assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );
1.291 - for( i=0; i<poly->vertex_count; i++ ) {
1.292 - pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], context[1], ptr, 0 );
1.293 - ptr += vertex_length;
1.294 - }
1.295 - if( is_modified ) {
1.296 - int mod_offset = (vertex_length - 3)>>1;
1.297 - assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );
1.298 - ptr = &pvr2_scene.pvr2_pbuf[poly_idx] + 5;
1.299 - poly->mod_vertex_index = pvr2_scene.vertex_index;
1.300 - for( i=0; i<poly->vertex_count; i++ ) {
1.301 - pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], context[3], ptr, mod_offset );
1.302 - ptr += vertex_length;
1.303 - }
1.304 - }
1.305 + ptr += (is_modified ? 5 : 3 );
1.306 + poly->vertex_index = pvr2_scene.vertex_index;
1.307 +
1.308 + assert( poly != NULL );
1.309 + assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );
1.310 + for( i=0; i<poly->vertex_count; i++ ) {
1.311 + pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], context[1], ptr, 0 );
1.312 + ptr += vertex_length;
1.313 + }
1.314 + if( is_modified ) {
1.315 + int mod_offset = (vertex_length - 3)>>1;
1.316 + assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );
1.317 + ptr = &pvr2_scene.pvr2_pbuf[poly_idx] + 5;
1.318 + poly->mod_vertex_index = pvr2_scene.vertex_index;
1.319 + for( i=0; i<poly->vertex_count; i++ ) {
1.320 + pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], context[3], ptr, mod_offset );
1.321 + ptr += vertex_length;
1.322 + }
1.323 + }
1.324 }
1.325 }
1.326
1.327 @@ -372,7 +382,7 @@
1.328 pvr2_decode_render_vertex( &quad[i], context[0], context[1], ptr, 0 );
1.329 ptr += vertex_length;
1.330 }
1.331 - scene_compute_vertex( &quad[3], &quad[0], !POLY1_GOURAUD_SHADED(context[0]) );
1.332 + scene_compute_vertexes( &quad[3], 1, &quad[0], !POLY1_GOURAUD_SHADED(context[0]) );
1.333 // Swap last two vertexes (quad arrangement => tri strip arrangement)
1.334 memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index], quad, sizeof(struct vertex_struct)*2 );
1.335 memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index+2], &quad[3], sizeof(struct vertex_struct) );
1.336 @@ -380,7 +390,7 @@
1.337 pvr2_scene.vertex_index += 4;
1.338
1.339 if( is_modified ) {
1.340 - int mod_offset = (vertex_length - 3)>>1;
1.341 + int mod_offset = (vertex_length - 3)>>1;
1.342 assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );
1.343 ptr = &pvr2_scene.pvr2_pbuf[poly_idx] + 5;
1.344 poly->mod_vertex_index = pvr2_scene.vertex_index;
1.345 @@ -388,7 +398,7 @@
1.346 pvr2_decode_render_vertex( &quad[4], context[0], context[3], ptr, mod_offset );
1.347 ptr += vertex_length;
1.348 }
1.349 - scene_compute_vertex( &quad[3], &quad[0], !POLY1_GOURAUD_SHADED(context[0]) );
1.350 + scene_compute_vertexes( &quad[3], 1, &quad[0], !POLY1_GOURAUD_SHADED(context[0]) );
1.351 memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index], quad, sizeof(struct vertex_struct)*2 );
1.352 memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index+2], &quad[3], sizeof(struct vertex_struct) );
1.353 memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index+3], &quad[2], sizeof(struct vertex_struct) );
1.354 @@ -401,64 +411,64 @@
1.355 {
1.356 uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);
1.357 do {
1.358 - uint32_t entry = *tile_list++;
1.359 - if( entry >> 28 == 0x0F ) {
1.360 - break;
1.361 - } else if( entry >> 28 == 0x0E ) {
1.362 - tile_list = (uint32_t *)(video_base + (entry&0x007FFFFF));
1.363 - } else {
1.364 - pvraddr_t polyaddr = entry&0x000FFFFF;
1.365 - int is_modified = (entry & 0x01000000) && pvr2_scene.full_shadow;
1.366 - int vertex_length = (entry >> 21) & 0x07;
1.367 - int context_length = 3;
1.368 - if( is_modified ) {
1.369 - context_length = 5;
1.370 - vertex_length <<= 1 ;
1.371 - }
1.372 - vertex_length += 3;
1.373 -
1.374 - if( (entry & 0xE0000000) == 0x80000000 ) {
1.375 - /* Triangle(s) */
1.376 - int strip_count = ((entry >> 25) & 0x0F)+1;
1.377 - int polygon_length = 3 * vertex_length + context_length;
1.378 - int i;
1.379 - struct polygon_struct *last_poly = NULL;
1.380 - for( i=0; i<strip_count; i++ ) {
1.381 - struct polygon_struct *poly = scene_add_polygon( polyaddr, 3, is_modified );
1.382 - polyaddr += polygon_length;
1.383 - if( last_poly != NULL && last_poly->next == NULL ) {
1.384 - last_poly->next = poly;
1.385 - }
1.386 - last_poly = poly;
1.387 - }
1.388 - } else if( (entry & 0xE0000000) == 0xA0000000 ) {
1.389 - /* Sprite(s) */
1.390 - int strip_count = ((entry >> 25) & 0x0F)+1;
1.391 - int polygon_length = 4 * vertex_length + context_length;
1.392 - int i;
1.393 - struct polygon_struct *last_poly = NULL;
1.394 - for( i=0; i<strip_count; i++ ) {
1.395 - struct polygon_struct *poly = scene_add_polygon( polyaddr, 4, is_modified );
1.396 - polyaddr += polygon_length;
1.397 - if( last_poly != NULL && last_poly->next == NULL ) {
1.398 - last_poly->next = poly;
1.399 - }
1.400 - last_poly = poly;
1.401 - }
1.402 - } else {
1.403 - /* Polygon */
1.404 - int i, last = -1;
1.405 - for( i=5; i>=0; i-- ) {
1.406 - if( entry & (0x40000000>>i) ) {
1.407 - last = i;
1.408 - break;
1.409 - }
1.410 - }
1.411 - if( last != -1 ) {
1.412 - scene_add_polygon( polyaddr, last+3, is_modified );
1.413 - }
1.414 - }
1.415 - }
1.416 + uint32_t entry = *tile_list++;
1.417 + if( entry >> 28 == 0x0F ) {
1.418 + break;
1.419 + } else if( entry >> 28 == 0x0E ) {
1.420 + tile_list = (uint32_t *)(video_base + (entry&0x007FFFFF));
1.421 + } else {
1.422 + pvraddr_t polyaddr = entry&0x000FFFFF;
1.423 + int is_modified = (entry & 0x01000000) && pvr2_scene.full_shadow;
1.424 + int vertex_length = (entry >> 21) & 0x07;
1.425 + int context_length = 3;
1.426 + if( is_modified ) {
1.427 + context_length = 5;
1.428 + vertex_length <<= 1 ;
1.429 + }
1.430 + vertex_length += 3;
1.431 +
1.432 + if( (entry & 0xE0000000) == 0x80000000 ) {
1.433 + /* Triangle(s) */
1.434 + int strip_count = ((entry >> 25) & 0x0F)+1;
1.435 + int polygon_length = 3 * vertex_length + context_length;
1.436 + int i;
1.437 + struct polygon_struct *last_poly = NULL;
1.438 + for( i=0; i<strip_count; i++ ) {
1.439 + struct polygon_struct *poly = scene_add_polygon( polyaddr, 3, is_modified );
1.440 + polyaddr += polygon_length;
1.441 + if( last_poly != NULL && last_poly->next == NULL ) {
1.442 + last_poly->next = poly;
1.443 + }
1.444 + last_poly = poly;
1.445 + }
1.446 + } else if( (entry & 0xE0000000) == 0xA0000000 ) {
1.447 + /* Sprite(s) */
1.448 + int strip_count = ((entry >> 25) & 0x0F)+1;
1.449 + int polygon_length = 4 * vertex_length + context_length;
1.450 + int i;
1.451 + struct polygon_struct *last_poly = NULL;
1.452 + for( i=0; i<strip_count; i++ ) {
1.453 + struct polygon_struct *poly = scene_add_polygon( polyaddr, 4, is_modified );
1.454 + polyaddr += polygon_length;
1.455 + if( last_poly != NULL && last_poly->next == NULL ) {
1.456 + last_poly->next = poly;
1.457 + }
1.458 + last_poly = poly;
1.459 + }
1.460 + } else {
1.461 + /* Polygon */
1.462 + int i, last = -1;
1.463 + for( i=5; i>=0; i-- ) {
1.464 + if( entry & (0x40000000>>i) ) {
1.465 + last = i;
1.466 + break;
1.467 + }
1.468 + }
1.469 + if( last != -1 ) {
1.470 + scene_add_polygon( polyaddr, last+3, is_modified );
1.471 + }
1.472 + }
1.473 + }
1.474 } while( 1 );
1.475 }
1.476
1.477 @@ -517,6 +527,66 @@
1.478 } while( 1 );
1.479 }
1.480
1.481 +static void scene_extract_background( void )
1.482 +{
1.483 + uint32_t bgplane = MMIO_READ(PVR2, RENDER_BGPLANE);
1.484 + int vertex_length = (bgplane >> 24) & 0x07;
1.485 + int context_length = 3, i;
1.486 + int is_modified = (bgplane & 0x08000000) && pvr2_scene.full_shadow;
1.487 +
1.488 + struct polygon_struct *poly = &pvr2_scene.poly_array[pvr2_scene.poly_count++];
1.489 + uint32_t *context = &pvr2_scene.pvr2_pbuf[(bgplane & 0x00FFFFFF)>>3];
1.490 + poly->context = context;
1.491 + poly->vertex_count = 4;
1.492 + poly->vertex_index = pvr2_scene.vertex_count;
1.493 + if( is_modified ) {
1.494 + context_length = 5;
1.495 + vertex_length <<= 1;
1.496 + poly->mod_vertex_index = pvr2_scene.vertex_count + 4;
1.497 + pvr2_scene.vertex_count += 8;
1.498 + } else {
1.499 + poly->mod_vertex_index = -1;
1.500 + pvr2_scene.vertex_count += 4;
1.501 + }
1.502 + vertex_length += 3;
1.503 + context_length += (bgplane & 0x07) * vertex_length;
1.504 +
1.505 + poly->next = NULL;
1.506 + pvr2_scene.bkgnd_poly = poly;
1.507 +
1.508 + struct vertex_struct base_vertexes[3];
1.509 + uint32_t *ptr = context + context_length;
1.510 + for( i=0; i<3; i++ ) {
1.511 + pvr2_decode_render_vertex( &base_vertexes[i], context[0], context[1],
1.512 + ptr, 0 );
1.513 + ptr += vertex_length;
1.514 + }
1.515 + struct vertex_struct *result_vertexes = &pvr2_scene.vertex_array[poly->vertex_index];
1.516 + result_vertexes[0].x = result_vertexes[0].y = 0;
1.517 + result_vertexes[1].x = result_vertexes[3].x = pvr2_scene.buffer_width;
1.518 + result_vertexes[1].y = result_vertexes[2].x = 0;
1.519 + result_vertexes[2].y = result_vertexes[3].y = pvr2_scene.buffer_height;
1.520 + scene_compute_vertexes( result_vertexes, 4, base_vertexes, !POLY1_GOURAUD_SHADED(context[0]) );
1.521 +
1.522 + if( is_modified ) {
1.523 + int mod_offset = (vertex_length - 3)>>1;
1.524 + ptr = context + context_length;
1.525 + for( i=0; i<3; i++ ) {
1.526 + pvr2_decode_render_vertex( &base_vertexes[i], context[0], context[3],
1.527 + ptr, mod_offset );
1.528 + ptr += vertex_length;
1.529 + }
1.530 + result_vertexes = &pvr2_scene.vertex_array[poly->mod_vertex_index];
1.531 + result_vertexes[0].x = result_vertexes[0].y = 0;
1.532 + result_vertexes[1].x = result_vertexes[3].x = pvr2_scene.buffer_width;
1.533 + result_vertexes[1].y = result_vertexes[2].x = 0;
1.534 + result_vertexes[2].y = result_vertexes[3].y = pvr2_scene.buffer_height;
1.535 + scene_compute_vertexes( result_vertexes, 4, base_vertexes, !POLY1_GOURAUD_SHADED(context[0]) );
1.536 + }
1.537 +
1.538 +}
1.539 +
1.540 +
1.541 uint32_t pvr2_scene_buffer_width()
1.542 {
1.543 return pvr2_scene.buffer_width;
1.544 @@ -554,62 +624,63 @@
1.545 pvr2_scene.segment_list = (struct tile_segment *)tilebuffer;
1.546 pvr2_scene.pvr2_pbuf = (uint32_t *)(video_base + MMIO_READ(PVR2,RENDER_POLYBASE));
1.547 pvr2_scene.full_shadow = MMIO_READ( PVR2, RENDER_SHADOW ) & 0x100 ? FALSE : TRUE;
1.548 -
1.549 +
1.550 int max_tile_x = 0;
1.551 int max_tile_y = 0;
1.552 int obj_config = MMIO_READ( PVR2, RENDER_OBJCFG );
1.553 int isp_config = MMIO_READ( PVR2, RENDER_ISPCFG );
1.554
1.555 if( (obj_config & 0x00200000) == 0 ) {
1.556 - if( isp_config & 1 ) {
1.557 - pvr2_scene.sort_mode = SORT_NEVER;
1.558 - } else {
1.559 - pvr2_scene.sort_mode = SORT_ALWAYS;
1.560 - }
1.561 + if( isp_config & 1 ) {
1.562 + pvr2_scene.sort_mode = SORT_NEVER;
1.563 + } else {
1.564 + pvr2_scene.sort_mode = SORT_ALWAYS;
1.565 + }
1.566 } else {
1.567 - pvr2_scene.sort_mode = SORT_TILEFLAG;
1.568 + pvr2_scene.sort_mode = SORT_TILEFLAG;
1.569 }
1.570
1.571 // Pass 1: Extract polygon list
1.572 uint32_t control;
1.573 int i;
1.574 do {
1.575 - control = *segment++;
1.576 - int tile_x = SEGMENT_X(control);
1.577 - int tile_y = SEGMENT_Y(control);
1.578 - if( tile_x > max_tile_x ) {
1.579 - max_tile_x = tile_x;
1.580 - }
1.581 - if( tile_y > max_tile_y ) {
1.582 - max_tile_y = tile_y;
1.583 - }
1.584 - for( i=0; i<5; i++ ) {
1.585 - if( (*segment & NO_POINTER) == 0 ) {
1.586 - scene_extract_polygons( *segment );
1.587 - }
1.588 - segment++;
1.589 - }
1.590 + control = *segment++;
1.591 + int tile_x = SEGMENT_X(control);
1.592 + int tile_y = SEGMENT_Y(control);
1.593 + if( tile_x > max_tile_x ) {
1.594 + max_tile_x = tile_x;
1.595 + }
1.596 + if( tile_y > max_tile_y ) {
1.597 + max_tile_y = tile_y;
1.598 + }
1.599 + for( i=0; i<5; i++ ) {
1.600 + if( (*segment & NO_POINTER) == 0 ) {
1.601 + scene_extract_polygons( *segment );
1.602 + }
1.603 + segment++;
1.604 + }
1.605 } while( (control & SEGMENT_END) == 0 );
1.606
1.607 pvr2_scene.buffer_width = (max_tile_x+1)<<5;
1.608 pvr2_scene.buffer_height = (max_tile_y+1)<<5;
1.609
1.610 - if( pvr2_scene.vertex_count > 0 ) {
1.611 - // Pass 2: Extract vertex data
1.612 - vertex_buffer_map();
1.613 - pvr2_scene.vertex_index = 0;
1.614 - segment = tilebuffer;
1.615 - do {
1.616 - control = *segment++;
1.617 - for( i=0; i<5; i++ ) {
1.618 - if( (*segment & NO_POINTER) == 0 ) {
1.619 - scene_extract_vertexes( *segment );
1.620 - }
1.621 - segment++;
1.622 - }
1.623 - } while( (control & SEGMENT_END) == 0 );
1.624 - vertex_buffer_unmap();
1.625 - }
1.626 + // Pass 2: Extract vertex data
1.627 + vertex_buffer_map();
1.628 + pvr2_scene.vertex_index = 0;
1.629 + segment = tilebuffer;
1.630 + do {
1.631 + control = *segment++;
1.632 + for( i=0; i<5; i++ ) {
1.633 + if( (*segment & NO_POINTER) == 0 ) {
1.634 + scene_extract_vertexes( *segment );
1.635 + }
1.636 + segment++;
1.637 + }
1.638 + } while( (control & SEGMENT_END) == 0 );
1.639 +
1.640 + scene_extract_background();
1.641 +
1.642 + vertex_buffer_unmap();
1.643 }
1.644
1.645 /**
.