2013-04-04 21:22:19 +00:00
/*
* Glide64 - Glide video plugin for Nintendo 64 emulators .
* Copyright ( c ) 2002 Dave2001
* Copyright ( c ) 2003 - 2009 Sergey ' Gonetz ' Lipski
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
//****************************************************************
//
// Glide64 - Glide Plugin for Nintendo 64 emulators
// Project started on December 29th, 2001
//
// Authors:
// Dave2001, original author, founded the project in 2001, left it in 2002
// Gugaman, joined the project in 2002, left it in 2002
// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
// Hiroshi 'KoolSmoky' Morii, joined the project in 2007
//
//****************************************************************
//
// To modify Glide64:
// * 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.
// * 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.
//
//****************************************************************
2015-10-13 23:29:13 +00:00
# include <math.h>
2016-01-28 20:00:13 +00:00
# include <string.h>
2015-10-09 00:07:09 +00:00
# include "Gfx_1.3.h"
2013-04-04 21:22:19 +00:00
# include "Util.h"
# include "Combine.h"
# include "3dmath.h"
# include "Debugger.h"
# include "TexCache.h"
# include "DepthBufferRender.h"
# define Vj rdp.vtxbuf2[j]
# define Vi rdp.vtxbuf2[i]
VERTEX * vtx_list1 [ 32 ] ; // vertex indexing
VERTEX * vtx_list2 [ 32 ] ;
//
// util_init - initialize data for the functions in this file
//
2016-01-20 09:59:35 +00:00
void util_init ( )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
for ( int i = 0 ; i < 32 ; i + + )
{
vtx_list1 [ i ] = & rdp . vtx1 [ i ] ;
vtx_list2 [ i ] = & rdp . vtx2 [ i ] ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 06:14:48 +00:00
static uint32_t u_cull_mode = 0 ;
2013-04-04 21:22:19 +00:00
//software backface culling. Gonetz
// mega modifications by Dave2001
int cull_tri ( VERTEX * * v ) // type changed to VERTEX** [Dave2001]
{
2016-01-20 09:59:35 +00:00
int i ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
if ( v [ 0 ] - > scr_off & v [ 1 ] - > scr_off & v [ 2 ] - > scr_off )
{
LRDP ( " clipped \n " ) ;
return TRUE ;
}
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
// Triangle can't be culled, if it need clipping
int draw = FALSE ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
for ( i = 0 ; i < 3 ; i + + )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
if ( ! v [ i ] - > screen_translated )
{
v [ i ] - > sx = rdp . view_trans [ 0 ] + v [ i ] - > x_w * rdp . view_scale [ 0 ] + rdp . offset_x ;
v [ i ] - > sy = rdp . view_trans [ 1 ] + v [ i ] - > y_w * rdp . view_scale [ 1 ] + rdp . offset_y ;
v [ i ] - > sz = rdp . view_trans [ 2 ] + v [ i ] - > z_w * rdp . view_scale [ 2 ] ;
v [ i ] - > screen_translated = 1 ;
}
if ( v [ i ] - > w < 0.01f ) //need clip_z. can't be culled now
draw = 1 ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
u_cull_mode = ( rdp . flags & CULLMASK ) ;
if ( draw | | u_cull_mode = = 0 | | u_cull_mode = = CULLMASK ) //no culling set
{
u_cull_mode > > = CULLSHIFT ;
return FALSE ;
}
2013-04-04 21:22:19 +00:00
# define SW_CULLING
# ifdef SW_CULLING
# if 1 // H.Morii - faster float comparisons with zero area check added
2016-01-20 09:59:35 +00:00
const float x1 = v [ 0 ] - > sx - v [ 1 ] - > sx ;
const float y1 = v [ 0 ] - > sy - v [ 1 ] - > sy ;
const float x2 = v [ 2 ] - > sx - v [ 1 ] - > sx ;
const float y2 = v [ 2 ] - > sy - v [ 1 ] - > sy ;
const float area = y1 * x2 - x1 * y2 ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
const int iarea = * ( int * ) & area ;
const unsigned int mode = ( u_cull_mode < < 19UL ) ;
u_cull_mode > > = CULLSHIFT ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
if ( ( iarea & 0x7FFFFFFF ) = = 0 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
LRDP ( " zero area triangles \n " ) ;
return TRUE ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( ( rdp . flags & CULLMASK ) & & ( ( int ) ( iarea ^ mode ) ) > = 0 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
LRDP ( " culled \n " ) ;
return TRUE ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
# else
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
float x1 = v [ 0 ] - > sx - v [ 1 ] - > sx ;
float y1 = v [ 0 ] - > sy - v [ 1 ] - > sy ;
float x2 = v [ 2 ] - > sx - v [ 1 ] - > sx ;
float y2 = v [ 2 ] - > sy - v [ 1 ] - > sy ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
u_cull_mode > > = CULLSHIFT ;
switch ( u_cull_mode )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
case 1 : // cull front
// if ((x1*y2 - y1*x2) < 0.0f) //counter-clockwise, positive
if ( ( y1 * x2 - x1 * y2 ) < 0.0f ) //counter-clockwise, positive
{
LRDP ( " culled! \n " ) ;
return TRUE ;
}
return FALSE ;
case 2 : // cull back
// if ((x1*y2 - y1*x2) >= 0.0f) //clockwise, negative
if ( ( y1 * x2 - x1 * y2 ) > = 0.0f ) //clockwise, negative
{
LRDP ( " culled! \n " ) ;
return TRUE ;
}
return FALSE ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
# endif
# endif
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
return FALSE ;
}
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
void apply_shade_mods ( VERTEX * v )
{
float col [ 4 ] ;
uint32_t mod ;
memcpy ( col , rdp . col , 16 ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
if ( rdp . cmb_flags )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
if ( v - > shade_mod = = 0 )
v - > color_backup = * ( uint32_t * ) ( & ( v - > b ) ) ;
else
* ( uint32_t * ) ( & ( v - > b ) ) = v - > color_backup ;
mod = rdp . cmb_flags ;
if ( mod & CMB_SET )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
if ( col [ 0 ] > 1.0f ) col [ 0 ] = 1.0f ;
if ( col [ 1 ] > 1.0f ) col [ 1 ] = 1.0f ;
if ( col [ 2 ] > 1.0f ) col [ 2 ] = 1.0f ;
if ( col [ 0 ] < 0.0f ) col [ 0 ] = 0.0f ;
if ( col [ 1 ] < 0.0f ) col [ 1 ] = 0.0f ;
if ( col [ 2 ] < 0.0f ) col [ 2 ] = 0.0f ;
v - > r = ( uint8_t ) ( 255.0f * col [ 0 ] ) ;
v - > g = ( uint8_t ) ( 255.0f * col [ 1 ] ) ;
v - > b = ( uint8_t ) ( 255.0f * col [ 2 ] ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( mod & CMB_A_SET )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
if ( col [ 3 ] > 1.0f ) col [ 3 ] = 1.0f ;
if ( col [ 3 ] < 0.0f ) col [ 3 ] = 0.0f ;
v - > a = ( uint8_t ) ( 255.0f * col [ 3 ] ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( mod & CMB_SETSHADE_SHADEALPHA )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
v - > r = v - > g = v - > b = v - > a ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( mod & CMB_MULT_OWN_ALPHA )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
float percent = v - > a / 255.0f ;
v - > r = ( uint8_t ) ( v - > r * percent ) ;
v - > g = ( uint8_t ) ( v - > g * percent ) ;
v - > b = ( uint8_t ) ( v - > b * percent ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( mod & CMB_MULT )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
if ( col [ 0 ] > 1.0f ) col [ 0 ] = 1.0f ;
if ( col [ 1 ] > 1.0f ) col [ 1 ] = 1.0f ;
if ( col [ 2 ] > 1.0f ) col [ 2 ] = 1.0f ;
if ( col [ 0 ] < 0.0f ) col [ 0 ] = 0.0f ;
if ( col [ 1 ] < 0.0f ) col [ 1 ] = 0.0f ;
if ( col [ 2 ] < 0.0f ) col [ 2 ] = 0.0f ;
v - > r = ( uint8_t ) ( v - > r * col [ 0 ] ) ;
v - > g = ( uint8_t ) ( v - > g * col [ 1 ] ) ;
v - > b = ( uint8_t ) ( v - > b * col [ 2 ] ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( mod & CMB_A_MULT )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
if ( col [ 3 ] > 1.0f ) col [ 3 ] = 1.0f ;
if ( col [ 3 ] < 0.0f ) col [ 3 ] = 0.0f ;
v - > a = ( uint8_t ) ( v - > a * col [ 3 ] ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( mod & CMB_SUB )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
int r = v - > r - ( int ) ( 255.0f * rdp . coladd [ 0 ] ) ;
int g = v - > g - ( int ) ( 255.0f * rdp . coladd [ 1 ] ) ;
int b = v - > b - ( int ) ( 255.0f * rdp . coladd [ 2 ] ) ;
if ( r < 0 ) r = 0 ;
if ( g < 0 ) g = 0 ;
if ( b < 0 ) b = 0 ;
v - > r = ( uint8_t ) r ;
v - > g = ( uint8_t ) g ;
v - > b = ( uint8_t ) b ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( mod & CMB_A_SUB )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
int a = v - > a - ( int ) ( 255.0f * rdp . coladd [ 3 ] ) ;
if ( a < 0 ) a = 0 ;
v - > a = ( uint8_t ) a ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( mod & CMB_ADD )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
int r = v - > r + ( int ) ( 255.0f * rdp . coladd [ 0 ] ) ;
int g = v - > g + ( int ) ( 255.0f * rdp . coladd [ 1 ] ) ;
int b = v - > b + ( int ) ( 255.0f * rdp . coladd [ 2 ] ) ;
if ( r > 255 ) r = 255 ;
if ( g > 255 ) g = 255 ;
if ( b > 255 ) b = 255 ;
v - > r = ( uint8_t ) r ;
v - > g = ( uint8_t ) g ;
v - > b = ( uint8_t ) b ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( mod & CMB_A_ADD )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
int a = v - > a + ( int ) ( 255.0f * rdp . coladd [ 3 ] ) ;
if ( a > 255 ) a = 255 ;
v - > a = ( uint8_t ) a ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( mod & CMB_COL_SUB_OWN )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
int r = ( uint8_t ) ( 255.0f * rdp . coladd [ 0 ] ) - v - > r ;
int g = ( uint8_t ) ( 255.0f * rdp . coladd [ 1 ] ) - v - > g ;
int b = ( uint8_t ) ( 255.0f * rdp . coladd [ 2 ] ) - v - > b ;
if ( r < 0 ) r = 0 ;
if ( g < 0 ) g = 0 ;
if ( b < 0 ) b = 0 ;
v - > r = ( uint8_t ) r ;
v - > g = ( uint8_t ) g ;
v - > b = ( uint8_t ) b ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
v - > shade_mod = cmb . shade_mod_hash ;
}
if ( rdp . cmb_flags_2 & CMB_INTER )
{
v - > r = ( uint8_t ) ( rdp . col_2 [ 0 ] * rdp . shade_factor * 255.0f + v - > r * ( 1.0f - rdp . shade_factor ) ) ;
v - > g = ( uint8_t ) ( rdp . col_2 [ 1 ] * rdp . shade_factor * 255.0f + v - > g * ( 1.0f - rdp . shade_factor ) ) ;
v - > b = ( uint8_t ) ( rdp . col_2 [ 2 ] * rdp . shade_factor * 255.0f + v - > b * ( 1.0f - rdp . shade_factor ) ) ;
v - > shade_mod = cmb . shade_mod_hash ;
}
}
static int dzdx = 0 ;
static int deltaZ = 0 ;
VERTEX * * org_vtx ;
void draw_tri ( VERTEX * * vtx , uint16_t linew )
{
deltaZ = dzdx = 0 ;
if ( linew = = 0 & & ( fb_depth_render_enabled | | ( rdp . rm & 0xC00 ) = = 0xC00 ) )
{
double X0 = vtx [ 0 ] - > sx / rdp . scale_x ;
double Y0 = vtx [ 0 ] - > sy / rdp . scale_y ;
double X1 = vtx [ 1 ] - > sx / rdp . scale_x ;
double Y1 = vtx [ 1 ] - > sy / rdp . scale_y ;
double X2 = vtx [ 2 ] - > sx / rdp . scale_x ;
double Y2 = vtx [ 2 ] - > sy / rdp . scale_y ;
double diffy_02 = Y0 - Y2 ;
double diffy_12 = Y1 - Y2 ;
double diffx_02 = X0 - X2 ;
double diffx_12 = X1 - X2 ;
double denom = ( diffx_02 * diffy_12 - diffx_12 * diffy_02 ) ;
if ( denom * denom > 0.0 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
double diffz_02 = vtx [ 0 ] - > sz - vtx [ 2 ] - > sz ;
double diffz_12 = vtx [ 1 ] - > sz - vtx [ 2 ] - > sz ;
double fdzdx = ( diffz_02 * diffy_12 - diffz_12 * diffy_02 ) / denom ;
if ( ( rdp . rm & 0xC00 ) = = 0xC00 ) {
// Calculate deltaZ per polygon for Decal z-mode
double fdzdy = ( diffz_02 * diffx_12 - diffz_12 * diffx_02 ) / denom ;
double fdz = fabs ( fdzdx ) + fabs ( fdzdy ) ;
if ( ( settings . hacks & hack_Zelda ) & & ( rdp . rm & 0x800 ) )
fdz * = 4.0 ; // Decal mode in Zelda sometimes needs mutiplied deltaZ to work correct, e.g. roads
2016-01-25 09:58:29 +00:00
deltaZ = maxval ( 8 , ( int ) fdz ) ;
2016-01-20 09:59:35 +00:00
}
dzdx = ( int ) ( fdzdx * 65536.0 ) ;
2013-04-04 21:22:19 +00:00
}
}
2016-01-20 09:59:35 +00:00
org_vtx = vtx ;
for ( int i = 0 ; i < 3 ; i + + )
{
VERTEX * v = vtx [ i ] ;
if ( v - > uv_calculated ! = rdp . tex_ctr )
{
2013-04-04 21:22:19 +00:00
# ifdef EXTREME_LOGGING
2016-01-20 09:59:35 +00:00
FRDP ( " * CALCULATING VERTEX U/V: %d \n " , v - > number ) ;
2013-04-04 21:22:19 +00:00
# endif
2016-01-20 09:59:35 +00:00
v - > uv_calculated = rdp . tex_ctr ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
if ( ! ( rdp . geom_mode & 0x00020000 ) )
{
if ( ! ( rdp . geom_mode & 0x00000200 ) )
{
if ( rdp . geom_mode & 0x00000004 ) // flat shading
{
2016-01-25 09:58:29 +00:00
int flag = minval ( 2 , ( rdp . cmd1 > > 24 ) & 3 ) ;
2016-01-20 09:59:35 +00:00
v - > a = vtx [ flag ] - > a ;
v - > b = vtx [ flag ] - > b ;
v - > g = vtx [ flag ] - > g ;
v - > r = vtx [ flag ] - > r ;
# ifdef EXTREME_LOGGING
FRDP ( " * Flat shaded, flag%d - r: %d, g: %d, b: %d, a: %d \n " , flag , v - > r , v - > g , v - > b , v - > a ) ;
# endif
}
else // prim color
{
# ifdef EXTREME_LOGGING
FRDP ( " * Prim shaded %08lx \n " , rdp . prim_color ) ;
# endif
v - > a = ( uint8_t ) ( rdp . prim_color & 0xFF ) ;
v - > b = ( uint8_t ) ( ( rdp . prim_color > > 8 ) & 0xFF ) ;
v - > g = ( uint8_t ) ( ( rdp . prim_color > > 16 ) & 0xFF ) ;
v - > r = ( uint8_t ) ( ( rdp . prim_color > > 24 ) & 0xFF ) ;
}
}
}
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
// Fix texture coordinates
if ( ! v - > uv_scaled )
{
v - > ou * = rdp . tiles [ rdp . cur_tile ] . s_scale ;
v - > ov * = rdp . tiles [ rdp . cur_tile ] . t_scale ;
v - > uv_scaled = 1 ;
if ( ! rdp . Persp_en )
{
// v->oow = v->w = 1.0f;
v - > ou * = 0.5f ;
v - > ov * = 0.5f ;
}
}
v - > u1 = v - > u0 = v - > ou ;
v - > v1 = v - > v0 = v - > ov ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
if ( rdp . tex > = 1 & & rdp . cur_cache [ 0 ] )
{
if ( rdp . aTBuffTex [ 0 ] )
{
v - > u0 + = rdp . aTBuffTex [ 0 ] - > u_shift + rdp . aTBuffTex [ 0 ] - > tile_uls ;
v - > v0 + = rdp . aTBuffTex [ 0 ] - > v_shift + rdp . aTBuffTex [ 0 ] - > tile_ult ;
}
if ( rdp . tiles [ rdp . cur_tile ] . shift_s )
{
if ( rdp . tiles [ rdp . cur_tile ] . shift_s > 10 )
v - > u0 * = ( float ) ( 1 < < ( 16 - rdp . tiles [ rdp . cur_tile ] . shift_s ) ) ;
else
v - > u0 / = ( float ) ( 1 < < rdp . tiles [ rdp . cur_tile ] . shift_s ) ;
}
if ( rdp . tiles [ rdp . cur_tile ] . shift_t )
{
if ( rdp . tiles [ rdp . cur_tile ] . shift_t > 10 )
v - > v0 * = ( float ) ( 1 < < ( 16 - rdp . tiles [ rdp . cur_tile ] . shift_t ) ) ;
else
v - > v0 / = ( float ) ( 1 < < rdp . tiles [ rdp . cur_tile ] . shift_t ) ;
}
if ( rdp . aTBuffTex [ 0 ] )
{
if ( rdp . aTBuffTex [ 0 ] - > tile_uls ! = ( int ) rdp . tiles [ rdp . cur_tile ] . f_ul_s )
v - > u0 - = rdp . tiles [ rdp . cur_tile ] . f_ul_s ;
if ( rdp . aTBuffTex [ 0 ] - > tile_ult ! = ( int ) rdp . tiles [ rdp . cur_tile ] . f_ul_t | | ( settings . hacks & hack_Megaman ) )
v - > v0 - = rdp . tiles [ rdp . cur_tile ] . f_ul_t ; //required for megaman (boss special attack)
v - > u0 * = rdp . aTBuffTex [ 0 ] - > u_scale ;
v - > v0 * = rdp . aTBuffTex [ 0 ] - > v_scale ;
# ifdef EXTREME_LOGGING
FRDP ( " tbuff_tex t0: (%f, %f)->(%f, %f) \n " , v - > ou , v - > ov , v - > u0 , v - > v0 ) ;
# endif
}
else
{
v - > u0 - = rdp . tiles [ rdp . cur_tile ] . f_ul_s ;
v - > v0 - = rdp . tiles [ rdp . cur_tile ] . f_ul_t ;
v - > u0 = rdp . cur_cache [ 0 ] - > c_off + rdp . cur_cache [ 0 ] - > c_scl_x * v - > u0 ;
v - > v0 = rdp . cur_cache [ 0 ] - > c_off + rdp . cur_cache [ 0 ] - > c_scl_y * v - > v0 ;
}
v - > u0_w = v - > u0 / v - > w ;
v - > v0_w = v - > v0 / v - > w ;
}
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
if ( rdp . tex > = 2 & & rdp . cur_cache [ 1 ] )
{
if ( rdp . aTBuffTex [ 1 ] )
{
v - > u1 + = rdp . aTBuffTex [ 1 ] - > u_shift + rdp . aTBuffTex [ 1 ] - > tile_uls ;
v - > v1 + = rdp . aTBuffTex [ 1 ] - > v_shift + rdp . aTBuffTex [ 1 ] - > tile_ult ;
}
if ( rdp . tiles [ rdp . cur_tile + 1 ] . shift_s )
{
if ( rdp . tiles [ rdp . cur_tile + 1 ] . shift_s > 10 )
v - > u1 * = ( float ) ( 1 < < ( 16 - rdp . tiles [ rdp . cur_tile + 1 ] . shift_s ) ) ;
else
v - > u1 / = ( float ) ( 1 < < rdp . tiles [ rdp . cur_tile + 1 ] . shift_s ) ;
}
if ( rdp . tiles [ rdp . cur_tile + 1 ] . shift_t )
{
if ( rdp . tiles [ rdp . cur_tile + 1 ] . shift_t > 10 )
v - > v1 * = ( float ) ( 1 < < ( 16 - rdp . tiles [ rdp . cur_tile + 1 ] . shift_t ) ) ;
else
v - > v1 / = ( float ) ( 1 < < rdp . tiles [ rdp . cur_tile + 1 ] . shift_t ) ;
}
if ( rdp . aTBuffTex [ 1 ] )
{
if ( rdp . aTBuffTex [ 1 ] - > tile_uls ! = ( int ) rdp . tiles [ rdp . cur_tile ] . f_ul_s )
v - > u1 - = rdp . tiles [ rdp . cur_tile ] . f_ul_s ;
v - > u1 * = rdp . aTBuffTex [ 1 ] - > u_scale ;
v - > v1 * = rdp . aTBuffTex [ 1 ] - > v_scale ;
# ifdef EXTREME_LOGGING
FRDP ( " tbuff_tex t1: (%f, %f)->(%f, %f) \n " , v - > ou , v - > ov , v - > u1 , v - > v1 ) ;
# endif
}
else
{
v - > u1 - = rdp . tiles [ rdp . cur_tile + 1 ] . f_ul_s ;
v - > v1 - = rdp . tiles [ rdp . cur_tile + 1 ] . f_ul_t ;
v - > u1 = rdp . cur_cache [ 1 ] - > c_off + rdp . cur_cache [ 1 ] - > c_scl_x * v - > u1 ;
v - > v1 = rdp . cur_cache [ 1 ] - > c_off + rdp . cur_cache [ 1 ] - > c_scl_y * v - > v1 ;
}
v - > u1_w = v - > u1 / v - > w ;
v - > v1_w = v - > v1 / v - > w ;
}
// 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);
}
# ifdef EXTREME_LOGGING
FRDP ( " draw_tri. v[%d] ou=%f, ov = %f \n " , i , v - > ou , v - > ov ) ;
# endif
if ( v - > shade_mod ! = cmb . shade_mod_hash )
apply_shade_mods ( v ) ;
} //for
rdp . clip = 0 ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
if ( ( vtx [ 0 ] - > scr_off & 16 ) | |
( vtx [ 1 ] - > scr_off & 16 ) | |
( vtx [ 2 ] - > scr_off & 16 ) )
rdp . clip | = CLIP_WMIN ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
vtx [ 0 ] - > not_zclipped = vtx [ 1 ] - > not_zclipped = vtx [ 2 ] - > not_zclipped = 1 ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
if ( rdp . cur_cache [ 0 ] & & ( rdp . tex & 1 ) & & ( rdp . cur_cache [ 0 ] - > splits > 1 ) & & ! rdp . aTBuffTex [ 0 ] & & ! rdp . clip )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
int index , i , j , min_256 , max_256 , cur_256 , left_256 , right_256 ;
float percent ;
2013-04-04 21:22:19 +00:00
2016-01-25 09:58:29 +00:00
min_256 = minval ( ( int ) vtx [ 0 ] - > u0 , ( int ) vtx [ 1 ] - > u0 ) ; // bah, don't put two mins on one line
min_256 = minval ( min_256 , ( int ) vtx [ 2 ] - > u0 ) > > 8 ; // or it will be calculated twice
2013-04-04 21:22:19 +00:00
2016-01-25 09:58:29 +00:00
max_256 = maxval ( ( int ) vtx [ 0 ] - > u0 , ( int ) vtx [ 1 ] - > u0 ) ; // not like it makes much difference
max_256 = maxval ( max_256 , ( int ) vtx [ 2 ] - > u0 ) > > 8 ; // anyway :P
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
for ( cur_256 = min_256 ; cur_256 < = max_256 ; cur_256 + + )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
left_256 = cur_256 < < 8 ;
right_256 = ( cur_256 + 1 ) < < 8 ;
// Set vertex buffers
rdp . vtxbuf = rdp . vtx1 ; // copy from v to rdp.vtx1
rdp . vtxbuf2 = rdp . vtx2 ;
rdp . vtx_buffer = 0 ;
rdp . n_global = 3 ;
index = 0 ;
// ** Left plane **
for ( i = 0 ; i < 3 ; i + + )
{
j = i + 1 ;
if ( j = = 3 ) j = 0 ;
VERTEX * v1 = vtx [ i ] ;
VERTEX * v2 = vtx [ j ] ;
if ( v1 - > u0 > = left_256 )
{
if ( v2 - > u0 > = left_256 ) // Both are in, save the last one
{
rdp . vtxbuf [ index ] = * v2 ;
rdp . vtxbuf [ index ] . u0 - = left_256 ;
rdp . vtxbuf [ index + + ] . v0 + = cur_256 * rdp . cur_cache [ 0 ] - > splitheight ;
}
else // First is in, second is out, save intersection
{
percent = ( left_256 - v1 - > u0 ) / ( v2 - > u0 - v1 - > u0 ) ;
rdp . vtxbuf [ index ] . x = v1 - > x + ( v2 - > x - v1 - > x ) * percent ;
rdp . vtxbuf [ index ] . y = v1 - > y + ( v2 - > y - v1 - > y ) * percent ;
rdp . vtxbuf [ index ] . z = v1 - > z + ( v2 - > z - v1 - > z ) * percent ;
rdp . vtxbuf [ index ] . w = v1 - > w + ( v2 - > w - v1 - > w ) * percent ;
rdp . vtxbuf [ index ] . f = v1 - > f + ( v2 - > f - v1 - > f ) * percent ;
rdp . vtxbuf [ index ] . u0 = 0.5f ;
rdp . vtxbuf [ index ] . v0 = v1 - > v0 + ( v2 - > v0 - v1 - > v0 ) * percent +
cur_256 * rdp . cur_cache [ 0 ] - > splitheight ;
rdp . vtxbuf [ index ] . u1 = v1 - > u1 + ( v2 - > u1 - v1 - > u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = v1 - > v1 + ( v2 - > v1 - v1 - > v1 ) * percent ;
rdp . vtxbuf [ index ] . b = ( uint8_t ) ( v1 - > b + ( v2 - > b - v1 - > b ) * percent ) ;
rdp . vtxbuf [ index ] . g = ( uint8_t ) ( v1 - > g + ( v2 - > g - v1 - > g ) * percent ) ;
rdp . vtxbuf [ index ] . r = ( uint8_t ) ( v1 - > r + ( v2 - > r - v1 - > r ) * percent ) ;
rdp . vtxbuf [ index + + ] . a = ( uint8_t ) ( v1 - > a + ( v2 - > a - v1 - > a ) * percent ) ;
}
}
else
{
//if (v2->u0 < left_256) // Both are out, save nothing
if ( v2 - > u0 > = left_256 ) // First is out, second is in, save intersection & in point
{
percent = ( left_256 - v2 - > u0 ) / ( v1 - > u0 - v2 - > u0 ) ;
rdp . vtxbuf [ index ] . x = v2 - > x + ( v1 - > x - v2 - > x ) * percent ;
rdp . vtxbuf [ index ] . y = v2 - > y + ( v1 - > y - v2 - > y ) * percent ;
rdp . vtxbuf [ index ] . z = v2 - > z + ( v1 - > z - v2 - > z ) * percent ;
rdp . vtxbuf [ index ] . w = v2 - > w + ( v1 - > w - v2 - > w ) * percent ;
rdp . vtxbuf [ index ] . f = v2 - > f + ( v1 - > f - v2 - > f ) * percent ;
rdp . vtxbuf [ index ] . u0 = 0.5f ;
rdp . vtxbuf [ index ] . v0 = v2 - > v0 + ( v1 - > v0 - v2 - > v0 ) * percent +
cur_256 * rdp . cur_cache [ 0 ] - > splitheight ;
rdp . vtxbuf [ index ] . u1 = v2 - > u1 + ( v1 - > u1 - v2 - > u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = v2 - > v1 + ( v1 - > v1 - v2 - > v1 ) * percent ;
rdp . vtxbuf [ index ] . b = ( uint8_t ) ( v2 - > b + ( v1 - > b - v2 - > b ) * percent ) ;
rdp . vtxbuf [ index ] . g = ( uint8_t ) ( v2 - > g + ( v1 - > g - v2 - > g ) * percent ) ;
rdp . vtxbuf [ index ] . r = ( uint8_t ) ( v2 - > r + ( v1 - > r - v2 - > r ) * percent ) ;
rdp . vtxbuf [ index + + ] . a = ( uint8_t ) ( v2 - > a + ( v1 - > a - v2 - > a ) * percent ) ;
// Save the in point
rdp . vtxbuf [ index ] = * v2 ;
rdp . vtxbuf [ index ] . u0 - = left_256 ;
rdp . vtxbuf [ index + + ] . v0 + = cur_256 * rdp . cur_cache [ 0 ] - > splitheight ;
}
}
}
rdp . n_global = index ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
rdp . vtxbuf = rdp . vtx2 ; // now vtx1 holds the value, & vtx2 is the destination
rdp . vtxbuf2 = rdp . vtx1 ;
rdp . vtx_buffer ^ = 1 ;
index = 0 ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
for ( i = 0 ; i < rdp . n_global ; i + + )
{
j = i + 1 ;
if ( j = = rdp . n_global ) j = 0 ;
VERTEX * v1 = & rdp . vtxbuf2 [ i ] ;
VERTEX * v2 = & rdp . vtxbuf2 [ j ] ;
// ** Right plane **
if ( v1 - > u0 < = right_256 )
{
if ( v2 - > u0 < = right_256 ) // Both are in, save the last one
{
rdp . vtxbuf [ index ] = * v2 ;
rdp . vtxbuf [ index + + ] . not_zclipped = 0 ;
}
else // First is in, second is out, save intersection
{
percent = ( right_256 - v1 - > u0 ) / ( v2 - > u0 - v1 - > u0 ) ;
rdp . vtxbuf [ index ] . x = v1 - > x + ( v2 - > x - v1 - > x ) * percent ;
rdp . vtxbuf [ index ] . y = v1 - > y + ( v2 - > y - v1 - > y ) * percent ;
rdp . vtxbuf [ index ] . z = v1 - > z + ( v2 - > z - v1 - > z ) * percent ;
rdp . vtxbuf [ index ] . w = v1 - > w + ( v2 - > w - v1 - > w ) * percent ;
rdp . vtxbuf [ index ] . f = v1 - > f + ( v2 - > f - v1 - > f ) * percent ;
rdp . vtxbuf [ index ] . u0 = 255.5f ;
rdp . vtxbuf [ index ] . v0 = v1 - > v0 + ( v2 - > v0 - v1 - > v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = v1 - > u1 + ( v2 - > u1 - v1 - > u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = v1 - > v1 + ( v2 - > v1 - v1 - > v1 ) * percent ;
rdp . vtxbuf [ index ] . b = ( uint8_t ) ( v1 - > b + ( v2 - > b - v1 - > b ) * percent ) ;
rdp . vtxbuf [ index ] . g = ( uint8_t ) ( v1 - > g + ( v2 - > g - v1 - > g ) * percent ) ;
rdp . vtxbuf [ index ] . r = ( uint8_t ) ( v1 - > r + ( v2 - > r - v1 - > r ) * percent ) ;
rdp . vtxbuf [ index ] . a = ( uint8_t ) ( v1 - > a + ( v2 - > a - v1 - > a ) * percent ) ;
rdp . vtxbuf [ index + + ] . not_zclipped = 0 ;
}
}
else
{
//if (v2->u0 > 256.0f) // Both are out, save nothing
if ( v2 - > u0 < = right_256 ) // First is out, second is in, save intersection & in point
{
percent = ( right_256 - v2 - > u0 ) / ( v1 - > u0 - v2 - > u0 ) ;
rdp . vtxbuf [ index ] . x = v2 - > x + ( v1 - > x - v2 - > x ) * percent ;
rdp . vtxbuf [ index ] . y = v2 - > y + ( v1 - > y - v2 - > y ) * percent ;
rdp . vtxbuf [ index ] . z = v2 - > z + ( v1 - > z - v2 - > z ) * percent ;
rdp . vtxbuf [ index ] . w = v2 - > w + ( v1 - > w - v2 - > w ) * percent ;
rdp . vtxbuf [ index ] . f = v2 - > f + ( v1 - > f - v2 - > f ) * percent ;
rdp . vtxbuf [ index ] . u0 = 255.5f ;
rdp . vtxbuf [ index ] . v0 = v2 - > v0 + ( v1 - > v0 - v2 - > v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = v2 - > u1 + ( v1 - > u1 - v2 - > u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = v2 - > v1 + ( v1 - > v1 - v2 - > v1 ) * percent ;
rdp . vtxbuf [ index ] . b = ( uint8_t ) ( v2 - > b + ( v1 - > b - v2 - > b ) * percent ) ;
rdp . vtxbuf [ index ] . g = ( uint8_t ) ( v2 - > g + ( v1 - > g - v2 - > g ) * percent ) ;
rdp . vtxbuf [ index ] . r = ( uint8_t ) ( v2 - > r + ( v1 - > r - v2 - > r ) * percent ) ;
rdp . vtxbuf [ index ] . a = ( uint8_t ) ( v2 - > a + ( v1 - > a - v2 - > a ) * percent ) ;
rdp . vtxbuf [ index + + ] . not_zclipped = 0 ;
// Save the in point
rdp . vtxbuf [ index ] = * v2 ;
rdp . vtxbuf [ index + + ] . not_zclipped = 0 ;
}
}
}
rdp . n_global = index ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
do_triangle_stuff ( linew , TRUE ) ;
2013-04-04 21:22:19 +00:00
}
}
2016-01-20 09:59:35 +00:00
else
{
// Set vertex buffers
rdp . vtxbuf = rdp . vtx1 ; // copy from v to rdp.vtx1
rdp . vtxbuf2 = rdp . vtx2 ;
rdp . vtx_buffer = 0 ;
rdp . n_global = 3 ;
rdp . vtxbuf [ 0 ] = * vtx [ 0 ] ;
rdp . vtxbuf [ 0 ] . number = 1 ;
rdp . vtxbuf [ 1 ] = * vtx [ 1 ] ;
rdp . vtxbuf [ 1 ] . number = 2 ;
rdp . vtxbuf [ 2 ] = * vtx [ 2 ] ;
rdp . vtxbuf [ 2 ] . number = 4 ;
do_triangle_stuff ( linew , FALSE ) ;
}
2013-04-04 21:22:19 +00:00
}
# define interp2p(a, b, r) (a + (b - a) * r)
//*
static void InterpolateColors ( VERTEX & va , VERTEX & vb , VERTEX & res , float percent )
{
2016-01-20 09:59:35 +00:00
res . b = ( uint8_t ) interp2p ( va . b , vb . b , percent ) ;
res . g = ( uint8_t ) interp2p ( va . g , vb . g , percent ) ; ;
res . r = ( uint8_t ) interp2p ( va . r , vb . r , percent ) ; ;
res . a = ( uint8_t ) interp2p ( va . a , vb . a , percent ) ; ;
res . f = interp2p ( va . f , vb . f , percent ) ; ;
2013-04-04 21:22:19 +00:00
}
//*/
//
// clip_w - clips aint the z-axis
//
2016-01-20 09:59:35 +00:00
static void clip_w ( int interpolate_colors )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
int i , j , index , n = rdp . n_global ;
float percent ;
// Swap vertex buffers
VERTEX * tmp = rdp . vtxbuf2 ;
rdp . vtxbuf2 = rdp . vtxbuf ;
rdp . vtxbuf = tmp ;
rdp . vtx_buffer ^ = 1 ;
index = 0 ;
// Check the vertices for clipping
for ( i = 0 ; i < n ; i + + )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
j = i + 1 ;
if ( j = = 3 ) j = 0 ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
if ( Vi . w > = 0.01f )
{
if ( Vj . w > = 0.01f ) // Both are in, save the last one
{
rdp . vtxbuf [ index ] = Vj ;
rdp . vtxbuf [ index + + ] . not_zclipped = 1 ;
}
else // First is in, second is out, save intersection
{
percent = ( - Vi . w ) / ( Vj . w - Vi . w ) ;
rdp . vtxbuf [ index ] . not_zclipped = 0 ;
rdp . vtxbuf [ index ] . x = Vi . x + ( Vj . x - Vi . x ) * percent ;
rdp . vtxbuf [ index ] . y = Vi . y + ( Vj . y - Vi . y ) * percent ;
rdp . vtxbuf [ index ] . z = Vi . z + ( Vj . z - Vi . z ) * percent ;
2016-01-27 05:26:28 +00:00
rdp . vtxbuf [ index ] . w = 1.00f ;
2016-01-20 09:59:35 +00:00
rdp . vtxbuf [ index ] . u0 = Vi . u0 + ( Vj . u0 - Vi . u0 ) * percent ;
rdp . vtxbuf [ index ] . v0 = Vi . v0 + ( Vj . v0 - Vi . v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = Vi . u1 + ( Vj . u1 - Vi . u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = Vi . v1 + ( Vj . v1 - Vi . v1 ) * percent ;
if ( interpolate_colors )
InterpolateColors ( Vi , Vj , rdp . vtxbuf [ index + + ] , percent ) ;
else
rdp . vtxbuf [ index + + ] . number = Vi . number | Vj . number ;
}
}
else
{
//if (Vj.w < 0.01f) // Both are out, save nothing
if ( Vj . w > = 0.01f ) // First is out, second is in, save intersection & in point
{
percent = ( - Vj . w ) / ( Vi . w - Vj . w ) ;
rdp . vtxbuf [ index ] . not_zclipped = 0 ;
rdp . vtxbuf [ index ] . x = Vj . x + ( Vi . x - Vj . x ) * percent ;
rdp . vtxbuf [ index ] . y = Vj . y + ( Vi . y - Vj . y ) * percent ;
rdp . vtxbuf [ index ] . z = Vj . z + ( Vi . z - Vj . z ) * percent ;
2016-01-27 05:26:28 +00:00
rdp . vtxbuf [ index ] . w = 1.00f ;
2016-01-20 09:59:35 +00:00
rdp . vtxbuf [ index ] . u0 = Vj . u0 + ( Vi . u0 - Vj . u0 ) * percent ;
rdp . vtxbuf [ index ] . v0 = Vj . v0 + ( Vi . v0 - Vj . v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = Vj . u1 + ( Vi . u1 - Vj . u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = Vj . v1 + ( Vi . v1 - Vj . v1 ) * percent ;
if ( interpolate_colors )
InterpolateColors ( Vj , Vi , rdp . vtxbuf [ index + + ] , percent ) ;
else
rdp . vtxbuf [ index + + ] . number = Vi . number | Vj . number ;
// Save the in point
rdp . vtxbuf [ index ] = Vj ;
rdp . vtxbuf [ index + + ] . not_zclipped = 1 ;
}
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
rdp . n_global = index ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
static void render_tri ( uint16_t linew , int old_interpolate ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
void do_triangle_stuff ( uint16_t linew , int old_interpolate ) // what else?? do the triangle stuff :P (to keep from writing code twice)
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
int i ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
if ( rdp . clip & CLIP_WMIN )
clip_w ( old_interpolate ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
float maxZ = ( rdp . zsrc ! = 1 ) ? rdp . view_trans [ 2 ] + rdp . view_scale [ 2 ] : rdp . prim_depth ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
uint8_t no_clip = 2 ;
for ( i = 0 ; i < rdp . n_global ; i + + )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
if ( rdp . vtxbuf [ i ] . not_zclipped ) // && rdp.zsrc != 1)
{
# ifdef EXTREME_LOGGING
FRDP ( " * NOT ZCLIPPPED: %d \n " , rdp . vtxbuf [ i ] . number ) ;
# endif
rdp . vtxbuf [ i ] . x = rdp . vtxbuf [ i ] . sx ;
rdp . vtxbuf [ i ] . y = rdp . vtxbuf [ i ] . sy ;
rdp . vtxbuf [ i ] . z = rdp . vtxbuf [ i ] . sz ;
rdp . vtxbuf [ i ] . q = rdp . vtxbuf [ i ] . oow ;
rdp . vtxbuf [ i ] . u0 = rdp . vtxbuf [ i ] . u0_w ;
rdp . vtxbuf [ i ] . v0 = rdp . vtxbuf [ i ] . v0_w ;
rdp . vtxbuf [ i ] . u1 = rdp . vtxbuf [ i ] . u1_w ;
rdp . vtxbuf [ i ] . v1 = rdp . vtxbuf [ i ] . v1_w ;
}
else
{
2013-04-04 21:22:19 +00:00
# ifdef EXTREME_LOGGING
2016-01-20 09:59:35 +00:00
FRDP ( " * ZCLIPPED: %d \n " , rdp . vtxbuf [ i ] . number ) ;
2013-04-04 21:22:19 +00:00
# endif
2016-01-20 09:59:35 +00:00
rdp . vtxbuf [ i ] . q = 1.0f / rdp . vtxbuf [ i ] . w ;
rdp . vtxbuf [ i ] . x = rdp . view_trans [ 0 ] + rdp . vtxbuf [ i ] . x * rdp . vtxbuf [ i ] . q * rdp . view_scale [ 0 ] + rdp . offset_x ;
rdp . vtxbuf [ i ] . y = rdp . view_trans [ 1 ] + rdp . vtxbuf [ i ] . y * rdp . vtxbuf [ i ] . q * rdp . view_scale [ 1 ] + rdp . offset_y ;
rdp . vtxbuf [ i ] . z = rdp . view_trans [ 2 ] + rdp . vtxbuf [ i ] . z * rdp . vtxbuf [ i ] . q * rdp . view_scale [ 2 ] ;
if ( rdp . tex > = 1 )
{
rdp . vtxbuf [ i ] . u0 * = rdp . vtxbuf [ i ] . q ;
rdp . vtxbuf [ i ] . v0 * = rdp . vtxbuf [ i ] . q ;
}
if ( rdp . tex > = 2 )
{
rdp . vtxbuf [ i ] . u1 * = rdp . vtxbuf [ i ] . q ;
rdp . vtxbuf [ i ] . v1 * = rdp . vtxbuf [ i ] . q ;
}
}
if ( rdp . zsrc = = 1 )
rdp . vtxbuf [ i ] . z = rdp . prim_depth ;
// Don't remove clipping, or it will freeze
if ( rdp . vtxbuf [ i ] . x > rdp . clip_max_x ) rdp . clip | = CLIP_XMAX ;
if ( rdp . vtxbuf [ i ] . x < rdp . clip_min_x ) rdp . clip | = CLIP_XMIN ;
if ( rdp . vtxbuf [ i ] . y > rdp . clip_max_y ) rdp . clip | = CLIP_YMAX ;
if ( rdp . vtxbuf [ i ] . y < rdp . clip_min_y ) rdp . clip | = CLIP_YMIN ;
if ( rdp . vtxbuf [ i ] . z > maxZ ) rdp . clip | = CLIP_ZMAX ;
if ( rdp . vtxbuf [ i ] . z < 0.0f ) rdp . clip | = CLIP_ZMIN ;
no_clip & = rdp . vtxbuf [ i ] . screen_translated ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( no_clip )
rdp . clip = 0 ;
2013-04-04 21:22:19 +00:00
else
{
2016-01-20 09:59:35 +00:00
if ( ! settings . clip_zmin )
rdp . clip & = ~ CLIP_ZMIN ;
if ( ! settings . clip_zmax )
rdp . clip & = ~ CLIP_ZMAX ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
render_tri ( linew , old_interpolate ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
void do_triangle_stuff_2 ( uint16_t linew )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
rdp . clip = 0 ;
for ( int i = 0 ; i < rdp . n_global ; i + + )
{
// Don't remove clipping, or it will freeze
if ( rdp . vtxbuf [ i ] . x > rdp . clip_max_x ) rdp . clip | = CLIP_XMAX ;
if ( rdp . vtxbuf [ i ] . x < rdp . clip_min_x ) rdp . clip | = CLIP_XMIN ;
if ( rdp . vtxbuf [ i ] . y > rdp . clip_max_y ) rdp . clip | = CLIP_YMAX ;
if ( rdp . vtxbuf [ i ] . y < rdp . clip_min_y ) rdp . clip | = CLIP_YMIN ;
}
render_tri ( linew , TRUE ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 06:17:45 +00:00
__inline uint8_t real_to_char ( double x )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
return ( uint8_t ) ( ( ( int ) floor ( x + 0.5 ) ) & 0xFF ) ;
2013-04-04 21:22:19 +00:00
}
//*
static void InterpolateColors2 ( VERTEX & va , VERTEX & vb , VERTEX & res , float percent )
{
2016-01-20 09:59:35 +00:00
float w = 1.0f / ( va . oow + ( vb . oow - va . oow ) * percent ) ;
// res.oow = va.oow + (vb.oow-va.oow) * percent;
// res.q = res.oow;
float ba = va . b * va . oow ;
float bb = vb . b * vb . oow ;
res . b = real_to_char ( interp2p ( ba , bb , percent ) * w ) ;
float ga = va . g * va . oow ;
float gb = vb . g * vb . oow ;
res . g = real_to_char ( interp2p ( ga , gb , percent ) * w ) ;
float ra = va . r * va . oow ;
float rb = vb . r * vb . oow ;
res . r = real_to_char ( interp2p ( ra , rb , percent ) * w ) ;
float aa = va . a * va . oow ;
float ab = vb . a * vb . oow ;
res . a = real_to_char ( interp2p ( aa , ab , percent ) * w ) ;
float fa = va . f * va . oow ;
float fb = vb . f * vb . oow ;
res . f = interp2p ( fa , fb , percent ) * w ;
/*
float u0a = va . u0_w * va . oow ;
float u0b = vb . u0_w * vb . oow ;
res . u0 = ( u0a + ( u0b - u0a ) * percent ) * w ;
float v0a = va . v0_w * va . oow ;
float v0b = vb . v0_w * vb . oow ;
res . v0 = ( v0a + ( v0b - v0a ) * percent ) * w ;
float u1a = va . u1_w * va . oow ;
float u1b = vb . u1_w * vb . oow ;
res . u1 = ( u1a + ( u1b - u1a ) * percent ) * w ;
float v1a = va . v1_w * va . oow ;
float v1b = vb . v1_w * vb . oow ;
res . v1 = ( v1a + ( v1b - v1a ) * percent ) * w ;
*/
2013-04-04 21:22:19 +00:00
}
//*/
typedef struct {
2016-01-20 09:59:35 +00:00
double d ;
double x ;
double y ;
2013-04-04 21:22:19 +00:00
} LineEuqationType ;
static double EvaLine ( LineEuqationType & li , double x , double y )
{
2016-01-20 09:59:35 +00:00
return li . x * x + li . y * y + li . d ;
2013-04-04 21:22:19 +00:00
}
static void Create1LineEq ( LineEuqationType & l , VERTEX & v1 , VERTEX & v2 , VERTEX & v3 )
{
2016-01-20 09:59:35 +00:00
// Line between (x1,y1) to (x2,y2)
l . x = v2 . sy - v1 . sy ;
l . y = v1 . sx - v2 . sx ;
l . d = - ( l . x * v2 . sx + ( l . y ) * v2 . sy ) ;
if ( EvaLine ( l , v3 . sx , v3 . sy ) * v3 . oow < 0 )
{
l . x = - l . x ;
l . y = - l . y ;
l . d = - l . d ;
}
2013-04-04 21:22:19 +00:00
}
__inline double interp3p ( float a , float b , float c , double r1 , double r2 )
{
2016-01-20 09:59:35 +00:00
return ( a ) + ( ( ( b ) + ( ( c ) - ( b ) ) * ( r2 ) ) - ( a ) ) * ( r1 ) ;
2013-04-04 21:22:19 +00:00
}
2015-03-11 21:15:42 +00:00
/*
2013-04-04 21:22:19 +00:00
# define interp3p(a, b, c, r1, r2) \
( a + ( ( ( b ) + ( ( c ) - ( b ) ) * ( r2 ) ) - ( a ) ) * ( r1 ) )
2016-01-20 09:59:35 +00:00
*/
2013-04-04 21:22:19 +00:00
static void InterpolateColors3 ( VERTEX & v1 , VERTEX & v2 , VERTEX & v3 , VERTEX & out )
{
2016-01-20 09:59:35 +00:00
LineEuqationType line ;
Create1LineEq ( line , v2 , v3 , v1 ) ;
double aDot = ( out . x * line . x + out . y * line . y ) ;
double bDot = ( v1 . sx * line . x + v1 . sy * line . y ) ;
double scale1 = ( - line . d - aDot ) / ( bDot - aDot ) ;
double tx = out . x + scale1 * ( v1 . sx - out . x ) ;
double ty = out . y + scale1 * ( v1 . sy - out . y ) ;
double s1 = 101.0 , s2 = 101.0 ;
double den = tx - v1 . sx ;
if ( fabs ( den ) > 1.0 )
s1 = ( out . x - v1 . sx ) / den ;
if ( s1 > 100.0f )
s1 = ( out . y - v1 . sy ) / ( ty - v1 . sy ) ;
den = v3 . sx - v2 . sx ;
if ( fabs ( den ) > 1.0 )
s2 = ( tx - v2 . sx ) / den ;
if ( s2 > 100.0f )
s2 = ( ty - v2 . sy ) / ( v3 . sy - v2 . sy ) ;
double w = 1.0 / interp3p ( v1 . oow , v2 . oow , v3 . oow , s1 , s2 ) ;
out . r = real_to_char ( interp3p ( v1 . r * v1 . oow , v2 . r * v2 . oow , v3 . r * v3 . oow , s1 , s2 ) * w ) ;
out . g = real_to_char ( interp3p ( v1 . g * v1 . oow , v2 . g * v2 . oow , v3 . g * v3 . oow , s1 , s2 ) * w ) ;
out . b = real_to_char ( interp3p ( v1 . b * v1 . oow , v2 . b * v2 . oow , v3 . b * v3 . oow , s1 , s2 ) * w ) ;
out . a = real_to_char ( interp3p ( v1 . a * v1 . oow , v2 . a * v2 . oow , v3 . a * v3 . oow , s1 , s2 ) * w ) ;
out . f = ( float ) ( interp3p ( v1 . f * v1 . oow , v2 . f * v2 . oow , v3 . f * v3 . oow , s1 , s2 ) * w ) ;
/*
out . u0 = interp3p ( v1 . u0_w * v1 . oow , v2 . u0_w * v2 . oow , v3 . u0_w * v3 . oow , s1 , s2 ) / oow ;
out . v0 = interp3p ( v1 . v0_w * v1 . oow , v2 . v0_w * v2 . oow , v3 . v0_w * v3 . oow , s1 , s2 ) / oow ;
out . u1 = interp3p ( v1 . u1_w * v1 . oow , v2 . u1_w * v2 . oow , v3 . u1_w * v3 . oow , s1 , s2 ) / oow ;
out . v1 = interp3p ( v1 . v1_w * v1 . oow , v2 . v1_w * v2 . oow , v3 . v1_w * v3 . oow , s1 , s2 ) / oow ;
*/
2013-04-04 21:22:19 +00:00
}
static void CalculateLOD ( VERTEX * v , int n )
{
2016-01-20 09:59:35 +00:00
//rdp.update |= UPDATE_TEXTURE;
/*
if ( rdp . lod_calculated )
{
float detailmax ;
if ( dc0_detailmax < 0.5 )
detailmax = rdp . lod_fraction ;
else
detailmax = 1.0f - rdp . lod_fraction ;
grTexDetailControl ( GR_TMU0 , dc0_lodbias , dc0_detailscale , detailmax ) ;
if ( num_tmu = = 2 )
grTexDetailControl ( GR_TMU1 , dc1_lodbias , dc1_detailscale , detailmax ) ;
return ;
}
*/
float deltaS , deltaT ;
float deltaX , deltaY ;
double deltaTexels , deltaPixels , lodFactor = 0 ;
double intptr ;
float s_scale = rdp . tiles [ rdp . cur_tile ] . width / 255.0f ;
float t_scale = rdp . tiles [ rdp . cur_tile ] . height / 255.0f ;
if ( settings . lodmode = = 1 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
deltaS = ( v [ 1 ] . u0 / v [ 1 ] . q - v [ 0 ] . u0 / v [ 0 ] . q ) * s_scale ;
deltaT = ( v [ 1 ] . v0 / v [ 1 ] . q - v [ 0 ] . v0 / v [ 0 ] . q ) * t_scale ;
deltaTexels = sqrt ( deltaS * deltaS + deltaT * deltaT ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
deltaX = ( v [ 1 ] . x - v [ 0 ] . x ) / rdp . scale_x ;
deltaY = ( v [ 1 ] . y - v [ 0 ] . y ) / rdp . scale_y ;
deltaPixels = sqrt ( deltaX * deltaX + deltaY * deltaY ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
lodFactor = deltaTexels / deltaPixels ;
}
else
{
int i , j ;
for ( i = 0 ; i < n ; i + + )
{
j = ( i < n - 1 ) ? i + 1 : 0 ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
deltaS = ( v [ j ] . u0 / v [ j ] . q - v [ i ] . u0 / v [ i ] . q ) * s_scale ;
deltaT = ( v [ j ] . v0 / v [ j ] . q - v [ i ] . v0 / v [ i ] . q ) * t_scale ;
// deltaS = v[j].ou - v[i].ou;
// deltaT = v[j].ov - v[i].ov;
deltaTexels = sqrt ( deltaS * deltaS + deltaT * deltaT ) ;
deltaX = ( v [ j ] . x - v [ i ] . x ) / rdp . scale_x ;
deltaY = ( v [ j ] . y - v [ i ] . y ) / rdp . scale_y ;
deltaPixels = sqrt ( deltaX * deltaX + deltaY * deltaY ) ;
lodFactor + = deltaTexels / deltaPixels ;
}
// Divide by n (n edges) to find average
lodFactor = lodFactor / n ;
}
int ilod = ( int ) lodFactor ;
2016-01-25 09:58:29 +00:00
int lod_tile = minval ( ( int ) ( log10f ( ( float ) ilod ) / log10f ( 2.0f ) ) , rdp . cur_tile + rdp . mipmap_level ) ;
2016-01-20 09:59:35 +00:00
float lod_fraction = 1.0f ;
if ( lod_tile < rdp . cur_tile + rdp . mipmap_level )
{
2016-01-25 09:58:29 +00:00
lod_fraction = maxval ( ( float ) modf ( lodFactor / pow ( 2. , lod_tile ) , & intptr ) , rdp . prim_lodmin / 255.0f ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
float detailmax ;
if ( cmb . dc0_detailmax < 0.5f )
detailmax = lod_fraction ;
else
detailmax = 1.0f - lod_fraction ;
grTexDetailControl ( GR_TMU0 , cmb . dc0_lodbias , cmb . dc0_detailscale , detailmax ) ;
if ( voodoo . num_tmu = = 2 )
grTexDetailControl ( GR_TMU1 , cmb . dc1_lodbias , cmb . dc1_detailscale , detailmax ) ;
FRDP ( " CalculateLOD factor: %f, tile: %d, lod_fraction: %f \n " , ( float ) lodFactor , lod_tile , lod_fraction ) ;
2013-04-04 21:22:19 +00:00
}
float ScaleZ ( float z )
{
2016-01-20 09:59:35 +00:00
if ( settings . n64_z_scale )
{
int iz = ( int ) ( z * 8.0f + 0.5f ) ;
if ( iz < 0 ) iz = 0 ;
else if ( iz > = 0x40000 ) iz = 0x40000 - 1 ;
return ( float ) zLUT [ iz ] ;
}
if ( z < 0.0f ) return 0.0f ;
z * = 1.9f ;
if ( z > 65534.0f ) return 65534.0f ;
return z ;
2013-04-04 21:22:19 +00:00
}
static void DepthBuffer ( VERTEX * vtx , int n )
{
2016-01-20 09:59:35 +00:00
if ( fb_depth_render_enabled & & ! ( settings . hacks & hack_RE2 ) & & dzdx & & ( rdp . flags & ZBUF_UPDATE ) )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
vertexi v [ 12 ] ;
if ( u_cull_mode = = 1 ) //cull front
{
for ( int i = 0 ; i < n ; i + + )
{
v [ i ] . x = ( int ) ( ( vtx [ n - i - 1 ] . x - rdp . offset_x ) / rdp . scale_x * 65536.0 ) ;
v [ i ] . y = ( int ) ( ( vtx [ n - i - 1 ] . y - rdp . offset_y ) / rdp . scale_y * 65536.0 ) ;
v [ i ] . z = ( int ) ( vtx [ n - i - 1 ] . z * 65536.0 ) ;
}
}
else
{
for ( int i = 0 ; i < n ; i + + )
{
v [ i ] . x = ( int ) ( ( vtx [ i ] . x - rdp . offset_x ) / rdp . scale_x * 65536.0 ) ;
v [ i ] . y = ( int ) ( ( vtx [ i ] . y - rdp . offset_y ) / rdp . scale_y * 65536.0 ) ;
v [ i ] . z = ( int ) ( vtx [ i ] . z * 65536.0 ) ;
}
}
Rasterize ( v , n , dzdx ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
for ( int i = 0 ; i < n ; i + + )
vtx [ i ] . z = ScaleZ ( vtx [ i ] . z ) ;
2013-04-04 21:22:19 +00:00
}
/*
std : : ofstream loga ;
# define LOGG(x) loga.open("glide_log.txt",std::ios::app); loga << x; loga.flush(); loga.close();
__inline void FRDP2 ( char * fmt , . . . )
{
va_list ap ;
va_start ( ap , fmt ) ;
vsprintf ( out_buf , fmt , ap ) ;
LOGG ( out_buf ) ;
va_end ( ap ) ;
}
//*/
//#define LOGG(x)
//#define FRDP2(x)
void clip_tri ( int interpolate_colors )
{
2016-01-20 09:59:35 +00:00
int i , j , index , n = rdp . n_global ;
float percent ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
// Check which clipping is needed
if ( rdp . clip & CLIP_XMAX ) // right of the screen
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
// Swap vertex buffers
VERTEX * tmp = rdp . vtxbuf2 ;
rdp . vtxbuf2 = rdp . vtxbuf ;
rdp . vtxbuf = tmp ;
rdp . vtx_buffer ^ = 1 ;
index = 0 ;
// Check the vertices for clipping
for ( i = 0 ; i < n ; i + + )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
j = i + 1 ;
if ( j = = n ) j = 0 ;
if ( Vi . x < = rdp . clip_max_x )
{
if ( Vj . x < = rdp . clip_max_x ) // Both are in, save the last one
{
rdp . vtxbuf [ index + + ] = Vj ;
}
else // First is in, second is out, save intersection
{
percent = ( rdp . clip_max_x - Vi . x ) / ( Vj . x - Vi . x ) ;
rdp . vtxbuf [ index ] . x = rdp . clip_max_x ;
rdp . vtxbuf [ index ] . y = Vi . y + ( Vj . y - Vi . y ) * percent ;
rdp . vtxbuf [ index ] . z = Vi . z + ( Vj . z - Vi . z ) * percent ;
rdp . vtxbuf [ index ] . q = Vi . q + ( Vj . q - Vi . q ) * percent ;
rdp . vtxbuf [ index ] . u0 = Vi . u0 + ( Vj . u0 - Vi . u0 ) * percent ;
rdp . vtxbuf [ index ] . v0 = Vi . v0 + ( Vj . v0 - Vi . v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = Vi . u1 + ( Vj . u1 - Vi . u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = Vi . v1 + ( Vj . v1 - Vi . v1 ) * percent ;
if ( interpolate_colors )
InterpolateColors ( Vi , Vj , rdp . vtxbuf [ index + + ] , percent ) ;
else
rdp . vtxbuf [ index + + ] . number = Vi . number | Vj . number | 8 ;
}
}
else
{
//if (Vj.x > rdp.clip_max_x) // Both are out, save nothing
if ( Vj . x < = rdp . clip_max_x ) // First is out, second is in, save intersection & in point
{
percent = ( rdp . clip_max_x - Vj . x ) / ( Vi . x - Vj . x ) ;
rdp . vtxbuf [ index ] . x = rdp . clip_max_x ;
rdp . vtxbuf [ index ] . y = Vj . y + ( Vi . y - Vj . y ) * percent ;
rdp . vtxbuf [ index ] . z = Vj . z + ( Vi . z - Vj . z ) * percent ;
rdp . vtxbuf [ index ] . q = Vj . q + ( Vi . q - Vj . q ) * percent ;
rdp . vtxbuf [ index ] . u0 = Vj . u0 + ( Vi . u0 - Vj . u0 ) * percent ;
rdp . vtxbuf [ index ] . v0 = Vj . v0 + ( Vi . v0 - Vj . v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = Vj . u1 + ( Vi . u1 - Vj . u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = Vj . v1 + ( Vi . v1 - Vj . v1 ) * percent ;
if ( interpolate_colors )
InterpolateColors ( Vj , Vi , rdp . vtxbuf [ index + + ] , percent ) ;
else
rdp . vtxbuf [ index + + ] . number = Vi . number | Vj . number | 8 ;
// Save the in point
rdp . vtxbuf [ index + + ] = Vj ;
}
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
n = index ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( rdp . clip & CLIP_XMIN ) // left of the screen
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
// Swap vertex buffers
VERTEX * tmp = rdp . vtxbuf2 ;
rdp . vtxbuf2 = rdp . vtxbuf ;
rdp . vtxbuf = tmp ;
rdp . vtx_buffer ^ = 1 ;
index = 0 ;
// Check the vertices for clipping
for ( i = 0 ; i < n ; i + + )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
j = i + 1 ;
if ( j = = n ) j = 0 ;
if ( Vi . x > = rdp . clip_min_x )
{
if ( Vj . x > = rdp . clip_min_x ) // Both are in, save the last one
{
rdp . vtxbuf [ index + + ] = Vj ;
}
else // First is in, second is out, save intersection
{
percent = ( rdp . clip_min_x - Vi . x ) / ( Vj . x - Vi . x ) ;
rdp . vtxbuf [ index ] . x = rdp . clip_min_x ;
rdp . vtxbuf [ index ] . y = Vi . y + ( Vj . y - Vi . y ) * percent ;
rdp . vtxbuf [ index ] . z = Vi . z + ( Vj . z - Vi . z ) * percent ;
rdp . vtxbuf [ index ] . q = Vi . q + ( Vj . q - Vi . q ) * percent ;
rdp . vtxbuf [ index ] . u0 = Vi . u0 + ( Vj . u0 - Vi . u0 ) * percent ;
rdp . vtxbuf [ index ] . v0 = Vi . v0 + ( Vj . v0 - Vi . v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = Vi . u1 + ( Vj . u1 - Vi . u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = Vi . v1 + ( Vj . v1 - Vi . v1 ) * percent ;
if ( interpolate_colors )
InterpolateColors ( Vi , Vj , rdp . vtxbuf [ index + + ] , percent ) ;
else
rdp . vtxbuf [ index + + ] . number = Vi . number | Vj . number | 8 ;
}
}
else
{
//if (Vj.x < rdp.clip_min_x) // Both are out, save nothing
if ( Vj . x > = rdp . clip_min_x ) // First is out, second is in, save intersection & in point
{
percent = ( rdp . clip_min_x - Vj . x ) / ( Vi . x - Vj . x ) ;
rdp . vtxbuf [ index ] . x = rdp . clip_min_x ;
rdp . vtxbuf [ index ] . y = Vj . y + ( Vi . y - Vj . y ) * percent ;
rdp . vtxbuf [ index ] . z = Vj . z + ( Vi . z - Vj . z ) * percent ;
rdp . vtxbuf [ index ] . q = Vj . q + ( Vi . q - Vj . q ) * percent ;
rdp . vtxbuf [ index ] . u0 = Vj . u0 + ( Vi . u0 - Vj . u0 ) * percent ;
rdp . vtxbuf [ index ] . v0 = Vj . v0 + ( Vi . v0 - Vj . v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = Vj . u1 + ( Vi . u1 - Vj . u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = Vj . v1 + ( Vi . v1 - Vj . v1 ) * percent ;
if ( interpolate_colors )
InterpolateColors ( Vj , Vi , rdp . vtxbuf [ index + + ] , percent ) ;
else
rdp . vtxbuf [ index + + ] . number = Vi . number | Vj . number | 8 ;
// Save the in point
rdp . vtxbuf [ index + + ] = Vj ;
}
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
n = index ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( rdp . clip & CLIP_YMAX ) // top of the screen
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
// Swap vertex buffers
VERTEX * tmp = rdp . vtxbuf2 ;
rdp . vtxbuf2 = rdp . vtxbuf ;
rdp . vtxbuf = tmp ;
rdp . vtx_buffer ^ = 1 ;
index = 0 ;
// Check the vertices for clipping
for ( i = 0 ; i < n ; i + + )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
j = i + 1 ;
if ( j = = n ) j = 0 ;
if ( Vi . y < = rdp . clip_max_y )
{
if ( Vj . y < = rdp . clip_max_y ) // Both are in, save the last one
{
rdp . vtxbuf [ index + + ] = Vj ;
}
else // First is in, second is out, save intersection
{
percent = ( rdp . clip_max_y - Vi . y ) / ( Vj . y - Vi . y ) ;
rdp . vtxbuf [ index ] . x = Vi . x + ( Vj . x - Vi . x ) * percent ;
rdp . vtxbuf [ index ] . y = rdp . clip_max_y ;
rdp . vtxbuf [ index ] . z = Vi . z + ( Vj . z - Vi . z ) * percent ;
rdp . vtxbuf [ index ] . q = Vi . q + ( Vj . q - Vi . q ) * percent ;
rdp . vtxbuf [ index ] . u0 = Vi . u0 + ( Vj . u0 - Vi . u0 ) * percent ;
rdp . vtxbuf [ index ] . v0 = Vi . v0 + ( Vj . v0 - Vi . v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = Vi . u1 + ( Vj . u1 - Vi . u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = Vi . v1 + ( Vj . v1 - Vi . v1 ) * percent ;
if ( interpolate_colors )
InterpolateColors ( Vi , Vj , rdp . vtxbuf [ index + + ] , percent ) ;
else
rdp . vtxbuf [ index + + ] . number = Vi . number | Vj . number | 16 ;
}
}
else
{
//if (Vj.y > rdp.clip_max_y) // Both are out, save nothing
if ( Vj . y < = rdp . clip_max_y ) // First is out, second is in, save intersection & in point
{
percent = ( rdp . clip_max_y - Vj . y ) / ( Vi . y - Vj . y ) ;
rdp . vtxbuf [ index ] . x = Vj . x + ( Vi . x - Vj . x ) * percent ;
rdp . vtxbuf [ index ] . y = rdp . clip_max_y ;
rdp . vtxbuf [ index ] . z = Vj . z + ( Vi . z - Vj . z ) * percent ;
rdp . vtxbuf [ index ] . q = Vj . q + ( Vi . q - Vj . q ) * percent ;
rdp . vtxbuf [ index ] . u0 = Vj . u0 + ( Vi . u0 - Vj . u0 ) * percent ;
rdp . vtxbuf [ index ] . v0 = Vj . v0 + ( Vi . v0 - Vj . v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = Vj . u1 + ( Vi . u1 - Vj . u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = Vj . v1 + ( Vi . v1 - Vj . v1 ) * percent ;
if ( interpolate_colors )
InterpolateColors ( Vj , Vi , rdp . vtxbuf [ index + + ] , percent ) ;
else
rdp . vtxbuf [ index + + ] . number = Vi . number | Vj . number | 16 ;
// Save the in point
rdp . vtxbuf [ index + + ] = Vj ;
}
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
n = index ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( rdp . clip & CLIP_YMIN ) // bottom of the screen
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
// Swap vertex buffers
VERTEX * tmp = rdp . vtxbuf2 ;
rdp . vtxbuf2 = rdp . vtxbuf ;
rdp . vtxbuf = tmp ;
rdp . vtx_buffer ^ = 1 ;
index = 0 ;
// Check the vertices for clipping
for ( i = 0 ; i < n ; i + + )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
j = i + 1 ;
if ( j = = n ) j = 0 ;
if ( Vi . y > = rdp . clip_min_y )
{
if ( Vj . y > = rdp . clip_min_y ) // Both are in, save the last one
{
rdp . vtxbuf [ index + + ] = Vj ;
}
else // First is in, second is out, save intersection
{
percent = ( rdp . clip_min_y - Vi . y ) / ( Vj . y - Vi . y ) ;
rdp . vtxbuf [ index ] . x = Vi . x + ( Vj . x - Vi . x ) * percent ;
rdp . vtxbuf [ index ] . y = rdp . clip_min_y ;
rdp . vtxbuf [ index ] . z = Vi . z + ( Vj . z - Vi . z ) * percent ;
rdp . vtxbuf [ index ] . q = Vi . q + ( Vj . q - Vi . q ) * percent ;
rdp . vtxbuf [ index ] . u0 = Vi . u0 + ( Vj . u0 - Vi . u0 ) * percent ;
rdp . vtxbuf [ index ] . v0 = Vi . v0 + ( Vj . v0 - Vi . v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = Vi . u1 + ( Vj . u1 - Vi . u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = Vi . v1 + ( Vj . v1 - Vi . v1 ) * percent ;
if ( interpolate_colors )
InterpolateColors ( Vi , Vj , rdp . vtxbuf [ index + + ] , percent ) ;
else
rdp . vtxbuf [ index + + ] . number = Vi . number | Vj . number | 16 ;
}
}
else
{
//if (Vj.y < rdp.clip_min_y) // Both are out, save nothing
if ( Vj . y > = rdp . clip_min_y ) // First is out, second is in, save intersection & in point
{
percent = ( rdp . clip_min_y - Vj . y ) / ( Vi . y - Vj . y ) ;
rdp . vtxbuf [ index ] . x = Vj . x + ( Vi . x - Vj . x ) * percent ;
rdp . vtxbuf [ index ] . y = rdp . clip_min_y ;
rdp . vtxbuf [ index ] . z = Vj . z + ( Vi . z - Vj . z ) * percent ;
rdp . vtxbuf [ index ] . q = Vj . q + ( Vi . q - Vj . q ) * percent ;
rdp . vtxbuf [ index ] . u0 = Vj . u0 + ( Vi . u0 - Vj . u0 ) * percent ;
rdp . vtxbuf [ index ] . v0 = Vj . v0 + ( Vi . v0 - Vj . v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = Vj . u1 + ( Vi . u1 - Vj . u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = Vj . v1 + ( Vi . v1 - Vj . v1 ) * percent ;
if ( interpolate_colors )
InterpolateColors ( Vj , Vi , rdp . vtxbuf [ index + + ] , percent ) ;
else
rdp . vtxbuf [ index + + ] . number = Vi . number | Vj . number | 16 ;
// Save the in point
rdp . vtxbuf [ index + + ] = Vj ;
}
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
n = index ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( rdp . clip & CLIP_ZMAX ) // far plane
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
// Swap vertex buffers
VERTEX * tmp = rdp . vtxbuf2 ;
rdp . vtxbuf2 = rdp . vtxbuf ;
rdp . vtxbuf = tmp ;
rdp . vtx_buffer ^ = 1 ;
index = 0 ;
float maxZ = rdp . view_trans [ 2 ] + rdp . view_scale [ 2 ] ;
// Check the vertices for clipping
for ( i = 0 ; i < n ; i + + )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
j = i + 1 ;
if ( j = = n ) j = 0 ;
if ( Vi . z < maxZ )
{
if ( Vj . z < maxZ ) // Both are in, save the last one
{
rdp . vtxbuf [ index + + ] = Vj ;
}
else // First is in, second is out, save intersection
{
percent = ( maxZ - Vi . z ) / ( Vj . z - Vi . z ) ;
rdp . vtxbuf [ index ] . x = Vi . x + ( Vj . x - Vi . x ) * percent ;
rdp . vtxbuf [ index ] . y = Vi . y + ( Vj . y - Vi . y ) * percent ;
rdp . vtxbuf [ index ] . z = maxZ - 0.001f ;
rdp . vtxbuf [ index ] . q = Vi . q + ( Vj . q - Vi . q ) * percent ;
rdp . vtxbuf [ index ] . u0 = Vi . u0 + ( Vj . u0 - Vi . u0 ) * percent ;
rdp . vtxbuf [ index ] . v0 = Vi . v0 + ( Vj . v0 - Vi . v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = Vi . u1 + ( Vj . u1 - Vi . u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = Vi . v1 + ( Vj . v1 - Vi . v1 ) * percent ;
if ( interpolate_colors )
InterpolateColors ( Vi , Vj , rdp . vtxbuf [ index + + ] , percent ) ;
else
rdp . vtxbuf [ index + + ] . number = Vi . number | Vj . number ;
}
}
else
{
//if (Vj.z > maxZ) // Both are out, save nothing
if ( Vj . z < maxZ ) // First is out, second is in, save intersection & in point
{
percent = ( maxZ - Vj . z ) / ( Vi . z - Vj . z ) ;
rdp . vtxbuf [ index ] . x = Vj . x + ( Vi . x - Vj . x ) * percent ;
rdp . vtxbuf [ index ] . y = Vj . y + ( Vi . y - Vj . y ) * percent ;
rdp . vtxbuf [ index ] . z = maxZ - 0.001f ; ;
rdp . vtxbuf [ index ] . q = Vj . q + ( Vi . q - Vj . q ) * percent ;
rdp . vtxbuf [ index ] . u0 = Vj . u0 + ( Vi . u0 - Vj . u0 ) * percent ;
rdp . vtxbuf [ index ] . v0 = Vj . v0 + ( Vi . v0 - Vj . v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = Vj . u1 + ( Vi . u1 - Vj . u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = Vj . v1 + ( Vi . v1 - Vj . v1 ) * percent ;
if ( interpolate_colors )
InterpolateColors ( Vj , Vi , rdp . vtxbuf [ index + + ] , percent ) ;
else
rdp . vtxbuf [ index + + ] . number = Vi . number | Vj . number ;
// Save the in point
rdp . vtxbuf [ index + + ] = Vj ;
}
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
n = index ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
/*
if ( rdp . clip & CLIP_ZMIN ) // near Z
{
// Swap vertex buffers
VERTEX * tmp = rdp . vtxbuf2 ;
rdp . vtxbuf2 = rdp . vtxbuf ;
rdp . vtxbuf = tmp ;
rdp . vtx_buffer ^ = 1 ;
index = 0 ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
// Check the vertices for clipping
for ( i = 0 ; i < n ; i + + )
{
2013-04-04 21:22:19 +00:00
j = i + 1 ;
if ( j = = n ) j = 0 ;
if ( Vi . z > = 0.0f )
{
2016-01-20 09:59:35 +00:00
if ( Vj . z > = 0.0f ) // Both are in, save the last one
{
rdp . vtxbuf [ index + + ] = Vj ;
}
else // First is in, second is out, save intersection
{
percent = ( - Vi . z ) / ( Vj . z - Vi . z ) ;
rdp . vtxbuf [ index ] . x = Vi . x + ( Vj . x - Vi . x ) * percent ;
rdp . vtxbuf [ index ] . y = Vi . y + ( Vj . y - Vi . y ) * percent ;
rdp . vtxbuf [ index ] . z = 0.0f ;
rdp . vtxbuf [ index ] . q = Vi . q + ( Vj . q - Vi . q ) * percent ;
rdp . vtxbuf [ index ] . u0 = Vi . u0 + ( Vj . u0 - Vi . u0 ) * percent ;
rdp . vtxbuf [ index ] . v0 = Vi . v0 + ( Vj . v0 - Vi . v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = Vi . u1 + ( Vj . u1 - Vi . u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = Vi . v1 + ( Vj . v1 - Vi . v1 ) * percent ;
if ( interpolate_colors )
InterpolateColors ( Vi , Vj , rdp . vtxbuf [ index + + ] , percent ) ;
else
rdp . vtxbuf [ index + + ] . number = Vi . number | Vj . number ;
}
2013-04-04 21:22:19 +00:00
}
else
{
2016-01-20 09:59:35 +00:00
//if (Vj.z < 0.0f) // Both are out, save nothing
if ( Vj . z > = 0.0f ) // First is out, second is in, save intersection & in point
{
percent = ( - Vj . z ) / ( Vi . z - Vj . z ) ;
rdp . vtxbuf [ index ] . x = Vj . x + ( Vi . x - Vj . x ) * percent ;
rdp . vtxbuf [ index ] . y = Vj . y + ( Vi . y - Vj . y ) * percent ;
rdp . vtxbuf [ index ] . z = 0.0f ; ;
rdp . vtxbuf [ index ] . q = Vj . q + ( Vi . q - Vj . q ) * percent ;
rdp . vtxbuf [ index ] . u0 = Vj . u0 + ( Vi . u0 - Vj . u0 ) * percent ;
rdp . vtxbuf [ index ] . v0 = Vj . v0 + ( Vi . v0 - Vj . v0 ) * percent ;
rdp . vtxbuf [ index ] . u1 = Vj . u1 + ( Vi . u1 - Vj . u1 ) * percent ;
rdp . vtxbuf [ index ] . v1 = Vj . v1 + ( Vi . v1 - Vj . v1 ) * percent ;
if ( interpolate_colors )
InterpolateColors ( Vj , Vi , rdp . vtxbuf [ index + + ] , percent ) ;
else
rdp . vtxbuf [ index + + ] . number = Vi . number | Vj . number ;
// Save the in point
rdp . vtxbuf [ index + + ] = Vj ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
}
}
n = index ;
}
*/
rdp . n_global = n ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
static void render_tri ( uint16_t linew , int old_interpolate )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
if ( rdp . clip )
clip_tri ( old_interpolate ) ;
int n = rdp . n_global ;
if ( n < 3 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
FRDP ( " * render_tri: n < 3 \n " ) ;
return ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
int i , j ;
//*
if ( ( rdp . clip & CLIP_ZMIN ) & & ( rdp . othermode_l & 0x00000030 ) )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
int to_render = FALSE ;
for ( i = 0 ; i < n ; i + + )
{
if ( rdp . vtxbuf [ i ] . z > = 0.0f )
{
to_render = TRUE ;
break ;
}
}
if ( ! to_render ) //all z < 0
{
FRDP ( " * render_tri: all z < 0 \n " ) ;
return ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
//*/
if ( rdp . clip & & ! old_interpolate )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
for ( i = 0 ; i < n ; i + + )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
float percent = 101.0f ;
VERTEX * v1 = 0 , * v2 = 0 ;
switch ( rdp . vtxbuf [ i ] . number & 7 )
{
case 1 :
case 2 :
case 4 :
continue ;
break ;
case 3 :
v1 = org_vtx [ 0 ] ;
v2 = org_vtx [ 1 ] ;
break ;
case 5 :
v1 = org_vtx [ 0 ] ;
v2 = org_vtx [ 2 ] ;
break ;
case 6 :
v1 = org_vtx [ 1 ] ;
v2 = org_vtx [ 2 ] ;
break ;
case 7 :
InterpolateColors3 ( * org_vtx [ 0 ] , * org_vtx [ 1 ] , * org_vtx [ 2 ] , rdp . vtxbuf [ i ] ) ;
continue ;
break ;
}
switch ( rdp . vtxbuf [ i ] . number & 24 )
{
case 8 :
percent = ( rdp . vtxbuf [ i ] . x - v1 - > sx ) / ( v2 - > sx - v1 - > sx ) ;
break ;
case 16 :
percent = ( rdp . vtxbuf [ i ] . y - v1 - > sy ) / ( v2 - > sy - v1 - > sy ) ;
break ;
default :
{
float d = ( v2 - > sx - v1 - > sx ) ;
if ( fabs ( d ) > 1.0 )
percent = ( rdp . vtxbuf [ i ] . x - v1 - > sx ) / d ;
if ( percent > 100.0f )
percent = ( rdp . vtxbuf [ i ] . y - v1 - > sy ) / ( v2 - > sy - v1 - > sy ) ;
}
}
InterpolateColors2 ( * v1 , * v2 , rdp . vtxbuf [ i ] , percent ) ;
2013-04-04 21:22:19 +00:00
}
}
2016-01-20 09:59:35 +00:00
/*
if ( rdp . clip )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
LOGG ( " Colors before clipping: \n " ) ;
unsigned int k ;
for ( k = 0 ; k < 3 ; k + + )
{
FRDP2 ( " V%d: r=%d, g=%d, b=%d, a=%d, f=%d \n " , k , org_vtx [ k ] - > r , org_vtx [ k ] - > g , org_vtx [ k ] - > b , org_vtx [ k ] - > a , ( short ) org_vtx [ k ] - > f ) ;
}
FRDP ( " Got %d vertex after clipping \n " , n ) ;
for ( k = 0 ; k < n ; k + + )
{
FRDP ( " V%d: r=%d, g=%d, b=%d, a=%d, f=%d \n " , k , rdp . vtxbuf [ k ] . r , rdp . vtxbuf [ k ] . g , rdp . vtxbuf [ k ] . b , rdp . vtxbuf [ k ] . a , ( short ) rdp . vtxbuf [ k ] . f ) ;
}
}
*/
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
ConvertCoordsConvert ( rdp . vtxbuf , n ) ;
if ( rdp . fog_mode = = RDP : : fog_enabled )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
for ( i = 0 ; i < n ; i + + )
{
2016-01-25 09:58:29 +00:00
rdp . vtxbuf [ i ] . f = 1.0f / maxval ( 4.0f , rdp . vtxbuf [ i ] . f ) ;
2016-01-20 09:59:35 +00:00
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
else if ( rdp . fog_mode = = RDP : : fog_blend )
2013-04-04 21:22:19 +00:00
{
2016-01-25 09:58:29 +00:00
float fog = 1.0f / maxval ( 1 , rdp . fog_color & 0xFF ) ;
2016-01-20 09:59:35 +00:00
for ( i = 0 ; i < n ; i + + )
{
rdp . vtxbuf [ i ] . f = fog ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
else if ( rdp . fog_mode = = RDP : : fog_blend_inverse )
2013-04-04 21:22:19 +00:00
{
2016-01-25 09:58:29 +00:00
float fog = 1.0f / maxval ( 1 , ( ~ rdp . fog_color ) & 0xFF ) ;
2016-01-20 09:59:35 +00:00
for ( i = 0 ; i < n ; i + + )
{
rdp . vtxbuf [ i ] . f = fog ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( settings . lodmode > 0 & & rdp . cur_tile < rdp . mipmap_level )
CalculateLOD ( rdp . vtxbuf , n ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
cmb . cmb_ext_use = cmb . tex_cmb_ext_use = 0 ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
/*
if ( rdp . tbuff_tex )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
for ( int k = 0 ; k < 3 ; k + + )
{
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 . tbuff_tex - > width , rdp . tbuff_tex - > height , rdp . tbuff_tex - > tex_width , rdp . tbuff_tex - > tex_height , rdp . tbuff_tex - > lr_u , rdp . tbuff_tex - > lr_v ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
}
*/
2016-01-20 17:12:15 +00:00
if ( settings . wireframe )
2013-04-04 21:22:19 +00:00
{
2016-01-20 17:12:15 +00:00
SetWireframeCol ( ) ;
for ( i = 0 ; i < n ; i + + )
2013-04-04 21:22:19 +00:00
{
2016-01-20 17:12:15 +00:00
j = i + 1 ;
if ( j = = n ) j = 0 ;
grDrawLine ( & rdp . vtxbuf [ i ] , & rdp . vtxbuf [ j ] ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 17:12:15 +00:00
}
else
{
// VERTEX ** pv = rdp.vtx_buffer?(vtx_list2):(vtx_list1);
// for (int k = 0; k < n; k ++)
// 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]);
// pv[k]->y = settings.res_y - pv[k]->y;
2016-01-20 09:59:35 +00:00
2016-01-20 17:12:15 +00:00
if ( linew > 0 )
{
VERTEX * V0 = & rdp . vtxbuf [ 0 ] ;
VERTEX * V1 = & rdp . vtxbuf [ 1 ] ;
if ( fabs ( V0 - > x - V1 - > x ) < 0.01 & & fabs ( V0 - > y - V1 - > y ) < 0.01 )
V1 = & rdp . vtxbuf [ 2 ] ;
V0 - > z = ScaleZ ( V0 - > z ) ;
V1 - > z = ScaleZ ( V1 - > z ) ;
VERTEX v [ 4 ] ;
v [ 0 ] = * V0 ;
v [ 1 ] = * V0 ;
v [ 2 ] = * V1 ;
v [ 3 ] = * V1 ;
float width = linew * 0.25f ;
if ( fabs ( V0 - > y - V1 - > y ) < 0.0001 )
2016-01-20 09:59:35 +00:00
{
2016-01-20 17:12:15 +00:00
v [ 0 ] . x = v [ 1 ] . x = V0 - > x ;
v [ 2 ] . x = v [ 3 ] . x = V1 - > x ;
2016-01-20 09:59:35 +00:00
2016-01-20 17:12:15 +00:00
width * = rdp . scale_y ;
v [ 0 ] . y = v [ 2 ] . y = V0 - > y - width ;
v [ 1 ] . y = v [ 3 ] . y = V0 - > y + width ;
}
else if ( fabs ( V0 - > x - V1 - > x ) < 0.0001 )
{
v [ 0 ] . y = v [ 1 ] . y = V0 - > y ;
v [ 2 ] . y = v [ 3 ] . y = V1 - > y ;
2016-01-20 09:59:35 +00:00
2016-01-20 17:12:15 +00:00
width * = rdp . scale_x ;
v [ 0 ] . x = v [ 2 ] . x = V0 - > x - width ;
v [ 1 ] . x = v [ 3 ] . x = V0 - > x + width ;
2016-01-20 09:59:35 +00:00
}
else
{
2016-01-20 17:12:15 +00:00
float dx = V1 - > x - V0 - > x ;
float dy = V1 - > y - V0 - > y ;
float len = sqrtf ( dx * dx + dy * dy ) ;
float wx = dy * width * rdp . scale_x / len ;
float wy = dx * width * rdp . scale_y / len ;
v [ 0 ] . x = V0 - > x + wx ;
v [ 0 ] . y = V0 - > y - wy ;
v [ 1 ] . x = V0 - > x - wx ;
v [ 1 ] . y = V0 - > y + wy ;
v [ 2 ] . x = V1 - > x + wx ;
v [ 2 ] . y = V1 - > y - wy ;
v [ 3 ] . x = V1 - > x - wx ;
v [ 3 ] . y = V1 - > y + wy ;
2016-01-20 09:59:35 +00:00
}
2016-01-20 17:12:15 +00:00
grDrawTriangle ( & v [ 0 ] , & v [ 1 ] , & v [ 2 ] ) ;
grDrawTriangle ( & v [ 1 ] , & v [ 2 ] , & v [ 3 ] ) ;
}
else
{
DepthBuffer ( rdp . vtxbuf , n ) ;
if ( ( rdp . rm & 0xC10 ) = = 0xC10 )
grDepthBiasLevel ( - deltaZ ) ;
grDrawVertexArray ( GR_TRIANGLE_FAN , n , rdp . vtx_buffer ? ( & vtx_list2 ) : ( & vtx_list1 ) ) ;
2013-04-04 21:22:19 +00:00
}
}
2016-01-20 09:59:35 +00:00
if ( _debugger . capture ) add_tri ( rdp . vtxbuf , n , TRI_TRIANGLE ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
void add_tri ( VERTEX * v , int n , int type )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
//FRDP ("ENTER (%f, %f, %f), (%f, %f, %f), (%f, %f, %f)\n", v[0].x, v[0].y, v[0].w,
// v[1].x, v[1].y, v[1].w, v[2].x, v[2].y, v[2].w);
// Debug capture
if ( _debugger . capture )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
rdp . debug_n + + ;
TRI_INFO * info = new TRI_INFO ;
info - > nv = n ;
info - > v = new VERTEX [ n ] ;
memcpy ( info - > v , v , sizeof ( VERTEX ) * n ) ;
info - > cycle_mode = rdp . cycle_mode ;
info - > cycle1 = rdp . cycle1 ;
info - > cycle2 = rdp . cycle2 ;
info - > uncombined = rdp . uncombined ;
info - > geom_mode = rdp . geom_mode ;
info - > othermode_h = rdp . othermode_h ;
info - > othermode_l = rdp . othermode_l ;
info - > tri_n = rdp . tri_n ;
info - > type = type ;
for ( int i = 0 ; i < 2 ; i + + )
{
int j = rdp . cur_tile + i ;
if ( i = = 0 )
info - > t [ i ] . tmu = rdp . t0 ;
else
info - > t [ i ] . tmu = rdp . t1 ;
info - > t [ i ] . cur_cache [ 0 ] = rdp . cur_cache_n [ rdp . t0 ] ;
info - > t [ i ] . cur_cache [ 1 ] = rdp . cur_cache_n [ rdp . t1 ] ;
info - > t [ i ] . format = rdp . tiles [ j ] . format ;
info - > t [ i ] . size = rdp . tiles [ j ] . size ;
info - > t [ i ] . width = rdp . tiles [ j ] . width ;
info - > t [ i ] . height = rdp . tiles [ j ] . height ;
info - > t [ i ] . line = rdp . tiles [ j ] . line ;
info - > t [ i ] . palette = rdp . tiles [ j ] . palette ;
info - > t [ i ] . clamp_s = rdp . tiles [ j ] . clamp_s ;
info - > t [ i ] . clamp_t = rdp . tiles [ j ] . clamp_t ;
info - > t [ i ] . mirror_s = rdp . tiles [ j ] . mirror_s ;
info - > t [ i ] . mirror_t = rdp . tiles [ j ] . mirror_t ;
info - > t [ i ] . shift_s = rdp . tiles [ j ] . shift_s ;
info - > t [ i ] . shift_t = rdp . tiles [ j ] . shift_t ;
info - > t [ i ] . mask_s = rdp . tiles [ j ] . mask_s ;
info - > t [ i ] . mask_t = rdp . tiles [ j ] . mask_t ;
info - > t [ i ] . ul_s = rdp . tiles [ j ] . ul_s ;
info - > t [ i ] . ul_t = rdp . tiles [ j ] . ul_t ;
info - > t [ i ] . lr_s = rdp . tiles [ j ] . lr_s ;
info - > t [ i ] . lr_t = rdp . tiles [ j ] . lr_t ;
info - > t [ i ] . t_ul_s = rdp . tiles [ 7 ] . t_ul_s ;
info - > t [ i ] . t_ul_t = rdp . tiles [ 7 ] . t_ul_t ;
info - > t [ i ] . t_lr_s = rdp . tiles [ 7 ] . t_lr_s ;
info - > t [ i ] . t_lr_t = rdp . tiles [ 7 ] . t_lr_t ;
info - > t [ i ] . scale_s = rdp . tiles [ j ] . s_scale ;
info - > t [ i ] . scale_t = rdp . tiles [ j ] . t_scale ;
}
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
info - > fog_color = rdp . fog_color ;
info - > fill_color = rdp . fill_color ;
info - > prim_color = rdp . prim_color ;
info - > blend_color = rdp . blend_color ;
info - > env_color = rdp . env_color ;
info - > prim_lodmin = rdp . prim_lodmin ;
info - > prim_lodfrac = rdp . prim_lodfrac ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
info - > pNext = _debugger . tri_list ;
_debugger . tri_list = info ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
if ( _debugger . tri_last = = NULL )
_debugger . tri_last = _debugger . tri_list ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
void update_scissor ( )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
if ( rdp . update & UPDATE_SCISSOR )
{
rdp . update ^ = UPDATE_SCISSOR ;
// KILL the floating point error with 0.01f
2016-01-25 09:58:29 +00:00
rdp . scissor . ul_x = ( uint32_t ) maxval ( minval ( ( rdp . scissor_o . ul_x * rdp . scale_x + rdp . offset_x + 0.01f ) , settings . res_x ) , 0 ) ;
rdp . scissor . lr_x = ( uint32_t ) maxval ( minval ( ( rdp . scissor_o . lr_x * rdp . scale_x + rdp . offset_x + 0.01f ) , settings . res_x ) , 0 ) ;
rdp . scissor . ul_y = ( uint32_t ) maxval ( minval ( ( rdp . scissor_o . ul_y * rdp . scale_y + rdp . offset_y + 0.01f ) , settings . res_y ) , 0 ) ;
rdp . scissor . lr_y = ( uint32_t ) maxval ( minval ( ( rdp . scissor_o . lr_y * rdp . scale_y + rdp . offset_y + 0.01f ) , settings . res_y ) , 0 ) ;
2016-01-20 09:59:35 +00:00
//grClipWindow specifies the hardware clipping window. Any pixels outside the clipping window are rejected.
//Values are inclusive for minimum x and y values and exclusive for maximum x and y values.
// grClipWindow (rdp.scissor.ul_x?rdp.scissor.ul_x+1:0, rdp.scissor.ul_y?rdp.scissor.ul_y+1:0, rdp.scissor.lr_x, rdp.scissor.lr_y);
2016-01-20 17:12:15 +00:00
grClipWindow ( rdp . scissor . ul_x , rdp . scissor . ul_y , rdp . scissor . lr_x , rdp . scissor . lr_y ) ;
FRDP ( " |- scissor - (%d, %d) -> (%d, %d) \n " , rdp . scissor . ul_x , rdp . scissor . ul_y , rdp . scissor . lr_x , rdp . scissor . lr_y ) ;
2016-01-20 09:59:35 +00:00
}
2013-04-04 21:22:19 +00:00
}
//
// update - update states if they need it
//
typedef struct
{
2016-01-20 09:59:35 +00:00
unsigned int c2_m2b : 2 ;
unsigned int c1_m2b : 2 ;
unsigned int c2_m2a : 2 ;
unsigned int c1_m2a : 2 ;
unsigned int c2_m1b : 2 ;
unsigned int c1_m1b : 2 ;
unsigned int c2_m1a : 2 ;
unsigned int c1_m1a : 2 ;
2013-04-04 21:22:19 +00:00
} rdp_blender_setting ;
2016-01-20 09:59:35 +00:00
void update ( )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
LRDP ( " -+ update called \n " ) ;
// Check for rendermode changes
2013-04-04 21:22:19 +00:00
// Z buffer
2016-01-20 09:59:35 +00:00
if ( rdp . render_mode_changed & 0x00000C30 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
FRDP ( " |- render_mode_changed zbuf - decal: %s, update: %s, compare: %s \n " ,
str_yn [ ( rdp . othermode_l & 0x00000400 ) ? 1 : 0 ] ,
str_yn [ ( rdp . othermode_l & 0x00000020 ) ? 1 : 0 ] ,
str_yn [ ( rdp . othermode_l & 0x00000010 ) ? 1 : 0 ] ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
rdp . render_mode_changed & = ~ 0x00000C30 ;
rdp . update | = UPDATE_ZBUF_ENABLED ;
// Update?
if ( ( rdp . othermode_l & 0x00000020 ) )
rdp . flags | = ZBUF_UPDATE ;
2015-03-11 21:15:42 +00:00
else
2016-01-20 09:59:35 +00:00
rdp . flags & = ~ ZBUF_UPDATE ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
// Compare?
if ( rdp . othermode_l & 0x00000010 )
rdp . flags | = ZBUF_COMPARE ;
2013-04-04 21:22:19 +00:00
else
2016-01-20 09:59:35 +00:00
rdp . flags & = ~ ZBUF_COMPARE ;
2013-04-04 21:22:19 +00:00
}
// Alpha compare
2016-01-20 09:59:35 +00:00
if ( rdp . render_mode_changed & 0x00001000 )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
FRDP ( " |- render_mode_changed alpha compare - on: %s \n " ,
str_yn [ ( rdp . othermode_l & 0x00001000 ) ? 1 : 0 ] ) ;
rdp . render_mode_changed & = ~ 0x00001000 ;
rdp . update | = UPDATE_ALPHA_COMPARE ;
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
if ( rdp . othermode_l & 0x00001000 )
rdp . flags | = ALPHA_COMPARE ;
else
rdp . flags & = ~ ALPHA_COMPARE ;
}
if ( rdp . render_mode_changed & 0x00002000 ) // alpha cvg sel
{
FRDP ( " |- render_mode_changed alpha cvg sel - on: %s \n " ,
str_yn [ ( rdp . othermode_l & 0x00002000 ) ? 1 : 0 ] ) ;
rdp . render_mode_changed & = ~ 0x00002000 ;
rdp . update | = UPDATE_COMBINE ;
rdp . update | = UPDATE_ALPHA_COMPARE ;
}
// Force blend
if ( rdp . render_mode_changed & 0xFFFF0000 )
{
FRDP ( " |- render_mode_changed force_blend - %08lx \n " , rdp . othermode_l & 0xFFFF0000 ) ;
rdp . render_mode_changed & = 0x0000FFFF ;
rdp . fbl_a0 = ( uint8_t ) ( ( rdp . othermode_l > > 30 ) & 0x3 ) ;
rdp . fbl_b0 = ( uint8_t ) ( ( rdp . othermode_l > > 26 ) & 0x3 ) ;
rdp . fbl_c0 = ( uint8_t ) ( ( rdp . othermode_l > > 22 ) & 0x3 ) ;
rdp . fbl_d0 = ( uint8_t ) ( ( rdp . othermode_l > > 18 ) & 0x3 ) ;
rdp . fbl_a1 = ( uint8_t ) ( ( rdp . othermode_l > > 28 ) & 0x3 ) ;
rdp . fbl_b1 = ( uint8_t ) ( ( rdp . othermode_l > > 24 ) & 0x3 ) ;
rdp . fbl_c1 = ( uint8_t ) ( ( rdp . othermode_l > > 20 ) & 0x3 ) ;
rdp . fbl_d1 = ( uint8_t ) ( ( rdp . othermode_l > > 16 ) & 0x3 ) ;
rdp . update | = UPDATE_COMBINE ;
}
// Combine MUST go before texture
if ( ( rdp . update & UPDATE_COMBINE ) & & rdp . allow_combine )
{
TBUFF_COLOR_IMAGE * aTBuff [ 2 ] = { 0 , 0 } ;
if ( rdp . aTBuffTex [ 0 ] )
aTBuff [ rdp . aTBuffTex [ 0 ] - > tile ] = rdp . aTBuffTex [ 0 ] ;
if ( rdp . aTBuffTex [ 1 ] )
aTBuff [ rdp . aTBuffTex [ 1 ] - > tile ] = rdp . aTBuffTex [ 1 ] ;
rdp . aTBuffTex [ 0 ] = aTBuff [ 0 ] ;
rdp . aTBuffTex [ 1 ] = aTBuff [ 1 ] ;
LRDP ( " |-+ update_combine \n " ) ;
Combine ( ) ;
}
if ( rdp . update & UPDATE_TEXTURE ) // note: UPDATE_TEXTURE and UPDATE_COMBINE are the same
{
rdp . tex_ctr + + ;
if ( rdp . tex_ctr = = 0xFFFFFFFF )
rdp . tex_ctr = 0 ;
TexCache ( ) ;
if ( rdp . noise = = RDP : : noise_none )
rdp . update ^ = UPDATE_TEXTURE ;
}
2016-01-20 17:12:15 +00:00
// Z buffer
if ( rdp . update & UPDATE_ZBUF_ENABLED )
2016-01-20 09:59:35 +00:00
{
2016-01-20 17:12:15 +00:00
// already logged above
rdp . update ^ = UPDATE_ZBUF_ENABLED ;
2016-01-20 09:59:35 +00:00
2016-01-20 17:12:15 +00:00
if ( ( ( rdp . flags & ZBUF_ENABLED ) | | rdp . zsrc = = 1 ) & & rdp . cycle_mode < 2 )
{
if ( rdp . flags & ZBUF_COMPARE )
2013-04-04 21:22:19 +00:00
{
2016-01-20 17:12:15 +00:00
switch ( ( rdp . rm & 0xC00 ) > > 10 ) {
case 0 :
2016-01-20 09:59:35 +00:00
grDepthBiasLevel ( 0 ) ;
2016-01-20 17:12:15 +00:00
grDepthBufferFunction ( settings . zmode_compare_less ? GR_CMP_LESS : GR_CMP_LEQUAL ) ;
break ;
case 1 :
grDepthBiasLevel ( - 4 ) ;
grDepthBufferFunction ( settings . zmode_compare_less ? GR_CMP_LESS : GR_CMP_LEQUAL ) ;
break ;
case 2 :
grDepthBiasLevel ( settings . ucode = = 7 ? - 4 : 0 ) ;
grDepthBufferFunction ( GR_CMP_LESS ) ;
break ;
case 3 :
// will be set dynamically per polygon
//grDepthBiasLevel(-deltaZ);
grDepthBufferFunction ( GR_CMP_LEQUAL ) ;
break ;
2016-01-20 09:59:35 +00:00
}
2013-04-04 21:22:19 +00:00
}
else
{
2016-01-20 09:59:35 +00:00
grDepthBiasLevel ( 0 ) ;
grDepthBufferFunction ( GR_CMP_ALWAYS ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
2016-01-20 17:12:15 +00:00
if ( rdp . flags & ZBUF_UPDATE )
grDepthMask ( FXTRUE ) ;
else
grDepthMask ( FXFALSE ) ;
}
else
2013-04-04 21:22:19 +00:00
{
2016-01-20 17:12:15 +00:00
grDepthBiasLevel ( 0 ) ;
grDepthBufferFunction ( GR_CMP_ALWAYS ) ;
grDepthMask ( FXFALSE ) ;
}
}
2016-01-20 09:59:35 +00:00
2016-01-20 17:12:15 +00:00
// Alpha compare
if ( rdp . update & UPDATE_ALPHA_COMPARE )
{
// already logged above
rdp . update ^ = UPDATE_ALPHA_COMPARE ;
// if (rdp.acmp == 1 && !(rdp.othermode_l & 0x00002000) && !force_full_alpha)
// if (rdp.acmp == 1 && !(rdp.othermode_l & 0x00002000) && (rdp.blend_color&0xFF))
if ( rdp . acmp = = 1 & & ! ( rdp . othermode_l & 0x00002000 ) & & ( ! ( rdp . othermode_l & 0x00004000 ) | | ( rdp . blend_color & 0xFF ) ) )
{
uint8_t reference = ( uint8_t ) ( rdp . blend_color & 0xFF ) ;
grAlphaTestFunction ( reference ? GR_CMP_GEQUAL : GR_CMP_GREATER ) ;
grAlphaTestReferenceValue ( reference ) ;
FRDP ( " |- alpha compare: blend: %02lx \n " , reference ) ;
}
else
{
if ( rdp . flags & ALPHA_COMPARE )
2016-01-20 09:59:35 +00:00
{
2016-01-20 17:12:15 +00:00
if ( ( rdp . othermode_l & 0x5000 ) ! = 0x5000 )
{
grAlphaTestFunction ( GR_CMP_GEQUAL ) ;
grAlphaTestReferenceValue ( 0x20 ) ; //0xA0);
LRDP ( " |- alpha compare: 0x20 \n " ) ;
}
else
2016-01-20 09:59:35 +00:00
{
2016-01-20 17:12:15 +00:00
grAlphaTestFunction ( GR_CMP_GREATER ) ;
if ( rdp . acmp = = 3 )
2016-01-20 09:59:35 +00:00
{
2016-01-20 17:12:15 +00:00
grAlphaTestReferenceValue ( ( uint8_t ) ( rdp . blend_color & 0xFF ) ) ;
FRDP ( " |- alpha compare: blend: %02lx \n " , rdp . blend_color & 0xFF ) ;
2016-01-20 09:59:35 +00:00
}
else
{
2016-01-20 17:12:15 +00:00
grAlphaTestReferenceValue ( 0x00 ) ;
LRDP ( " |- alpha compare: 0x00 \n " ) ;
2016-01-20 09:59:35 +00:00
}
}
}
2016-01-20 17:12:15 +00:00
else
2016-01-20 09:59:35 +00:00
{
2016-01-20 17:12:15 +00:00
grAlphaTestFunction ( GR_CMP_ALWAYS ) ;
LRDP ( " |- alpha compare: none \n " ) ;
2016-01-20 09:59:35 +00:00
}
2016-01-20 17:12:15 +00:00
}
if ( rdp . acmp = = 3 & & rdp . cycle_mode < 2 )
{
if ( grStippleModeExt ! = 0 )
2016-01-20 09:59:35 +00:00
{
2016-01-20 17:12:15 +00:00
if ( settings . old_style_adither | | rdp . alpha_dither_mode ! = 3 ) {
LRDP ( " |- alpha compare: dither \n " ) ;
grStippleModeExt ( settings . stipple_mode ) ;
2016-01-20 09:59:35 +00:00
}
2016-01-20 17:12:15 +00:00
else
grStippleModeExt ( GR_STIPPLE_DISABLE ) ;
2016-01-20 09:59:35 +00:00
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 17:12:15 +00:00
else
2013-04-04 21:22:19 +00:00
{
2016-01-20 17:12:15 +00:00
if ( grStippleModeExt )
2016-01-20 09:59:35 +00:00
{
2016-01-20 17:12:15 +00:00
//LRDP (" |- alpha compare: dither disabled\n");
grStippleModeExt ( GR_STIPPLE_DISABLE ) ;
2016-01-20 09:59:35 +00:00
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 17:12:15 +00:00
}
// Cull mode (leave this in for z-clipped triangles)
if ( rdp . update & UPDATE_CULL_MODE )
{
rdp . update ^ = UPDATE_CULL_MODE ;
uint32_t mode = ( rdp . flags & CULLMASK ) > > CULLSHIFT ;
FRDP ( " |- cull_mode - mode: %s \n " , str_cull [ mode ] ) ;
switch ( mode )
2013-04-04 21:22:19 +00:00
{
2016-01-20 17:12:15 +00:00
case 0 : // cull none
case 3 : // cull both
grCullMode ( GR_CULL_DISABLE ) ;
break ;
case 1 : // cull front
// grCullMode(GR_CULL_POSITIVE);
grCullMode ( GR_CULL_NEGATIVE ) ;
break ;
case 2 : // cull back
// grCullMode (GR_CULL_NEGATIVE);
grCullMode ( GR_CULL_POSITIVE ) ;
break ;
}
}
2016-01-20 09:59:35 +00:00
2016-01-20 17:12:15 +00:00
//Added by Gonetz.
if ( settings . fog & & ( rdp . update & UPDATE_FOG_ENABLED ) )
{
rdp . update ^ = UPDATE_FOG_ENABLED ;
uint16_t blender = ( uint16_t ) ( rdp . othermode_l > > 16 ) ;
if ( rdp . flags & FOG_ENABLED )
{
rdp_blender_setting & bl = * ( rdp_blender_setting * ) ( & ( blender ) ) ;
if ( ( rdp . fog_multiplier > 0 ) & & ( bl . c1_m1a = = 3 | | bl . c1_m2a = = 3 | | bl . c2_m1a = = 3 | | bl . c2_m2a = = 3 ) )
2016-01-20 09:59:35 +00:00
{
grFogColorValue ( rdp . fog_color ) ;
grFogMode ( GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT ) ;
2016-01-20 17:12:15 +00:00
rdp . fog_mode = RDP : : fog_enabled ;
LRDP ( " fog enabled \n " ) ;
2016-01-20 09:59:35 +00:00
}
else
{
2016-01-20 17:12:15 +00:00
LRDP ( " fog disabled in blender \n " ) ;
2016-01-20 09:59:35 +00:00
rdp . fog_mode = RDP : : fog_disabled ;
grFogMode ( GR_FOG_DISABLE ) ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 17:12:15 +00:00
else if ( blender = = 0xc410 | | blender = = 0xc411 | | blender = = 0xf500 )
{
grFogColorValue ( rdp . fog_color ) ;
grFogMode ( GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT ) ;
rdp . fog_mode = RDP : : fog_blend ;
LRDP ( " fog blend \n " ) ;
}
else if ( blender = = 0x04d1 )
{
grFogColorValue ( rdp . fog_color ) ;
grFogMode ( GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT ) ;
rdp . fog_mode = RDP : : fog_blend_inverse ;
LRDP ( " fog blend \n " ) ;
}
else
{
LRDP ( " fog disabled \n " ) ;
rdp . fog_mode = RDP : : fog_disabled ;
grFogMode ( GR_FOG_DISABLE ) ;
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( rdp . update & UPDATE_VIEWPORT )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
rdp . update ^ = UPDATE_VIEWPORT ;
2016-01-20 17:12:15 +00:00
float scale_x = ( float ) fabs ( rdp . view_scale [ 0 ] ) ;
float scale_y = ( float ) fabs ( rdp . view_scale [ 1 ] ) ;
2013-04-04 21:22:19 +00:00
2016-01-25 09:58:29 +00:00
rdp . clip_min_x = maxval ( ( rdp . view_trans [ 0 ] - scale_x + rdp . offset_x ) / rdp . clip_ratio , 0.0f ) ;
rdp . clip_min_y = maxval ( ( rdp . view_trans [ 1 ] - scale_y + rdp . offset_y ) / rdp . clip_ratio , 0.0f ) ;
rdp . clip_max_x = minval ( ( rdp . view_trans [ 0 ] + scale_x + rdp . offset_x ) * rdp . clip_ratio , settings . res_x ) ;
rdp . clip_max_y = minval ( ( rdp . view_trans [ 1 ] + scale_y + rdp . offset_y ) * rdp . clip_ratio , settings . res_y ) ;
2013-04-04 21:22:19 +00:00
2016-01-20 17:12:15 +00:00
FRDP ( " |- viewport - (%d, %d, %d, %d) \n " , ( uint32_t ) rdp . clip_min_x , ( uint32_t ) rdp . clip_min_y , ( uint32_t ) rdp . clip_max_x , ( uint32_t ) rdp . clip_max_y ) ;
if ( ! rdp . scissor_set )
{
rdp . scissor . ul_x = ( uint32_t ) rdp . clip_min_x ;
rdp . scissor . lr_x = ( uint32_t ) rdp . clip_max_x ;
rdp . scissor . ul_y = ( uint32_t ) rdp . clip_min_y ;
rdp . scissor . lr_y = ( uint32_t ) rdp . clip_max_y ;
grClipWindow ( rdp . scissor . ul_x , rdp . scissor . ul_y , rdp . scissor . lr_x , rdp . scissor . lr_y ) ;
2016-01-20 09:59:35 +00:00
}
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
if ( rdp . update & UPDATE_SCISSOR )
2016-01-20 17:12:15 +00:00
{
2016-01-20 09:59:35 +00:00
update_scissor ( ) ;
2016-01-20 17:12:15 +00:00
}
2013-04-04 21:22:19 +00:00
2016-01-20 09:59:35 +00:00
LRDP ( " + update end \n " ) ;
2013-04-04 21:22:19 +00:00
}
2016-01-20 09:59:35 +00:00
void set_message_combiner ( )
2013-04-04 21:22:19 +00:00
{
2016-01-20 09:59:35 +00:00
grColorCombine ( GR_COMBINE_FUNCTION_SCALE_OTHER ,
GR_COMBINE_FACTOR_ONE ,
GR_COMBINE_LOCAL_NONE ,
GR_COMBINE_OTHER_TEXTURE ,
FXFALSE ) ;
grAlphaCombine ( GR_COMBINE_FUNCTION_SCALE_OTHER ,
GR_COMBINE_FACTOR_ONE ,
GR_COMBINE_LOCAL_NONE ,
GR_COMBINE_OTHER_TEXTURE ,
FXFALSE ) ;
if ( settings . buff_clear & & ( settings . show_fps & 0x08 ) )
grAlphaBlendFunction ( GR_BLEND_SRC_ALPHA ,
GR_BLEND_ONE_MINUS_SRC_ALPHA ,
GR_BLEND_ZERO ,
GR_BLEND_ZERO ) ;
else
grAlphaBlendFunction ( GR_BLEND_ONE ,
GR_BLEND_ZERO ,
GR_BLEND_ZERO ,
GR_BLEND_ZERO ) ;
grAlphaTestFunction ( GR_CMP_ALWAYS ) ;
if ( grStippleModeExt )
{
grStippleModeExt ( GR_STIPPLE_DISABLE ) ;
}
grTexFilterMode ( 0 , GR_TEXTUREFILTER_BILINEAR , GR_TEXTUREFILTER_BILINEAR ) ;
grTexCombine ( GR_TMU1 ,
GR_COMBINE_FUNCTION_NONE ,
GR_COMBINE_FACTOR_NONE ,
GR_COMBINE_FUNCTION_NONE ,
GR_COMBINE_FACTOR_NONE ,
FXFALSE , FXFALSE ) ;
grTexCombine ( GR_TMU0 ,
GR_COMBINE_FUNCTION_LOCAL ,
GR_COMBINE_FACTOR_NONE ,
GR_COMBINE_FUNCTION_LOCAL ,
GR_COMBINE_FACTOR_NONE ,
FXFALSE , FXFALSE ) ;
grTexSource ( GR_TMU0 ,
voodoo . tex_min_addr [ GR_TMU0 ] + offset_font ,
GR_MIPMAPLEVELMASK_BOTH ,
& fontTex ) ;
grFogMode ( GR_FOG_DISABLE ) ;
2016-01-27 05:26:28 +00:00
}