2 * Glide64 - Glide video plugin for Nintendo 64 emulators.
3 * Copyright (c) 2002 Dave2001
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 //****************************************************************
22 // Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
23 // Project started on December 29th, 2001
26 // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
27 // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
29 // Official Glide64 development channel: #Glide64 on EFnet
31 // Original author: Dave2001 (Dave2999@hotmail.com)
32 // Other authors: Gonetz, Gugaman
34 //****************************************************************
42 #include "DepthBufferRender.h"
49 #define Vj rdp.vtxbuf2[j]
50 #define Vi rdp.vtxbuf2[i]
52 VERTEX
*vtx_list1
[32]; // vertex indexing
53 VERTEX
*vtx_list2
[32];
56 // util_init - initialize data for the functions in this file
61 for (int i
=0; i
<32; i
++)
63 vtx_list1
[i
] = &rdp
.vtx1
[i
];
64 vtx_list2
[i
] = &rdp
.vtx2
[i
];
68 //software backface culling. Gonetz
69 // mega modifications by Dave2001
70 BOOL
cull_tri(VERTEX
**v
) // type changed to VERTEX** [Dave2001]
74 if (v
[0]->scr_off
& v
[1]->scr_off
& v
[2]->scr_off
)
80 // Triangle can't be culled, if it need clipping
83 //fix for sun in zeldas
84 BOOL fix_i_uv
= FALSE
;
85 if (settings
.zelda
&& rdp
.rm
== 0x0c184241 && rdp
.tiles
[rdp
.cur_tile
].format
== 4)
90 if (!v
[i
]->screen_translated
)
92 v
[i
]->sx
= rdp
.view_trans
[0] + v
[i
]->x_w
* rdp
.view_scale
[0];
93 v
[i
]->sy
= rdp
.view_trans
[1] + v
[i
]->y_w
* rdp
.view_scale
[1];
94 v
[i
]->sz
= rdp
.view_trans
[2] + v
[i
]->z_w
* rdp
.view_scale
[2];
95 if ((fix_i_uv
) && (v
[i
]->uv_fixed
== 0))
101 v
[i
]->screen_translated
= 1;
103 if (v
[i
]->w
< 0.01f
) //need clip_z. can't be culled now
107 if (settings
.fix_tex_coord
)
109 if (draw
) return FALSE
; // z-clipping, can't be culled by software
113 //now we need to check, if triangle's vertices are in clockwise order
114 // Use precalculated x/z and y/z coordinates.
115 float x1
= v
[0]->sx
- v
[1]->sx
;
116 float y1
= v
[0]->sy
- v
[1]->sy
;
117 float x2
= v
[2]->sx
- v
[1]->sx
;
118 float y2
= v
[2]->sy
- v
[1]->sy
;
120 DWORD mode
= (rdp
.flags
& CULLMASK
) >> CULLSHIFT
;
123 case 1: // cull front
124 // if ((x1*y2 - y1*x2) < 0.0f) //counter-clockwise, positive
125 if ((y1
*x2
-x1
*y2
) < 0.0f
) //counter-clockwise, positive
132 // if ((x1*y2 - y1*x2) >= 0.0f) //clockwise, negative
133 if ((y1
*x2
-x1
*y2
) >= 0.0f
) //clockwise, negative
146 void apply_shade_mods (VERTEX
*v
)
150 memcpy (col
, rdp
.col
, 16);
157 if (col
[0] > 1.0f
) col
[0] = 1.0f
;
158 if (col
[1] > 1.0f
) col
[1] = 1.0f
;
159 if (col
[2] > 1.0f
) col
[2] = 1.0f
;
160 if (col
[0] < 0.0f
) col
[0] = 0.0f
;
161 if (col
[1] < 0.0f
) col
[1] = 0.0f
;
162 if (col
[2] < 0.0f
) col
[2] = 0.0f
;
163 v
->r
= (BYTE
)(255.0f
* col
[0]);
164 v
->g
= (BYTE
)(255.0f
* col
[1]);
165 v
->b
= (BYTE
)(255.0f
* col
[2]);
169 if (col
[3] > 1.0f
) col
[3] = 1.0f
;
170 if (col
[3] < 0.0f
) col
[3] = 0.0f
;
171 v
->a
= (BYTE
)(255.0f
* col
[3]);
173 if (cmb
& CMB_SETSHADE_SHADEALPHA
)
175 v
->r
= v
->g
= v
->b
= v
->a
;
179 int r
= v
->r
- (int)(255.0f
* rdp
.coladd
[0]);
180 int g
= v
->g
- (int)(255.0f
* rdp
.coladd
[1]);
181 int b
= v
->b
- (int)(255.0f
* rdp
.coladd
[2]);
191 int a
= v
->a
- (int)(255.0f
* rdp
.coladd
[3]);
198 int r
= v
->r
+ (int)(255.0f
* rdp
.coladd
[0]);
199 int g
= v
->g
+ (int)(255.0f
* rdp
.coladd
[1]);
200 int b
= v
->b
+ (int)(255.0f
* rdp
.coladd
[2]);
201 if (r
> 255) r
= 255;
202 if (g
> 255) g
= 255;
203 if (b
> 255) b
= 255;
210 int a
= v
->a
+ (int)(255.0f
* rdp
.coladd
[3]);
211 if (a
> 255) a
= 255;
214 if (cmb
& CMB_COL_SUB_OWN
)
216 int r
= (BYTE
)(255.0f
* rdp
.coladd
[0]) - v
->r
;
217 int g
= (BYTE
)(255.0f
* rdp
.coladd
[1]) - v
->g
;
218 int b
= (BYTE
)(255.0f
* rdp
.coladd
[2]) - v
->b
;
228 if (col
[0] > 1.0f
) col
[0] = 1.0f
;
229 if (col
[1] > 1.0f
) col
[1] = 1.0f
;
230 if (col
[2] > 1.0f
) col
[2] = 1.0f
;
231 if (col
[0] < 0.0f
) col
[0] = 0.0f
;
232 if (col
[1] < 0.0f
) col
[1] = 0.0f
;
233 if (col
[2] < 0.0f
) col
[2] = 0.0f
;
234 v
->r
= (BYTE
)(v
->r
* col
[0]);
235 v
->g
= (BYTE
)(v
->g
* col
[1]);
236 v
->b
= (BYTE
)(v
->b
* col
[2]);
238 if (cmb
& CMB_A_MULT
)
240 if (col
[3] > 1.0f
) col
[3] = 1.0f
;
241 if (col
[3] < 0.0f
) col
[3] = 0.0f
;
242 v
->a
= (BYTE
)(v
->a
* col
[3]);
244 if (cmb
& CMB_MULT_OWN_ALPHA
)
246 float percent
= v
->a
/ 255.0f
;
247 v
->r
= (BYTE
)(v
->r
* percent
);
248 v
->g
= (BYTE
)(v
->g
* percent
);
249 v
->b
= (BYTE
)(v
->b
* percent
);
251 v
->shade_mods_allowed
= 0;
253 cmb
= rdp
.cmb_flags_2
;
256 v
->r
= (BYTE
)(rdp
.col_2
[0] * rdp
.shade_factor
* 255.0f
+ v
->r
* (1.0f
- rdp
.shade_factor
));
257 v
->g
= (BYTE
)(rdp
.col_2
[1] * rdp
.shade_factor
* 255.0f
+ v
->g
* (1.0f
- rdp
.shade_factor
));
258 v
->b
= (BYTE
)(rdp
.col_2
[2] * rdp
.shade_factor
* 255.0f
+ v
->b
* (1.0f
- rdp
.shade_factor
));
259 v
->shade_mods_allowed
= 0;
264 static long dzdx
= 0;
266 void DrawTri (VERTEX
**vtx
, WORD linew
)
268 if (settings
.fb_depth_render
&& linew
== 0)
270 float X0
= vtx
[0]->sx
/ rdp
.scale_x
;
271 float Y0
= vtx
[0]->sy
/ rdp
.scale_y
;
272 float X1
= vtx
[1]->sx
/ rdp
.scale_x
;
273 float Y1
= vtx
[1]->sy
/ rdp
.scale_y
;
274 float X2
= vtx
[2]->sx
/ rdp
.scale_x
;
275 float Y2
= vtx
[2]->sy
/ rdp
.scale_y
;
276 float diff12
= Y1
- Y2
;
277 float diff02
= Y0
- Y2
;
280 double denom
= ((X0
- X2
) * diff12
-
282 if(denom
*denom
> 0.0)
284 dzdx
= (long)(((vtx
[0]->sz
- vtx
[2]->sz
) * diff12
-
285 (vtx
[1]->sz
- vtx
[2]->sz
) * diff02
) / denom
* 65536.0);
293 for (int i
=0; i
<3; i
++)
297 if (v
->uv_calculated
!= rdp
.tex_ctr
)
299 #ifdef EXTREME_LOGGING
300 FRDP(" * CALCULATING VERTEX U/V: %d\n", v
->number
);
302 v
->uv_calculated
= rdp
.tex_ctr
;
304 if (!(rdp
.geom_mode
& 0x00020000))
306 if (!(rdp
.geom_mode
& 0x00000200))
308 if (rdp
.geom_mode
& 0x00000004) // flat shading
310 #ifdef EXTREME_LOGGING
311 RDP(" * Flat shaded\n");
320 #ifdef EXTREME_LOGGING
321 FRDP(" * Prim shaded %08lx\n", rdp
.prim_color
);
323 v
->a
= (BYTE
)(rdp
.prim_color
& 0xFF);
324 v
->b
= (BYTE
)((rdp
.prim_color
>> 8) & 0xFF);
325 v
->g
= (BYTE
)((rdp
.prim_color
>> 16) & 0xFF);
326 v
->r
= (BYTE
)((rdp
.prim_color
>> 24) & 0xFF);
331 // Fix texture coordinates
332 v
->u1
= v
->u0
= v
->ou
;
333 v
->v1
= v
->v0
= v
->ov
;
335 if (rdp
.tex
>= 1 && rdp
.cur_cache
[0])
337 if (rdp
.hires_tex
&& rdp
.hires_tex
->tile
== 0)
339 v
->u0
+= rdp
.hires_tex
->u_shift
+ rdp
.hires_tex
->tile_uls
;
340 v
->v0
+= rdp
.hires_tex
->v_shift
+ rdp
.hires_tex
->tile_ult
;
343 if (rdp
.tiles
[rdp
.cur_tile
].shift_s
)
345 if (rdp
.tiles
[rdp
.cur_tile
].shift_s
> 10)
346 v
->u0
*= (float)(1 << (16 - rdp
.tiles
[rdp
.cur_tile
].shift_s
));
348 v
->u0
/= (float)(1 << rdp
.tiles
[rdp
.cur_tile
].shift_s
);
350 if (rdp
.tiles
[rdp
.cur_tile
].shift_t
)
352 if (rdp
.tiles
[rdp
.cur_tile
].shift_t
> 10)
353 v
->v0
*= (float)(1 << (16 - rdp
.tiles
[rdp
.cur_tile
].shift_t
));
355 v
->v0
/= (float)(1 << rdp
.tiles
[rdp
.cur_tile
].shift_t
);
358 if (rdp
.hires_tex
&& rdp
.hires_tex
->tile
== 0)
360 if (rdp
.hires_tex
->tile_uls
!= (int)rdp
.tiles
[rdp
.cur_tile
].f_ul_s
)
361 v
->u0
-= rdp
.tiles
[rdp
.cur_tile
].f_ul_s
;
362 v
->u0
*= rdp
.hires_tex
->u_scale
;
363 v
->v0
*= rdp
.hires_tex
->u_scale
;
366 FRDP("hires_tex t0: (%f, %f)->(%f, %f)\n", v
->ou
, v
->ov
, v
->u0
, v
->v0
);
370 v
->u0
-= rdp
.tiles
[rdp
.cur_tile
].f_ul_s
;
371 v
->v0
-= rdp
.tiles
[rdp
.cur_tile
].f_ul_t
;
372 v
->u0
= rdp
.cur_cache
[0]->c_off
+ rdp
.cur_cache
[0]->c_scl_x
* v
->u0
;
373 v
->v0
= rdp
.cur_cache
[0]->c_off
+ rdp
.cur_cache
[0]->c_scl_y
* v
->v0
;
375 v
->u0_w
= v
->u0
/ v
->w
;
376 v
->v0_w
= v
->v0
/ v
->w
;
379 if (rdp
.tex
>= 2 && rdp
.cur_cache
[1])
381 if (rdp
.hires_tex
&& rdp
.hires_tex
->tile
== 1)
383 v
->u1
+= rdp
.hires_tex
->u_shift
+ rdp
.hires_tex
->tile_uls
;
384 v
->v1
+= rdp
.hires_tex
->v_shift
+ rdp
.hires_tex
->tile_ult
;
386 if (rdp
.tiles
[rdp
.cur_tile
+1].shift_s
)
388 if (rdp
.tiles
[rdp
.cur_tile
+1].shift_s
> 10)
389 v
->u1
*= (float)(1 << (16 - rdp
.tiles
[rdp
.cur_tile
+1].shift_s
));
391 v
->u1
/= (float)(1 << rdp
.tiles
[rdp
.cur_tile
+1].shift_s
);
393 if (rdp
.tiles
[rdp
.cur_tile
+1].shift_t
)
395 if (rdp
.tiles
[rdp
.cur_tile
+1].shift_t
> 10)
396 v
->v1
*= (float)(1 << (16 - rdp
.tiles
[rdp
.cur_tile
+1].shift_t
));
398 v
->v1
/= (float)(1 << rdp
.tiles
[rdp
.cur_tile
+1].shift_t
);
401 if (rdp
.hires_tex
&& rdp
.hires_tex
->tile
== 1)
403 if (rdp
.hires_tex
->tile_uls
!= (int)rdp
.tiles
[rdp
.cur_tile
].f_ul_s
)
404 v
->u1
-= rdp
.tiles
[rdp
.cur_tile
].f_ul_s
;
405 v
->u1
*= rdp
.hires_tex
->u_scale
;
406 v
->v1
*= rdp
.hires_tex
->u_scale
;
409 FRDP("hires_tex t1: (%f, %f)->(%f, %f)\n", v
->ou
, v
->ov
, v
->u0
, v
->v0
);
413 v
->u1
-= rdp
.tiles
[rdp
.cur_tile
+1].f_ul_s
;
414 v
->v1
-= rdp
.tiles
[rdp
.cur_tile
+1].f_ul_t
;
415 v
->u1
= rdp
.cur_cache
[1]->c_off
+ rdp
.cur_cache
[1]->c_scl_x
* v
->u1
;
416 v
->v1
= rdp
.cur_cache
[1]->c_off
+ rdp
.cur_cache
[1]->c_scl_y
* v
->v1
;
419 v
->u1_w
= v
->u1
/ v
->w
;
420 v
->v1_w
= v
->v1
/ v
->w
;
422 // FRDP(" * CALCULATING VERTEX U/V: %d u0: %f, v0: %f, u1: %f, v1: %f\n", v->number, v->u0, v->v0, v->u1, v->v1);
424 if (v
->shade_mods_allowed
)
425 apply_shade_mods (v
);
430 if ((vtx
[0]->scr_off
& 16) ||
431 (vtx
[1]->scr_off
& 16) ||
432 (vtx
[2]->scr_off
& 16))
433 rdp
.clip
|= CLIP_ZMIN
;
435 vtx
[0]->not_zclipped
= vtx
[1]->not_zclipped
= vtx
[2]->not_zclipped
= 1;
437 if (rdp
.cur_cache
[0] && (rdp
.tex
& 1) && (rdp
.cur_cache
[0]->splits
> 1) && !rdp
.hires_tex
&& !rdp
.clip
)
439 int index
,i
,j
, min_256
,max_256
, cur_256
,left_256
,right_256
;
442 min_256
= min((int)vtx
[0]->u0
,(int)vtx
[1]->u0
); // bah, don't put two mins on one line
443 min_256
= min(min_256
,(int)vtx
[2]->u0
) >> 8; // or it will be calculated twice
445 max_256
= max((int)vtx
[0]->u0
,(int)vtx
[1]->u0
); // not like it makes much difference
446 max_256
= max(max_256
,(int)vtx
[2]->u0
) >> 8; // anyway :P
448 for (cur_256
=min_256
; cur_256
<=max_256
; cur_256
++)
450 left_256
= cur_256
<< 8;
451 right_256
= (cur_256
+1) << 8;
453 // Set vertex buffers
454 rdp
.vtxbuf
= rdp
.vtx1
; // copy from v to rdp.vtx1
455 rdp
.vtxbuf2
= rdp
.vtx2
;
469 if (v1
->u0
>= left_256
)
471 if (v2
->u0
>= left_256
) // Both are in, save the last one
473 rdp
.vtxbuf
[index
] = *v2
;
474 rdp
.vtxbuf
[index
].u0
-= left_256
;
475 rdp
.vtxbuf
[index
++].v0
+= rdp
.cur_cache
[0]->c_scl_y
* (cur_256
* rdp
.cur_cache
[0]->splitheight
);
477 else // First is in, second is out, save intersection
479 percent
= (left_256
- v1
->u0
) / (v2
->u0
- v1
->u0
);
480 rdp
.vtxbuf
[index
].x
= v1
->x
+ (v2
->x
- v1
->x
) * percent
;
481 rdp
.vtxbuf
[index
].y
= v1
->y
+ (v2
->y
- v1
->y
) * percent
;
482 rdp
.vtxbuf
[index
].z
= v1
->z
+ (v2
->z
- v1
->z
) * percent
;
483 rdp
.vtxbuf
[index
].w
= v1
->w
+ (v2
->w
- v1
->w
) * percent
;
484 rdp
.vtxbuf
[index
].f
= v1
->f
+ (v2
->f
- v1
->f
) * percent
;
485 rdp
.vtxbuf
[index
].u0
= 0.5f
;
486 rdp
.vtxbuf
[index
].v0
= v1
->v0
+ (v2
->v0
- v1
->v0
) * percent
+
487 rdp
.cur_cache
[0]->c_scl_y
* cur_256
* rdp
.cur_cache
[0]->splitheight
;
488 rdp
.vtxbuf
[index
].u1
= v1
->u1
+ (v2
->u1
- v1
->u1
) * percent
;
489 rdp
.vtxbuf
[index
].v1
= v1
->v1
+ (v2
->v1
- v1
->v1
) * percent
;
490 rdp
.vtxbuf
[index
].b
= (BYTE
)(v1
->b
+ (v2
->b
- v1
->b
) * percent
);
491 rdp
.vtxbuf
[index
].g
= (BYTE
)(v1
->g
+ (v2
->g
- v1
->g
) * percent
);
492 rdp
.vtxbuf
[index
].r
= (BYTE
)(v1
->r
+ (v2
->r
- v1
->r
) * percent
);
493 rdp
.vtxbuf
[index
++].a
= (BYTE
)(v1
->a
+ (v2
->a
- v1
->a
) * percent
);
498 //if (v2->u0 < left_256) // Both are out, save nothing
499 if (v2
->u0
>= left_256
) // First is out, second is in, save intersection & in point
501 percent
= (left_256
- v2
->u0
) / (v1
->u0
- v2
->u0
);
502 rdp
.vtxbuf
[index
].x
= v2
->x
+ (v1
->x
- v2
->x
) * percent
;
503 rdp
.vtxbuf
[index
].y
= v2
->y
+ (v1
->y
- v2
->y
) * percent
;
504 rdp
.vtxbuf
[index
].z
= v2
->z
+ (v1
->z
- v2
->z
) * percent
;
505 rdp
.vtxbuf
[index
].w
= v2
->w
+ (v1
->w
- v2
->w
) * percent
;
506 rdp
.vtxbuf
[index
].f
= v2
->f
+ (v1
->f
- v2
->f
) * percent
;
507 rdp
.vtxbuf
[index
].u0
= 0.5f
;
508 rdp
.vtxbuf
[index
].v0
= v2
->v0
+ (v1
->v0
- v2
->v0
) * percent
+
509 rdp
.cur_cache
[0]->c_scl_y
* cur_256
* rdp
.cur_cache
[0]->splitheight
;
510 rdp
.vtxbuf
[index
].u1
= v2
->u1
+ (v1
->u1
- v2
->u1
) * percent
;
511 rdp
.vtxbuf
[index
].v1
= v2
->v1
+ (v1
->v1
- v2
->v1
) * percent
;
512 rdp
.vtxbuf
[index
].b
= (BYTE
)(v2
->b
+ (v1
->b
- v2
->b
) * percent
);
513 rdp
.vtxbuf
[index
].g
= (BYTE
)(v2
->g
+ (v1
->g
- v2
->g
) * percent
);
514 rdp
.vtxbuf
[index
].r
= (BYTE
)(v2
->r
+ (v1
->r
- v2
->r
) * percent
);
515 rdp
.vtxbuf
[index
++].a
= (BYTE
)(v2
->a
+ (v1
->a
- v2
->a
) * percent
);
518 rdp
.vtxbuf
[index
] = *v2
;
519 rdp
.vtxbuf
[index
].u0
-= left_256
;
520 rdp
.vtxbuf
[index
++].v0
+= rdp
.cur_cache
[0]->c_scl_y
* (cur_256
* rdp
.cur_cache
[0]->splitheight
);
524 rdp
.n_global
= index
;
526 rdp
.vtxbuf
= rdp
.vtx2
; // now vtx1 holds the value, & vtx2 is the destination
527 rdp
.vtxbuf2
= rdp
.vtx1
;
531 for (i
=0; i
<rdp
.n_global
; i
++)
534 if (j
== rdp
.n_global
) j
= 0;
536 VERTEX
*v1
= &rdp
.vtxbuf2
[i
];
537 VERTEX
*v2
= &rdp
.vtxbuf2
[j
];
540 if (v1
->u0
<= 256.0f
)
542 if (v2
->u0
<= 256.0f
) // Both are in, save the last one
544 rdp
.vtxbuf
[index
] = *v2
;
545 rdp
.vtxbuf
[index
++].not_zclipped
= 0;
547 else // First is in, second is out, save intersection
549 percent
= (right_256
- v1
->u0
) / (v2
->u0
- v1
->u0
);
550 rdp
.vtxbuf
[index
].x
= v1
->x
+ (v2
->x
- v1
->x
) * percent
;
551 rdp
.vtxbuf
[index
].y
= v1
->y
+ (v2
->y
- v1
->y
) * percent
;
552 rdp
.vtxbuf
[index
].z
= v1
->z
+ (v2
->z
- v1
->z
) * percent
;
553 rdp
.vtxbuf
[index
].w
= v1
->w
+ (v2
->w
- v1
->w
) * percent
;
554 rdp
.vtxbuf
[index
].f
= v1
->f
+ (v2
->f
- v1
->f
) * percent
;
555 rdp
.vtxbuf
[index
].u0
= 255.5f
;
556 rdp
.vtxbuf
[index
].v0
= v1
->v0
+ (v2
->v0
- v1
->v0
) * percent
;
557 rdp
.vtxbuf
[index
].u1
= v1
->u1
+ (v2
->u1
- v1
->u1
) * percent
;
558 rdp
.vtxbuf
[index
].v1
= v1
->v1
+ (v2
->v1
- v1
->v1
) * percent
;
559 rdp
.vtxbuf
[index
].b
= (BYTE
)(v1
->b
+ (v2
->b
- v1
->b
) * percent
);
560 rdp
.vtxbuf
[index
].g
= (BYTE
)(v1
->g
+ (v2
->g
- v1
->g
) * percent
);
561 rdp
.vtxbuf
[index
].r
= (BYTE
)(v1
->r
+ (v2
->r
- v1
->r
) * percent
);
562 rdp
.vtxbuf
[index
].a
= (BYTE
)(v1
->a
+ (v2
->a
- v1
->a
) * percent
);
563 rdp
.vtxbuf
[index
++].not_zclipped
= 0;
568 //if (v2->u0 > 256.0f) // Both are out, save nothing
569 if (v2
->u0
<= 256.0f
) // First is out, second is in, save intersection & in point
571 percent
= (right_256
- v2
->u0
) / (v1
->u0
- v2
->u0
);
572 rdp
.vtxbuf
[index
].x
= v2
->x
+ (v1
->x
- v2
->x
) * percent
;
573 rdp
.vtxbuf
[index
].y
= v2
->y
+ (v1
->y
- v2
->y
) * percent
;
574 rdp
.vtxbuf
[index
].z
= v2
->z
+ (v1
->z
- v2
->z
) * percent
;
575 rdp
.vtxbuf
[index
].w
= v2
->w
+ (v1
->w
- v2
->w
) * percent
;
576 rdp
.vtxbuf
[index
].f
= v2
->f
+ (v1
->f
- v2
->f
) * percent
;
577 rdp
.vtxbuf
[index
].u0
= 255.5f
;
578 rdp
.vtxbuf
[index
].v0
= v2
->v0
+ (v1
->v0
- v2
->v0
) * percent
;
579 rdp
.vtxbuf
[index
].u1
= v2
->u1
+ (v1
->u1
- v2
->u1
) * percent
;
580 rdp
.vtxbuf
[index
].v1
= v2
->v1
+ (v1
->v1
- v2
->v1
) * percent
;
581 rdp
.vtxbuf
[index
].b
= (BYTE
)(v2
->b
+ (v1
->b
- v2
->b
) * percent
);
582 rdp
.vtxbuf
[index
].g
= (BYTE
)(v2
->g
+ (v1
->g
- v2
->g
) * percent
);
583 rdp
.vtxbuf
[index
].r
= (BYTE
)(v2
->r
+ (v1
->r
- v2
->r
) * percent
);
584 rdp
.vtxbuf
[index
].a
= (BYTE
)(v2
->a
+ (v1
->a
- v2
->a
) * percent
);
585 rdp
.vtxbuf
[index
++].not_zclipped
= 0;
588 rdp
.vtxbuf
[index
] = *v2
;
589 rdp
.vtxbuf
[index
++].not_zclipped
= 0;
593 rdp
.n_global
= index
;
595 do_triangle_stuff (linew
);
600 // Set vertex buffers
601 rdp
.vtxbuf
= rdp
.vtx1
; // copy from v to rdp.vtx1
602 rdp
.vtxbuf2
= rdp
.vtx2
;
606 rdp
.vtxbuf
[0] = *vtx
[0];
607 rdp
.vtxbuf
[1] = *vtx
[1];
608 rdp
.vtxbuf
[2] = *vtx
[2];
610 do_triangle_stuff (linew
);
614 void do_triangle_stuff (WORD linew
) // what else?? do the triangle stuff :P (to keep from writing code twice)
618 // if (rdp.zsrc != 1)
621 for (i
=0; i
<rdp
.n_global
; i
++)
623 if (rdp
.vtxbuf
[i
].not_zclipped
)// && rdp.zsrc != 1)
625 #ifdef EXTREME_LOGGING
626 FRDP (" * NOT ZCLIPPPED: %d\n", rdp
.vtxbuf
[i
].number
);
628 rdp
.vtxbuf
[i
].x
= rdp
.vtxbuf
[i
].sx
;
629 rdp
.vtxbuf
[i
].y
= rdp
.vtxbuf
[i
].sy
;
630 rdp
.vtxbuf
[i
].z
= rdp
.vtxbuf
[i
].sz
;
631 rdp
.vtxbuf
[i
].q
= rdp
.vtxbuf
[i
].oow
;
632 rdp
.vtxbuf
[i
].u0
= rdp
.vtxbuf
[i
].u0_w
;
633 rdp
.vtxbuf
[i
].v0
= rdp
.vtxbuf
[i
].v0_w
;
634 rdp
.vtxbuf
[i
].u1
= rdp
.vtxbuf
[i
].u1_w
;
635 rdp
.vtxbuf
[i
].v1
= rdp
.vtxbuf
[i
].v1_w
;
639 #ifdef EXTREME_LOGGING
640 FRDP (" * ZCLIPPED: %d\n", rdp
.vtxbuf
[i
].number
);
642 rdp
.vtxbuf
[i
].q
= 1.0f
/ rdp
.vtxbuf
[i
].w
;
643 rdp
.vtxbuf
[i
].x
= rdp
.view_trans
[0] + rdp
.vtxbuf
[i
].x
* rdp
.vtxbuf
[i
].q
* rdp
.view_scale
[0];
644 rdp
.vtxbuf
[i
].y
= rdp
.view_trans
[1] + rdp
.vtxbuf
[i
].y
* rdp
.vtxbuf
[i
].q
* rdp
.view_scale
[1];
645 rdp
.vtxbuf
[i
].z
= rdp
.view_trans
[2] + rdp
.vtxbuf
[i
].z
* rdp
.vtxbuf
[i
].q
* rdp
.view_scale
[2];
648 rdp
.vtxbuf
[i
].u0
*= rdp
.vtxbuf
[i
].q
;
649 rdp
.vtxbuf
[i
].v0
*= rdp
.vtxbuf
[i
].q
;
653 rdp
.vtxbuf
[i
].u1
*= rdp
.vtxbuf
[i
].q
;
654 rdp
.vtxbuf
[i
].v1
*= rdp
.vtxbuf
[i
].q
;
659 rdp
.vtxbuf
[i
].z
= rdp
.prim_depth
;
661 // Don't remove clipping, or it will freeze
662 if (rdp
.vtxbuf
[i
].x
> rdp
.scissor
.lr_x
) rdp
.clip
|= CLIP_XMAX
;
663 if (rdp
.vtxbuf
[i
].x
< rdp
.scissor
.ul_x
) rdp
.clip
|= CLIP_XMIN
;
664 if (rdp
.vtxbuf
[i
].y
> rdp
.scissor
.lr_y
) rdp
.clip
|= CLIP_YMAX
;
665 if (rdp
.vtxbuf
[i
].y
< rdp
.scissor
.ul_y
) rdp
.clip
|= CLIP_YMIN
;
671 void do_triangle_stuff_2 (WORD linew
)
675 for (int i
=0; i
<rdp
.n_global
; i
++)
677 // Don't remove clipping, or it will freeze
678 if (rdp
.vtxbuf
[i
].x
> rdp
.scissor
.lr_x
) rdp
.clip
|= CLIP_XMAX
;
679 if (rdp
.vtxbuf
[i
].x
< rdp
.scissor
.ul_x
) rdp
.clip
|= CLIP_XMIN
;
680 if (rdp
.vtxbuf
[i
].y
> rdp
.scissor
.lr_y
) rdp
.clip
|= CLIP_YMAX
;
681 if (rdp
.vtxbuf
[i
].y
< rdp
.scissor
.ul_y
) rdp
.clip
|= CLIP_YMIN
;
688 // clip_z - clips along the z-axis, also copies the vertex buffer for clip_tri
689 // * ALWAYS * processes it, even if it does not need z-clipping. It needs
690 // to copy the buffer anyway.
695 int i
,j
,index
,n
=rdp
.n_global
;
698 if (rdp
.clip
& CLIP_ZMIN
)
700 // Swap vertex buffers
701 VERTEX
*tmp
= rdp
.vtxbuf2
;
702 rdp
.vtxbuf2
= rdp
.vtxbuf
;
707 // Check the vertices for clipping
715 if (Vj
.w
>= 0.01f
) // Both are in, save the last one
717 rdp
.vtxbuf
[index
] = Vj
;
718 rdp
.vtxbuf
[index
++].not_zclipped
= 1;
720 else // First is in, second is out, save intersection
722 percent
= (-Vi
.w
) / (Vj
.w
- Vi
.w
);
723 rdp
.vtxbuf
[index
].not_zclipped
= 0;
724 rdp
.vtxbuf
[index
].x
= Vi
.x
+ (Vj
.x
- Vi
.x
) * percent
;
725 rdp
.vtxbuf
[index
].y
= Vi
.y
+ (Vj
.y
- Vi
.y
) * percent
;
726 rdp
.vtxbuf
[index
].z
= Vi
.z
+ (Vj
.z
- Vi
.z
) * percent
;
727 rdp
.vtxbuf
[index
].f
= Vi
.f
+ (Vj
.f
- Vi
.f
) * percent
;
728 rdp
.vtxbuf
[index
].w
= 0.01f
;
729 rdp
.vtxbuf
[index
].u0
= Vi
.u0
+ (Vj
.u0
- Vi
.u0
) * percent
;
730 rdp
.vtxbuf
[index
].v0
= Vi
.v0
+ (Vj
.v0
- Vi
.v0
) * percent
;
731 rdp
.vtxbuf
[index
].u1
= Vi
.u1
+ (Vj
.u1
- Vi
.u1
) * percent
;
732 rdp
.vtxbuf
[index
].v1
= Vi
.v1
+ (Vj
.v1
- Vi
.v1
) * percent
;
733 rdp
.vtxbuf
[index
].b
= (BYTE
)(Vi
.b
+ (Vj
.b
- Vi
.b
) * percent
);
734 rdp
.vtxbuf
[index
].g
= (BYTE
)(Vi
.g
+ (Vj
.g
- Vi
.g
) * percent
);
735 rdp
.vtxbuf
[index
].r
= (BYTE
)(Vi
.r
+ (Vj
.r
- Vi
.r
) * percent
);
736 rdp
.vtxbuf
[index
++].a
= (BYTE
)(Vi
.a
+ (Vj
.a
- Vi
.a
) * percent
);
741 //if (Vj.w < 0.01f) // Both are out, save nothing
742 if (Vj
.w
>= 0.01f
) // First is out, second is in, save intersection & in point
744 percent
= (-Vj
.w
) / (Vi
.w
- Vj
.w
);
745 rdp
.vtxbuf
[index
].not_zclipped
= 0;
746 rdp
.vtxbuf
[index
].x
= Vj
.x
+ (Vi
.x
- Vj
.x
) * percent
;
747 rdp
.vtxbuf
[index
].y
= Vj
.y
+ (Vi
.y
- Vj
.y
) * percent
;
748 rdp
.vtxbuf
[index
].z
= Vj
.z
+ (Vi
.z
- Vj
.z
) * percent
;
749 rdp
.vtxbuf
[index
].f
= Vj
.f
+ (Vi
.f
- Vj
.f
) * percent
;
750 rdp
.vtxbuf
[index
].w
= 0.01f
;
751 rdp
.vtxbuf
[index
].u0
= Vj
.u0
+ (Vi
.u0
- Vj
.u0
) * percent
;
752 rdp
.vtxbuf
[index
].v0
= Vj
.v0
+ (Vi
.v0
- Vj
.v0
) * percent
;
753 rdp
.vtxbuf
[index
].u1
= Vj
.u1
+ (Vi
.u1
- Vj
.u1
) * percent
;
754 rdp
.vtxbuf
[index
].v1
= Vj
.v1
+ (Vi
.v1
- Vj
.v1
) * percent
;
755 rdp
.vtxbuf
[index
].b
= (BYTE
)(Vj
.b
+ (Vi
.b
- Vj
.b
) * percent
);
756 rdp
.vtxbuf
[index
].g
= (BYTE
)(Vj
.g
+ (Vi
.g
- Vj
.g
) * percent
);
757 rdp
.vtxbuf
[index
].r
= (BYTE
)(Vj
.r
+ (Vi
.r
- Vj
.r
) * percent
);
758 rdp
.vtxbuf
[index
++].a
= (BYTE
)(Vj
.a
+ (Vi
.a
- Vj
.a
) * percent
);
761 rdp
.vtxbuf
[index
] = Vj
;
762 rdp
.vtxbuf
[index
++].not_zclipped
= 1;
766 rdp
.n_global
= index
;
770 static void CalculateLOD(VERTEX
**v
, int n
)
772 //rdp.update |= UPDATE_TEXTURE;
774 if (rdp.lod_calculated)
777 if (dc0_detailmax < 0.5)
778 detailmax = rdp.lod_fraction;
780 detailmax = 1.0f - rdp.lod_fraction;
781 grTexDetailControl (GR_TMU0, dc0_lodbias, dc0_detailscale, detailmax);
783 grTexDetailControl (GR_TMU1, dc1_lodbias, dc1_detailscale, detailmax);
787 float deltaS
, deltaT
;
788 float deltaX
, deltaY
;
789 double deltaTexels
, deltaPixels
, lodFactor
= 0;
791 float s_scale
= rdp
.tiles
[rdp
.cur_tile
].width
/ 255.0f
;
792 float t_scale
= rdp
.tiles
[rdp
.cur_tile
].height
/ 255.0f
;
793 if (settings
.lodmode
== 1)
795 deltaS
= (v
[1]->u0
/v
[1]->q
- v
[0]->u0
/v
[0]->q
) * s_scale
;
796 deltaT
= (v
[1]->v0
/v
[1]->q
- v
[0]->v0
/v
[0]->q
) * t_scale
;
797 deltaTexels
= sqrt( deltaS
* deltaS
+ deltaT
* deltaT
);
799 deltaX
= (v
[1]->x
- v
[0]->x
)/rdp
.scale_x
;
800 deltaY
= (v
[1]->y
- v
[0]->y
)/rdp
.scale_y
;
801 deltaPixels
= sqrt( deltaX
* deltaX
+ deltaY
* deltaY
);
803 lodFactor
= deltaTexels
/ deltaPixels
;
808 for (i
= 0; i
< n
; i
++)
810 j
= (i
< n
-1) ? i
+ 1 : 0;
812 deltaS
= (v
[j
]->u0
/v
[j
]->q
- v
[i
]->u0
/v
[i
]->q
) * s_scale
;
813 deltaT
= (v
[j
]->v0
/v
[j
]->q
- v
[i
]->v0
/v
[i
]->q
) * t_scale
;
814 // deltaS = v[j]->ou - v[i]->ou;
815 // deltaT = v[j]->ov - v[i]->ov;
816 deltaTexels
= sqrt( deltaS
* deltaS
+ deltaT
* deltaT
);
818 deltaX
= (v
[j
]->x
- v
[i
]->x
)/rdp
.scale_x
;
819 deltaY
= (v
[j
]->y
- v
[i
]->y
)/rdp
.scale_y
;
820 deltaPixels
= sqrt( deltaX
* deltaX
+ deltaY
* deltaY
);
822 lodFactor
+= deltaTexels
/ deltaPixels
;
824 // Divide by n (n edges) to find average
825 lodFactor
= lodFactor
/ n
;
827 long ilod
= (long)lodFactor
;
828 int lod_tile
= min((int)(log(ilod
)/log(2)), rdp
.cur_tile
+ rdp
.mipmap_level
);
829 float lod_fraction
= 1.0f
;
830 if (lod_tile
< rdp
.cur_tile
+ rdp
.mipmap_level
)
832 lod_fraction
= max((float)modf(lodFactor
/ pow(2,lod_tile
),&intptr
), rdp
.prim_lodmin
/ 255.0f
);
835 if (cmb
.dc0_detailmax
< 0.5f
)
836 detailmax
= lod_fraction
;
838 detailmax
= 1.0f
- lod_fraction
;
839 grTexDetailControl (GR_TMU0
, cmb
.dc0_lodbias
, cmb
.dc0_detailscale
, detailmax
);
841 grTexDetailControl (GR_TMU1
, cmb
.dc1_lodbias
, cmb
.dc1_detailscale
, detailmax
);
842 FRDP("CalculateLOD factor: %f, tile: %d, lod_fraction: %f\n", (float)lodFactor
, lod_tile
, lod_fraction
);
845 static void DepthBuffer(VERTEX
** vtx
, int n
)
849 for(int i
=0; i
<n
; i
++)
851 int fz
= (int)(vtx
[i
]->z
*8.0f
+0.5f
);
853 else if (fz
>= 0x40000) fz
= 0x40000 - 1;
854 vtx
[i
]->z
= (float)zLUT
[fz
];
858 if (settings
.fb_depth_render
&& dzdx
&& (rdp
.flags
& ZBUF_UPDATE
))
862 for(int i
=0; i
<n
; i
++)
864 v
[i
].x
= (long)(vtx
[i
]->x
/ rdp
.scale_x
* 65536.0);
865 v
[i
].y
= (long)(vtx
[i
]->y
/ rdp
.scale_y
* 65536.0);
866 v
[i
].z
= (long)(vtx
[i
]->z
* 65536.0);
868 Rasterize(v
, n
, dzdx
);
870 for(int i
=0; i
<n
; i
++)
871 vtx
[i
]->z
= ScaleZ(vtx
[i
]->z
);
874 void clip_tri (WORD linew
)
876 int i
,j
,index
,n
=rdp
.n_global
;
879 // rdp.vtxbuf and rdp.vtxbuf2 were set by clip_z
881 // Check which clipping is needed
882 if (rdp
.clip
& CLIP_XMAX
) // right of the screen
884 // Swap vertex buffers
885 VERTEX
*tmp
= rdp
.vtxbuf2
;
886 rdp
.vtxbuf2
= rdp
.vtxbuf
;
891 // Check the vertices for clipping
897 if (Vi
.x
<= rdp
.scissor
.lr_x
)
899 if (Vj
.x
<= rdp
.scissor
.lr_x
) // Both are in, save the last one
901 rdp
.vtxbuf
[index
++] = Vj
;
903 else // First is in, second is out, save intersection
905 percent
= (rdp
.scissor
.lr_x
- Vi
.x
) / (Vj
.x
- Vi
.x
);
906 rdp
.vtxbuf
[index
].x
= (float)rdp
.scissor
.lr_x
+ 0.001f
;
907 rdp
.vtxbuf
[index
].y
= Vi
.y
+ (Vj
.y
- Vi
.y
) * percent
;
908 rdp
.vtxbuf
[index
].z
= Vi
.z
+ (Vj
.z
- Vi
.z
) * percent
;
909 rdp
.vtxbuf
[index
].q
= Vi
.q
+ (Vj
.q
- Vi
.q
) * percent
;
910 rdp
.vtxbuf
[index
].f
= Vi
.f
+ (Vj
.f
- Vi
.f
) * percent
;
911 rdp
.vtxbuf
[index
].u0
= Vi
.u0
+ (Vj
.u0
- Vi
.u0
) * percent
;
912 rdp
.vtxbuf
[index
].v0
= Vi
.v0
+ (Vj
.v0
- Vi
.v0
) * percent
;
913 rdp
.vtxbuf
[index
].u1
= Vi
.u1
+ (Vj
.u1
- Vi
.u1
) * percent
;
914 rdp
.vtxbuf
[index
].v1
= Vi
.v1
+ (Vj
.v1
- Vi
.v1
) * percent
;
915 rdp
.vtxbuf
[index
].b
= (BYTE
)(Vi
.b
+ (Vj
.b
- Vi
.b
) * percent
);
916 rdp
.vtxbuf
[index
].g
= (BYTE
)(Vi
.g
+ (Vj
.g
- Vi
.g
) * percent
);
917 rdp
.vtxbuf
[index
].r
= (BYTE
)(Vi
.r
+ (Vj
.r
- Vi
.r
) * percent
);
918 rdp
.vtxbuf
[index
++].a
= (BYTE
)(Vi
.a
+ (Vj
.a
- Vi
.a
) * percent
);
923 //if (Vj.x > rdp.scissor.lr_x) // Both are out, save nothing
924 if (Vj
.x
<= rdp
.scissor
.lr_x
) // First is out, second is in, save intersection & in point
926 percent
= (rdp
.scissor
.lr_x
- Vj
.x
) / (Vi
.x
- Vj
.x
);
927 rdp
.vtxbuf
[index
].x
= (float)rdp
.scissor
.lr_x
+ 0.001f
;
928 rdp
.vtxbuf
[index
].y
= Vj
.y
+ (Vi
.y
- Vj
.y
) * percent
;
929 rdp
.vtxbuf
[index
].z
= Vj
.z
+ (Vi
.z
- Vj
.z
) * percent
;
930 rdp
.vtxbuf
[index
].q
= Vj
.q
+ (Vi
.q
- Vj
.q
) * percent
;
931 rdp
.vtxbuf
[index
].f
= Vj
.f
+ (Vi
.f
- Vj
.f
) * percent
;
932 rdp
.vtxbuf
[index
].u0
= Vj
.u0
+ (Vi
.u0
- Vj
.u0
) * percent
;
933 rdp
.vtxbuf
[index
].v0
= Vj
.v0
+ (Vi
.v0
- Vj
.v0
) * percent
;
934 rdp
.vtxbuf
[index
].u1
= Vj
.u1
+ (Vi
.u1
- Vj
.u1
) * percent
;
935 rdp
.vtxbuf
[index
].v1
= Vj
.v1
+ (Vi
.v1
- Vj
.v1
) * percent
;
936 rdp
.vtxbuf
[index
].b
= (BYTE
)(Vj
.b
+ (Vi
.b
- Vj
.b
) * percent
);
937 rdp
.vtxbuf
[index
].g
= (BYTE
)(Vj
.g
+ (Vi
.g
- Vj
.g
) * percent
);
938 rdp
.vtxbuf
[index
].r
= (BYTE
)(Vj
.r
+ (Vi
.r
- Vj
.r
) * percent
);
939 rdp
.vtxbuf
[index
++].a
= (BYTE
)(Vj
.a
+ (Vi
.a
- Vj
.a
) * percent
);
942 rdp
.vtxbuf
[index
++] = Vj
;
948 if (rdp
.clip
& CLIP_XMIN
) // left of the screen
950 // Swap vertex buffers
951 VERTEX
*tmp
= rdp
.vtxbuf2
;
952 rdp
.vtxbuf2
= rdp
.vtxbuf
;
957 // Check the vertices for clipping
963 if (Vi
.x
>= rdp
.scissor
.ul_x
)
965 if (Vj
.x
>= rdp
.scissor
.ul_x
) // Both are in, save the last one
967 rdp
.vtxbuf
[index
++] = Vj
;
969 else // First is in, second is out, save intersection
971 percent
= (rdp
.scissor
.ul_x
- Vi
.x
) / (Vj
.x
- Vi
.x
);
972 rdp
.vtxbuf
[index
].x
= (float)rdp
.scissor
.ul_x
+ 0.001f
;
973 rdp
.vtxbuf
[index
].y
= Vi
.y
+ (Vj
.y
- Vi
.y
) * percent
;
974 rdp
.vtxbuf
[index
].z
= Vi
.z
+ (Vj
.z
- Vi
.z
) * percent
;
975 rdp
.vtxbuf
[index
].q
= Vi
.q
+ (Vj
.q
- Vi
.q
) * percent
;
976 rdp
.vtxbuf
[index
].f
= Vi
.f
+ (Vj
.f
- Vi
.f
) * percent
;
977 rdp
.vtxbuf
[index
].u0
= Vi
.u0
+ (Vj
.u0
- Vi
.u0
) * percent
;
978 rdp
.vtxbuf
[index
].v0
= Vi
.v0
+ (Vj
.v0
- Vi
.v0
) * percent
;
979 rdp
.vtxbuf
[index
].u1
= Vi
.u1
+ (Vj
.u1
- Vi
.u1
) * percent
;
980 rdp
.vtxbuf
[index
].v1
= Vi
.v1
+ (Vj
.v1
- Vi
.v1
) * percent
;
981 rdp
.vtxbuf
[index
].b
= (BYTE
)(Vi
.b
+ (Vj
.b
- Vi
.b
) * percent
);
982 rdp
.vtxbuf
[index
].g
= (BYTE
)(Vi
.g
+ (Vj
.g
- Vi
.g
) * percent
);
983 rdp
.vtxbuf
[index
].r
= (BYTE
)(Vi
.r
+ (Vj
.r
- Vi
.r
) * percent
);
984 rdp
.vtxbuf
[index
++].a
= (BYTE
)(Vi
.a
+ (Vj
.a
- Vi
.a
) * percent
);
989 //if (Vj.x < rdp.scissor.ul_x) // Both are out, save nothing
990 if (Vj
.x
>= rdp
.scissor
.ul_x
) // First is out, second is in, save intersection & in point
992 percent
= (rdp
.scissor
.ul_x
- Vj
.x
) / (Vi
.x
- Vj
.x
);
993 rdp
.vtxbuf
[index
].x
= (float)rdp
.scissor
.ul_x
+ 0.001f
;
994 rdp
.vtxbuf
[index
].y
= Vj
.y
+ (Vi
.y
- Vj
.y
) * percent
;
995 rdp
.vtxbuf
[index
].z
= Vj
.z
+ (Vi
.z
- Vj
.z
) * percent
;
996 rdp
.vtxbuf
[index
].q
= Vj
.q
+ (Vi
.q
- Vj
.q
) * percent
;
997 rdp
.vtxbuf
[index
].f
= Vj
.f
+ (Vi
.f
- Vj
.f
) * percent
;
998 rdp
.vtxbuf
[index
].u0
= Vj
.u0
+ (Vi
.u0
- Vj
.u0
) * percent
;
999 rdp
.vtxbuf
[index
].v0
= Vj
.v0
+ (Vi
.v0
- Vj
.v0
) * percent
;
1000 rdp
.vtxbuf
[index
].u1
= Vj
.u1
+ (Vi
.u1
- Vj
.u1
) * percent
;
1001 rdp
.vtxbuf
[index
].v1
= Vj
.v1
+ (Vi
.v1
- Vj
.v1
) * percent
;
1002 rdp
.vtxbuf
[index
].b
= (BYTE
)(Vj
.b
+ (Vi
.b
- Vj
.b
) * percent
);
1003 rdp
.vtxbuf
[index
].g
= (BYTE
)(Vj
.g
+ (Vi
.g
- Vj
.g
) * percent
);
1004 rdp
.vtxbuf
[index
].r
= (BYTE
)(Vj
.r
+ (Vi
.r
- Vj
.r
) * percent
);
1005 rdp
.vtxbuf
[index
++].a
= (BYTE
)(Vj
.a
+ (Vi
.a
- Vj
.a
) * percent
);
1007 // Save the in point
1008 rdp
.vtxbuf
[index
++] = Vj
;
1014 if (rdp
.clip
& CLIP_YMAX
) // top of the screen
1016 // Swap vertex buffers
1017 VERTEX
*tmp
= rdp
.vtxbuf2
;
1018 rdp
.vtxbuf2
= rdp
.vtxbuf
;
1020 rdp
.vtx_buffer
^= 1;
1023 // Check the vertices for clipping
1029 if (Vi
.y
<= rdp
.scissor
.lr_y
)
1031 if (Vj
.y
<= rdp
.scissor
.lr_y
) // Both are in, save the last one
1033 rdp
.vtxbuf
[index
++] = Vj
;
1035 else // First is in, second is out, save intersection
1037 percent
= (rdp
.scissor
.lr_y
- Vi
.y
) / (Vj
.y
- Vi
.y
);
1038 rdp
.vtxbuf
[index
].x
= Vi
.x
+ (Vj
.x
- Vi
.x
) * percent
;
1039 rdp
.vtxbuf
[index
].y
= (float)rdp
.scissor
.lr_y
+ 0.001f
;
1040 rdp
.vtxbuf
[index
].z
= Vi
.z
+ (Vj
.z
- Vi
.z
) * percent
;
1041 rdp
.vtxbuf
[index
].q
= Vi
.q
+ (Vj
.q
- Vi
.q
) * percent
;
1042 rdp
.vtxbuf
[index
].f
= Vi
.f
+ (Vj
.f
- Vi
.f
) * percent
;
1043 rdp
.vtxbuf
[index
].u0
= Vi
.u0
+ (Vj
.u0
- Vi
.u0
) * percent
;
1044 rdp
.vtxbuf
[index
].v0
= Vi
.v0
+ (Vj
.v0
- Vi
.v0
) * percent
;
1045 rdp
.vtxbuf
[index
].u1
= Vi
.u1
+ (Vj
.u1
- Vi
.u1
) * percent
;
1046 rdp
.vtxbuf
[index
].v1
= Vi
.v1
+ (Vj
.v1
- Vi
.v1
) * percent
;
1047 rdp
.vtxbuf
[index
].b
= (BYTE
)(Vi
.b
+ (Vj
.b
- Vi
.b
) * percent
);
1048 rdp
.vtxbuf
[index
].g
= (BYTE
)(Vi
.g
+ (Vj
.g
- Vi
.g
) * percent
);
1049 rdp
.vtxbuf
[index
].r
= (BYTE
)(Vi
.r
+ (Vj
.r
- Vi
.r
) * percent
);
1050 rdp
.vtxbuf
[index
++].a
= (BYTE
)(Vi
.a
+ (Vj
.a
- Vi
.a
) * percent
);
1055 //if (Vj.y > rdp.scissor.lr_y) // Both are out, save nothing
1056 if (Vj
.y
<= rdp
.scissor
.lr_y
) // First is out, second is in, save intersection & in point
1058 percent
= (rdp
.scissor
.lr_y
- Vj
.y
) / (Vi
.y
- Vj
.y
);
1059 rdp
.vtxbuf
[index
].x
= Vj
.x
+ (Vi
.x
- Vj
.x
) * percent
;
1060 rdp
.vtxbuf
[index
].y
= (float)rdp
.scissor
.lr_y
+ 0.001f
;
1061 rdp
.vtxbuf
[index
].z
= Vj
.z
+ (Vi
.z
- Vj
.z
) * percent
;
1062 rdp
.vtxbuf
[index
].q
= Vj
.q
+ (Vi
.q
- Vj
.q
) * percent
;
1063 rdp
.vtxbuf
[index
].f
= Vj
.f
+ (Vi
.f
- Vj
.f
) * percent
;
1064 rdp
.vtxbuf
[index
].u0
= Vj
.u0
+ (Vi
.u0
- Vj
.u0
) * percent
;
1065 rdp
.vtxbuf
[index
].v0
= Vj
.v0
+ (Vi
.v0
- Vj
.v0
) * percent
;
1066 rdp
.vtxbuf
[index
].u1
= Vj
.u1
+ (Vi
.u1
- Vj
.u1
) * percent
;
1067 rdp
.vtxbuf
[index
].v1
= Vj
.v1
+ (Vi
.v1
- Vj
.v1
) * percent
;
1068 rdp
.vtxbuf
[index
].b
= (BYTE
)(Vj
.b
+ (Vi
.b
- Vj
.b
) * percent
);
1069 rdp
.vtxbuf
[index
].g
= (BYTE
)(Vj
.g
+ (Vi
.g
- Vj
.g
) * percent
);
1070 rdp
.vtxbuf
[index
].r
= (BYTE
)(Vj
.r
+ (Vi
.r
- Vj
.r
) * percent
);
1071 rdp
.vtxbuf
[index
++].a
= (BYTE
)(Vj
.a
+ (Vi
.a
- Vj
.a
) * percent
);
1073 // Save the in point
1074 rdp
.vtxbuf
[index
++] = Vj
;
1080 if (rdp
.clip
& CLIP_YMIN
) // bottom of the screen
1082 // Swap vertex buffers
1083 VERTEX
*tmp
= rdp
.vtxbuf2
;
1084 rdp
.vtxbuf2
= rdp
.vtxbuf
;
1086 rdp
.vtx_buffer
^= 1;
1089 // Check the vertices for clipping
1095 if (Vi
.y
>= rdp
.scissor
.ul_y
)
1097 if (Vj
.y
>= rdp
.scissor
.ul_y
) // Both are in, save the last one
1099 rdp
.vtxbuf
[index
++] = Vj
;
1101 else // First is in, second is out, save intersection
1103 percent
= (rdp
.scissor
.ul_y
- Vi
.y
) / (Vj
.y
- Vi
.y
);
1104 rdp
.vtxbuf
[index
].x
= Vi
.x
+ (Vj
.x
- Vi
.x
) * percent
;
1105 rdp
.vtxbuf
[index
].y
= (float)rdp
.scissor
.ul_y
+ 0.001f
;
1106 rdp
.vtxbuf
[index
].z
= Vi
.z
+ (Vj
.z
- Vi
.z
) * percent
;
1107 rdp
.vtxbuf
[index
].q
= Vi
.q
+ (Vj
.q
- Vi
.q
) * percent
;
1108 rdp
.vtxbuf
[index
].f
= Vi
.f
+ (Vj
.f
- Vi
.f
) * percent
;
1109 rdp
.vtxbuf
[index
].u0
= Vi
.u0
+ (Vj
.u0
- Vi
.u0
) * percent
;
1110 rdp
.vtxbuf
[index
].v0
= Vi
.v0
+ (Vj
.v0
- Vi
.v0
) * percent
;
1111 rdp
.vtxbuf
[index
].u1
= Vi
.u1
+ (Vj
.u1
- Vi
.u1
) * percent
;
1112 rdp
.vtxbuf
[index
].v1
= Vi
.v1
+ (Vj
.v1
- Vi
.v1
) * percent
;
1113 rdp
.vtxbuf
[index
].b
= (BYTE
)(Vi
.b
+ (Vj
.b
- Vi
.b
) * percent
);
1114 rdp
.vtxbuf
[index
].g
= (BYTE
)(Vi
.g
+ (Vj
.g
- Vi
.g
) * percent
);
1115 rdp
.vtxbuf
[index
].r
= (BYTE
)(Vi
.r
+ (Vj
.r
- Vi
.r
) * percent
);
1116 rdp
.vtxbuf
[index
++].a
= (BYTE
)(Vi
.a
+ (Vj
.a
- Vi
.a
) * percent
);
1121 //if (Vj.y < rdp.scissor.ul_y) // Both are out, save nothing
1122 if (Vj
.y
>= rdp
.scissor
.ul_y
) // First is out, second is in, save intersection & in point
1124 percent
= (rdp
.scissor
.ul_y
- Vj
.y
) / (Vi
.y
- Vj
.y
);
1125 rdp
.vtxbuf
[index
].x
= Vj
.x
+ (Vi
.x
- Vj
.x
) * percent
;
1126 rdp
.vtxbuf
[index
].y
= (float)rdp
.scissor
.ul_y
+ 0.001f
;
1127 rdp
.vtxbuf
[index
].z
= Vj
.z
+ (Vi
.z
- Vj
.z
) * percent
;
1128 rdp
.vtxbuf
[index
].q
= Vj
.q
+ (Vi
.q
- Vj
.q
) * percent
;
1129 rdp
.vtxbuf
[index
].f
= Vj
.f
+ (Vi
.f
- Vj
.f
) * percent
;
1130 rdp
.vtxbuf
[index
].u0
= Vj
.u0
+ (Vi
.u0
- Vj
.u0
) * percent
;
1131 rdp
.vtxbuf
[index
].v0
= Vj
.v0
+ (Vi
.v0
- Vj
.v0
) * percent
;
1132 rdp
.vtxbuf
[index
].u1
= Vj
.u1
+ (Vi
.u1
- Vj
.u1
) * percent
;
1133 rdp
.vtxbuf
[index
].v1
= Vj
.v1
+ (Vi
.v1
- Vj
.v1
) * percent
;
1134 rdp
.vtxbuf
[index
].b
= (BYTE
)(Vj
.b
+ (Vi
.b
- Vj
.b
) * percent
);
1135 rdp
.vtxbuf
[index
].g
= (BYTE
)(Vj
.g
+ (Vi
.g
- Vj
.g
) * percent
);
1136 rdp
.vtxbuf
[index
].r
= (BYTE
)(Vj
.r
+ (Vi
.r
- Vj
.r
) * percent
);
1137 rdp
.vtxbuf
[index
++].a
= (BYTE
)(Vj
.a
+ (Vi
.a
- Vj
.a
) * percent
);
1139 // Save the in point
1140 rdp
.vtxbuf
[index
++] = Vj
;
1149 FRDP (" * clip_tri: n < 3\n");
1152 ConvertCoordsConvert (rdp
.vtxbuf
, n
);
1153 if (rdp
.fog_coord_enabled
)
1155 for (i
= 0; i
< n
; i
++)
1157 rdp
.vtxbuf
[i
].f
= 1.0f
/max(16.0f
,rdp
.vtxbuf
[i
].f
);
1161 if (settings
.lodmode
> 0 && rdp
.cur_tile
< rdp
.mipmap_level
)
1162 CalculateLOD(rdp
.vtx_buffer
?(vtx_list2
):(vtx_list1
), n
);
1164 cmb
.cmb_ext_use
= cmb
.tex_cmb_ext_use
= 0;
1169 for (int k = 0; k < 3; k++)
1171 FRDP("v%d %f->%f, width: %d. height: %d, tex_width: %d, tex_height: %d, lr_u: %f, lr_v: %f\n", k, vv0[k], pv[k]->v1, rdp.hires_tex->width, rdp.hires_tex->height, rdp.hires_tex->tex_width, rdp.hires_tex->tex_height, rdp.hires_tex->lr_u, rdp.hires_tex->lr_v);
1177 if (settings
.wireframe
)
1184 grDrawLine (&rdp
.vtxbuf
[i
], &rdp
.vtxbuf
[j
]);
1190 // VERTEX ** pv = rdp.vtx_buffer?(vtx_list2):(vtx_list1);
1191 // for (int k = 0; k < n; k ++)
1192 // FRDP ("DRAW[%d]: v.x = %f, v.y = %f, v.z = %f, v.u = %f, v.v = %f\n", k, pv[k]->x, pv[k]->y, pv[k]->z, pv[k]->coord[rdp.t0<<1], pv[k]->coord[(rdp.t0<<1)+1]);
1193 // pv[k]->y = settings.res_y - pv[k]->y;
1201 rdp
.vtxbuf
[i
].z
= ScaleZ(rdp
.vtxbuf
[i
].z
);
1204 grDrawLine (&rdp
.vtxbuf
[i
], &rdp
.vtxbuf
[j
]);
1209 rdp
.vtxbuf
[0].z
= ScaleZ(rdp
.vtxbuf
[0].z
);
1210 rdp
.vtxbuf
[1].z
= ScaleZ(rdp
.vtxbuf
[1].z
);
1212 v
[0] = rdp
.vtxbuf
[0];
1213 v
[1] = rdp
.vtxbuf
[0];
1214 v
[2] = rdp
.vtxbuf
[1];
1215 v
[3] = rdp
.vtxbuf
[1];
1216 float width
= (linew
-1)*0.25f
;
1217 if(rdp
.vtxbuf
[0].y
== rdp
.vtxbuf
[1].y
)
1219 v
[0].x
= v
[1].x
= rdp
.vtxbuf
[0].x
;
1220 v
[2].x
= v
[3].x
= rdp
.vtxbuf
[1].x
;
1222 v
[0].y
= v
[2].y
= rdp
.vtxbuf
[0].y
-width
*rdp
.scale_y
+1;
1223 v
[1].y
= v
[3].y
= rdp
.vtxbuf
[0].y
+width
*rdp
.scale_y
;
1227 v
[0].y
= v
[1].y
= rdp
.vtxbuf
[0].y
;
1228 v
[2].y
= v
[3].y
= rdp
.vtxbuf
[1].y
;
1230 v
[0].x
= v
[2].x
= rdp
.vtxbuf
[0].x
-width
*rdp
.scale_x
+1;
1231 v
[1].x
= v
[3].x
= rdp
.vtxbuf
[0].x
+width
*rdp
.scale_x
;
1233 grDrawTriangle(&v
[0], &v
[1], &v
[2]);
1234 grDrawTriangle(&v
[1], &v
[2], &v
[3]);
1239 if (settings
.ucode
== 5)
1241 if (rdp
.vtxbuf
[i
].z
< -1000.0f
) return;//rdp.vtxbuf[i].z = 0.0f;
1242 DepthBuffer(rdp
.vtx_buffer
?(vtx_list2
):(vtx_list1
), n
);
1243 grDrawVertexArray (GR_TRIANGLE_FAN
, n
, rdp
.vtx_buffer
?(&vtx_list2
):(&vtx_list1
));
1245 //grDrawVertexArrayContiguous (GR_TRIANGLE_FAN, n, rdp.vtxbuf, sizeof(VERTEX));
1249 if (debug
.capture
) add_tri (rdp
.vtxbuf
, n
, TRI_TRIANGLE
);
1252 void add_tri (VERTEX
*v
, int n
, int type
)
1254 //FRDP ("ENTER (%f, %f, %f), (%f, %f, %f), (%f, %f, %f)\n", v[0].x, v[0].y, v[0].w,
1255 // v[1].x, v[1].y, v[1].w, v[2].x, v[2].y, v[2].w);
1262 TRI_INFO
*info
= new TRI_INFO
;
1264 info
->v
= new VERTEX
[n
];
1265 memcpy (info
->v
, v
, sizeof(VERTEX
)*n
);
1266 info
->cycle_mode
= rdp
.cycle_mode
;
1267 info
->cycle1
= rdp
.cycle1
;
1268 info
->cycle2
= rdp
.cycle2
;
1269 info
->uncombined
= rdp
.uncombined
;
1270 info
->geom_mode
= rdp
.geom_mode
;
1271 info
->othermode_h
= rdp
.othermode_h
;
1272 info
->othermode_l
= rdp
.othermode_l
;
1273 info
->tri_n
= rdp
.tri_n
;
1276 for (int i
=0; i
<2; i
++)
1278 int j
= rdp
.cur_tile
+i
;
1280 info
->t
[i
].tmu
= rdp
.t0
;
1282 info
->t
[i
].tmu
= rdp
.t1
;
1283 info
->t
[i
].cur_cache
[0] = rdp
.cur_cache_n
[rdp
.t0
];
1284 info
->t
[i
].cur_cache
[1] = rdp
.cur_cache_n
[rdp
.t1
];
1285 info
->t
[i
].format
= rdp
.tiles
[j
].format
;
1286 info
->t
[i
].size
= rdp
.tiles
[j
].size
;
1287 info
->t
[i
].width
= rdp
.tiles
[j
].width
;
1288 info
->t
[i
].height
= rdp
.tiles
[j
].height
;
1289 info
->t
[i
].line
= rdp
.tiles
[j
].line
;
1290 info
->t
[i
].palette
= rdp
.tiles
[j
].palette
;
1291 info
->t
[i
].clamp_s
= rdp
.tiles
[j
].clamp_s
;
1292 info
->t
[i
].clamp_t
= rdp
.tiles
[j
].clamp_t
;
1293 info
->t
[i
].mirror_s
= rdp
.tiles
[j
].mirror_s
;
1294 info
->t
[i
].mirror_t
= rdp
.tiles
[j
].mirror_t
;
1295 info
->t
[i
].shift_s
= rdp
.tiles
[j
].shift_s
;
1296 info
->t
[i
].shift_t
= rdp
.tiles
[j
].shift_t
;
1297 info
->t
[i
].mask_s
= rdp
.tiles
[j
].mask_s
;
1298 info
->t
[i
].mask_t
= rdp
.tiles
[j
].mask_t
;
1299 info
->t
[i
].ul_s
= rdp
.tiles
[j
].ul_s
;
1300 info
->t
[i
].ul_t
= rdp
.tiles
[j
].ul_t
;
1301 info
->t
[i
].lr_s
= rdp
.tiles
[j
].lr_s
;
1302 info
->t
[i
].lr_t
= rdp
.tiles
[j
].lr_t
;
1303 info
->t
[i
].t_ul_s
= rdp
.tiles
[7].t_ul_s
;
1304 info
->t
[i
].t_ul_t
= rdp
.tiles
[7].t_ul_t
;
1305 info
->t
[i
].t_lr_s
= rdp
.tiles
[7].t_lr_s
;
1306 info
->t
[i
].t_lr_t
= rdp
.tiles
[7].t_lr_t
;
1307 info
->t
[i
].scale_s
= rdp
.tiles
[j
].s_scale
;
1308 info
->t
[i
].scale_t
= rdp
.tiles
[j
].t_scale
;
1311 info
->fog_color
= rdp
.fog_color
;
1312 info
->fill_color
= rdp
.fill_color
;
1313 info
->prim_color
= rdp
.prim_color
;
1314 info
->blend_color
= rdp
.blend_color
;
1315 info
->env_color
= rdp
.env_color
;
1316 info
->prim_lodmin
= rdp
.prim_lodmin
;
1317 info
->prim_lodfrac
= rdp
.prim_lodfrac
;
1319 info
->pNext
= debug
.tri_list
;
1320 debug
.tri_list
= info
;
1322 if (debug
.tri_last
== NULL
)
1323 debug
.tri_last
= debug
.tri_list
;
1327 void update_scissor ()
1329 if (rdp
.update
& UPDATE_SCISSOR
)
1331 rdp
.update
^= UPDATE_SCISSOR
;
1333 // KILL the floating point error with 0.01f
1334 rdp
.scissor
.ul_x
= (DWORD
) max(min((rdp
.scissor_o
.ul_x
* rdp
.scale_x
+ rdp
.offset_x
+ 0.01f
),settings
.res_x
),0);
1335 rdp
.scissor
.lr_x
= (DWORD
) max(min((rdp
.scissor_o
.lr_x
* rdp
.scale_x
+ rdp
.offset_x
+ 0.01f
),settings
.res_x
),0);
1336 rdp
.scissor
.ul_y
= (DWORD
) max(min((rdp
.scissor_o
.ul_y
* rdp
.scale_y
+ rdp
.offset_y
+ 0.01f
),settings
.res_y
),0);
1337 rdp
.scissor
.lr_y
= (DWORD
) max(min((rdp
.scissor_o
.lr_y
* rdp
.scale_y
+ rdp
.offset_y
+ 0.01f
),settings
.res_y
),0);
1338 FRDP (" |- scissor - (%d, %d) -> (%d, %d)\n", rdp
.scissor
.ul_x
, rdp
.scissor
.ul_y
,
1339 rdp
.scissor
.lr_x
, rdp
.scissor
.lr_y
);
1344 // update - update states if they need it
1349 unsigned int c2_m2b
:2;
1350 unsigned int c1_m2b
:2;
1351 unsigned int c2_m2a
:2;
1352 unsigned int c1_m2a
:2;
1353 unsigned int c2_m1b
:2;
1354 unsigned int c1_m1b
:2;
1355 unsigned int c2_m1a
:2;
1356 unsigned int c1_m1a
:2;
1357 } rdp_blender_setting
;
1361 RDP ("-+ update called\n");
1362 // Check for rendermode changes
1364 if (rdp
.render_mode_changed
& 0x00000C30)
1366 FRDP (" |- render_mode_changed zbuf - decal: %s, update: %s, compare: %s\n",
1367 str_yn
[(rdp
.othermode_l
&0x00000C00) == 0x00000C00],
1368 str_yn
[(rdp
.othermode_l
&0x00000020)?1:0],
1369 str_yn
[(rdp
.othermode_l
&0x00000010)?1:0]);
1371 rdp
.render_mode_changed
&= ~0x00000C30;
1372 rdp
.update
|= UPDATE_ZBUF_ENABLED
;
1375 // if ((rdp.othermode_l & 0x00000C00) == 0x00000C00)
1376 if (rdp
.othermode_l
& 0x00000800)
1377 rdp
.flags
|= ZBUF_DECAL
;
1379 rdp
.flags
&= ~ZBUF_DECAL
;
1382 if ((rdp
.othermode_l
& 0x00000020))
1383 rdp
.flags
|= ZBUF_UPDATE
;
1385 rdp
.flags
&= ~ZBUF_UPDATE
;
1388 if (rdp
.othermode_l
& 0x00000010)
1389 rdp
.flags
|= ZBUF_COMPARE
;
1391 rdp
.flags
&= ~ZBUF_COMPARE
;
1395 if (rdp
.render_mode_changed
& 0x00001000)
1397 FRDP (" |- render_mode_changed alpha compare - on: %s\n",
1398 str_yn
[(rdp
.othermode_l
&0x00001000)?1:0]);
1399 rdp
.render_mode_changed
&= ~0x00001000;
1400 rdp
.update
|= UPDATE_ALPHA_COMPARE
;
1402 if (rdp
.othermode_l
& 0x00001000)
1403 rdp
.flags
|= ALPHA_COMPARE
;
1405 rdp
.flags
&= ~ALPHA_COMPARE
;
1408 if (rdp
.render_mode_changed
& 0x00002000) // alpha cvg sel
1410 FRDP (" |- render_mode_changed alpha cvg sel - on: %s\n",
1411 str_yn
[(rdp
.othermode_l
&0x00002000)?1:0]);
1412 rdp
.render_mode_changed
&= ~0x00002000;
1413 rdp
.update
|= UPDATE_COMBINE
;
1417 if (rdp
.render_mode_changed
& 0xFFFF0000)
1419 FRDP (" |- render_mode_changed force_blend - %08lx\n", rdp
.othermode_l
&0xFFFF0000);
1420 rdp
.render_mode_changed
&= 0x0000FFFF;
1422 rdp
.fbl_a0
= (BYTE
)((rdp
.othermode_l
>>30)&0x3);
1423 rdp
.fbl_b0
= (BYTE
)((rdp
.othermode_l
>>26)&0x3);
1424 rdp
.fbl_c0
= (BYTE
)((rdp
.othermode_l
>>22)&0x3);
1425 rdp
.fbl_d0
= (BYTE
)((rdp
.othermode_l
>>18)&0x3);
1426 rdp
.fbl_a1
= (BYTE
)((rdp
.othermode_l
>>28)&0x3);
1427 rdp
.fbl_b1
= (BYTE
)((rdp
.othermode_l
>>24)&0x3);
1428 rdp
.fbl_c1
= (BYTE
)((rdp
.othermode_l
>>20)&0x3);
1429 rdp
.fbl_d1
= (BYTE
)((rdp
.othermode_l
>>16)&0x3);
1431 rdp
.update
|= UPDATE_COMBINE
;
1436 // Combine MUST go before texture
1437 if ((rdp
.update
& UPDATE_COMBINE
) && rdp
.allow_combine
)
1439 RDP (" |-+ update_combine\n");
1443 if (rdp
.update
& UPDATE_TEXTURE
) // note: UPDATE_TEXTURE and UPDATE_COMBINE are the same
1446 if (rdp
.tex_ctr
== 0xFFFFFFFF)
1450 if (rdp
.noise
== noise_none
)
1451 rdp
.update
^= UPDATE_TEXTURE
;
1457 if (rdp
.update
& UPDATE_ZBUF_ENABLED
)
1459 // already logged above
1460 rdp
.update
^= UPDATE_ZBUF_ENABLED
;
1462 if (rdp
.flags
& ZBUF_DECAL
)
1464 if ((rdp
.othermode_l
& 0x00000C00) == 0x00000C00)
1466 grDepthBiasLevel (settings
.depth_bias
);//(-32);
1467 FRDP("depth bias: %d\n", settings
.depth_bias
);
1471 // VP changed that to -1 (was -4)
1472 grDepthBiasLevel (-4);//-16);
1473 RDP("depth bias: -4");
1478 grDepthBiasLevel (0);
1481 if ((rdp
.flags
& ZBUF_ENABLED
) || (settings
.force_depth_compare
&& rdp
.zsrc
== 1))
1483 if ((rdp
.flags
& ZBUF_COMPARE
))
1485 if (settings
.soft_depth_compare
)
1487 grDepthBufferFunction (GR_CMP_LEQUAL
);
1491 grDepthBufferFunction (GR_CMP_LESS
);
1496 grDepthBufferFunction (GR_CMP_ALWAYS
);
1499 if ((rdp
.flags
& ZBUF_UPDATE
)
1500 // || (rdp.flags & ZBUF_DECAL) // FOR DEBUGGING ONLY
1503 grDepthMask (FXTRUE
);
1507 grDepthMask (FXFALSE
);
1512 grDepthBufferFunction (GR_CMP_ALWAYS
);
1513 grDepthMask (FXFALSE
);
1517 if (rdp
.update
& UPDATE_ALPHA_COMPARE
)
1519 // already logged above
1520 rdp
.update
^= UPDATE_ALPHA_COMPARE
;
1522 // if (rdp.acmp == 1 && !(rdp.othermode_l & 0x00002000) && !force_full_alpha)
1523 // if (rdp.acmp == 1 && !(rdp.othermode_l & 0x00002000) && (rdp.blend_color&0xFF))
1524 if (rdp
.acmp
== 1 && !(rdp
.othermode_l
& 0x00002000) && (!(rdp
.othermode_l
& 0x00004000) || (rdp
.blend_color
&0xFF)))
1526 BYTE reference
= (BYTE
)(rdp
.blend_color
&0xFF);
1528 grAlphaTestFunction (GR_CMP_GEQUAL
);
1530 grAlphaTestFunction (GR_CMP_GREATER
);
1531 grAlphaTestReferenceValue (reference
);
1532 FRDP (" |- alpha compare: blend: %02lx\n", reference
);
1536 if (rdp
.flags
& ALPHA_COMPARE
)
1538 if ((rdp
.othermode_l
& 0x5000) != 0x5000)
1540 grAlphaTestFunction (GR_CMP_GEQUAL
);
1541 grAlphaTestReferenceValue (0x20);//0xA0);
1542 RDP (" |- alpha compare: 0x20\n");
1546 grAlphaTestFunction (GR_CMP_GREATER
);
1549 grAlphaTestReferenceValue ((BYTE
)(rdp
.blend_color
&0xFF));
1550 FRDP (" |- alpha compare: blend: %02lx\n", rdp
.blend_color
&0xFF);
1554 grAlphaTestReferenceValue (0x00);
1555 RDP (" |- alpha compare: 0x00\n");
1561 grAlphaTestFunction (GR_CMP_ALWAYS
);
1562 RDP (" |- alpha compare: none\n");
1567 if (grStippleModeExt
)
1569 RDP (" |- alpha compare: dither\n");
1570 grStippleModeExt(settings
.stipple_mode
);
1571 // grStippleModeExt(GR_STIPPLE_PATTERN);
1576 if (grStippleModeExt
)
1578 //RDP (" |- alpha compare: dither disabled\n");
1579 grStippleModeExt(GR_STIPPLE_DISABLE
);
1583 // Cull mode (leave this in for z-clipped triangles)
1584 if (rdp
.update
& UPDATE_CULL_MODE
)
1586 rdp
.update
^= UPDATE_CULL_MODE
;
1587 DWORD mode
= (rdp
.flags
& CULLMASK
) >> CULLSHIFT
;
1588 FRDP (" |- cull_mode - mode: %s\n", str_cull
[mode
]);
1591 case 0: // cull none
1592 case 3: // cull both
1593 grCullMode(GR_CULL_DISABLE
);
1595 case 1: // cull front
1596 // grCullMode(GR_CULL_POSITIVE);
1597 grCullMode(GR_CULL_NEGATIVE
);
1599 case 2: // cull back
1600 // grCullMode (GR_CULL_NEGATIVE);
1601 grCullMode (GR_CULL_POSITIVE
);
1607 if (settings
.fog
&& (rdp
.update
& UPDATE_FOG_ENABLED
))
1609 rdp
.update
^= UPDATE_FOG_ENABLED
;
1611 if (rdp
.flags
& FOG_ENABLED
)
1613 typedef union { WORD
*w
; rdp_blender_setting
*b
; } BLEND
;
1614 WORD blword
= (WORD
) (rdp
.othermode_l
>> 16);
1617 if((rdp
.fog_multiplier
> 0) && (bl
.b
->c1_m1a
==3 || bl
.b
->c1_m2a
== 3 || bl
.b
->c2_m1a
== 3 || bl
.b
->c2_m2a
== 3))
1619 grFogColorValue(rdp
.fog_color
);
1620 grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT
);
1621 rdp
.fog_coord_enabled
= TRUE
;
1622 RDP("fog enabled \n");
1626 RDP("fog disabled in blender\n");
1627 rdp
.fog_coord_enabled
= FALSE
;
1628 grFogMode (GR_FOG_DISABLE
);
1633 RDP("fog disabled\n");
1634 rdp
.fog_coord_enabled
= FALSE
;
1635 grFogMode (GR_FOG_DISABLE
);
1640 if (rdp
.update
& UPDATE_VIEWPORT
)
1642 rdp
.update
^= UPDATE_VIEWPORT
;
1647 grClipWindow (0, 0, settings
.res_x
-1, settings
.res_y
-1);
1651 float scale_x
= (float)fabs(rdp
.view_scale
[0]);
1652 float scale_y
= (float)fabs(rdp
.view_scale
[1]);
1653 //printf("scale_y %g\n", scale_y);
1655 DWORD min_x
= (DWORD
) max(rdp
.view_trans
[0] - scale_x
, 0);
1656 DWORD min_y
= (DWORD
) max(rdp
.view_trans
[1] - scale_y
, 0);
1657 DWORD max_x
= (DWORD
) min(rdp
.view_trans
[0] + scale_x
+ 1, settings
.res_x
);
1658 DWORD max_y
= (DWORD
) min(rdp
.view_trans
[1] + scale_y
+ 1, settings
.res_y
);
1660 FRDP (" |- viewport - (%d, %d, %d, %d)\n", min_x
, min_y
, max_x
, max_y
);
1661 grClipWindow (min_x
, min_y
, max_x
, max_y
);
1662 //printf("viewport %d %d %d %d\n", min_x, min_y, max_x, max_y);
1667 if (rdp
.update
& UPDATE_SCISSOR
)
1670 RDP (" + update end\n");
1673 void set_message_combiner ()
1675 grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER
,
1676 GR_COMBINE_FACTOR_ONE
,
1677 GR_COMBINE_LOCAL_NONE
,
1678 GR_COMBINE_OTHER_TEXTURE
,
1680 grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER
,
1681 GR_COMBINE_FACTOR_ONE
,
1682 GR_COMBINE_LOCAL_NONE
,
1683 GR_COMBINE_OTHER_TEXTURE
,
1685 if (settings
.buff_clear
&& (settings
.show_fps
& 0x08))
1686 grAlphaBlendFunction (GR_BLEND_SRC_ALPHA
,
1687 GR_BLEND_ONE_MINUS_SRC_ALPHA
,
1691 grAlphaBlendFunction (GR_BLEND_ONE
,
1695 grAlphaTestFunction (GR_CMP_ALWAYS
);
1696 if (grStippleModeExt
)
1698 grStippleModeExt(GR_STIPPLE_DISABLE
);
1700 grTexCombine (GR_TMU1
,
1701 GR_COMBINE_FUNCTION_NONE
,
1702 GR_COMBINE_FACTOR_NONE
,
1703 GR_COMBINE_FUNCTION_NONE
,
1704 GR_COMBINE_FACTOR_NONE
,
1706 grTexCombine (GR_TMU0
,
1707 GR_COMBINE_FUNCTION_LOCAL
,
1708 GR_COMBINE_FACTOR_NONE
,
1709 GR_COMBINE_FUNCTION_LOCAL
,
1710 GR_COMBINE_FACTOR_NONE
,
1712 grTexSource(GR_TMU0
,
1713 grTexMinAddress(GR_TMU0
) + offset_font
,
1714 GR_MIPMAPLEVELMASK_BOTH
,
1716 grFogMode (GR_FOG_DISABLE
);
1721 2 bit: I textures, V-Rally 99
1722 3 bit: South Park, Polaris
1727 void fix_tex_coord (VERTEX
**v
)
1730 if (settings
.fix_tex_coord
& 449)
1732 // if ( (rdp.tiles[rdp.last_tile_size].format == 2) ||
1733 // ( (rdp.tiles[rdp.last_tile_size].size != 2)) )
1734 if (rdp
.tiles
[rdp
.last_tile_size
].size
!= 2)
1736 if (settings
.fix_tex_coord
& 128)
1738 if (v
[0]->sz
!= v
[1]->sz
|| v
[0]->sz
!= v
[2]->sz
)
1742 if (settings
.fix_tex_coord
& 256) //dr.mario
1744 if ((rdp
.tiles
[rdp
.last_tile_size
].format
== 2) && (rdp
.tiles
[rdp
.last_tile_size
].size
== 0))
1748 // int lu = (rdp.tiles[rdp.last_tile_size].ul_s)<<1;
1749 int ru
= (rdp
.tiles
[rdp
.last_tile_size
].lr_s
+1)<<1;
1750 int rv
= (rdp
.tiles
[rdp
.last_tile_size
].lr_t
+1)<<1;
1751 int diff
= (settings
.fix_tex_coord
& 64) ? 5 : 3;
1753 for (int t
= 0; t
< 3; t
++)
1755 if ((v
[t
]->uv_fixed
== 0)) //&& (((short)v[t]->ou > 0) || ((short)v[t]->ov > 0)))
1757 if ( (abs((short)v
[t
]->ou
- ru
) < diff
) || (abs((short)v
[t
]->ov
- rv
) < diff
) )
1758 // if ( ((short)v[t]->ou == lu) || (abs((short)v[t]->ou - ru) < 3) )
1772 for (int t
= 0; t
< 3; t
++)
1774 if (v
[t
]->uv_fixed
== 0)
1777 FRDP("v[%d] uv_fixed (%f, %f)->(%f,%f)\n",t
, v
[t
]->ou
, v
[t
]->ov
, v
[t
]->ou
*0.5f
, v
[t
]->ov
*0.5f
);
1786 if (settings
.fix_tex_coord
& 2)
1788 if (rdp
.tiles
[rdp
.last_tile_size
].format
== 4)
1790 for (int t
= 0; t
< 3; t
++)
1792 if (v
[t
]->uv_fixed
== 0)
1802 if (settings
.fix_tex_coord
& 4)
1804 TILE
& last_tile
= rdp
.tiles
[rdp
.last_tile_size
];
1805 if ((last_tile
.format
== 2) &&
1806 (last_tile
.size
== 0) &&
1807 (last_tile
.line
%2 == 0) &&
1808 (last_tile
.lr_s
>= last_tile
.lr_t
))
1810 int ru
= (rdp
.tiles
[rdp
.last_tile_size
].lr_s
+1);
1811 int rv
= (rdp
.tiles
[rdp
.last_tile_size
].lr_t
+1);
1813 for (t
= 0; t
< 3; t
++)
1815 if (v
[t
]->uv_fixed
== 0)
1817 if ( (abs((short)v
[t
]->ou
- ru
) < 3) || (abs((short)v
[t
]->ov
- rv
) < 3) )
1821 for (t
= 0; t
< 3; t
++)
1823 if (v
[t
]->uv_fixed
== 0)
1833 if (settings
.fix_tex_coord
& 8)
1835 if (rdp
.tiles
[rdp
.last_tile_size
].format
== 3 && rdp
.tiles
[rdp
.last_tile_size
].size
== 1)
1837 short width
= (rdp
.tiles
[rdp
.last_tile_size
].ul_s
<<1)+1 ;
1838 for (int t
= 0; t
< 3; t
++)
1840 if (v
[t
]->uv_fixed
== 0)
1842 if (short(v
[t
]->ou
) == width
)
1856 RDP("texcoord fixed!\n");
1857 for (int t
= 0; t
< 3; t
++)
1859 if (v
[t
]->uv_fixed
== 0)
1870 if (settings
.fix_tex_coord
& 16)
1872 if ((rdp
.tiles
[rdp
.last_tile_size
].format
== 2) && (rdp
.tiles
[rdp
.last_tile_size
].size
== 0))
1874 short width
= rdp
.tiles
[rdp
.last_tile_size
].lr_s
+ 1;
1875 short height
= rdp
.tiles
[rdp
.last_tile_size
].lr_t
+ 1;
1876 for (int t
= 0; t
< 3; t
++)
1878 if (v
[t
]->uv_fixed
== 0)
1880 if ((short(v
[t
]->ou
) > width
) || (short(v
[t
]->ov
) > height
))
1894 for (int t
= 0; t
< 3; t
++)
1896 if (v
[t
]->uv_fixed
== 0)
1903 RDP("texcoord fixed!\n");
1908 if (settings
.fix_tex_coord
& 32)
1910 if (!rdp
.vtx
[rdp
.v0
].uv_fixed
&&
1911 (rdp
.tiles
[rdp
.last_tile_size
].format
== 2) &&
1912 (rdp
.tiles
[rdp
.last_tile_size
].size
== 1) &&
1913 (rdp
.tiles
[rdp
.last_tile_size
].lr_s
>= 31) &&
1914 (rdp
.tiles
[rdp
.last_tile_size
].lr_t
>= 31))
1916 int ru
= (rdp
.tiles
[rdp
.last_tile_size
].lr_s
+1)<<1;
1917 int rv
= (rdp
.tiles
[rdp
.last_tile_size
].lr_t
+1)<<1;
1918 int top
= rdp
.v0
+ rdp
.vn
;
1919 for (int t
= rdp
.v0
; t
< top
; t
++)
1921 if ( (abs((short)rdp
.vtx
[t
].ou
- ru
) < 2) || (abs((short)rdp
.vtx
[t
].ov
- rv
) < 2) )
1929 for (int t
= rdp
.v0
; t
< top
; t
++)
1931 rdp
.vtx
[t
].uv_fixed
= 1;
1932 rdp
.vtx
[t
].ou
*= 0.5f
;
1933 rdp
.vtx
[t
].ov
*= 0.5f
;
1935 RDP("texcoord fixed!\n");