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.
//
//****************************************************************
//
// Draw N64 frame buffer to screen.
// Created by Gonetz, 2007
//
//****************************************************************
2015-10-09 00:07:09 +00:00
# include "Gfx_1.3.h"
2013-04-04 21:22:19 +00:00
# include "FBtoScreen.h"
# include "TexCache.h"
static int SetupFBtoScreenCombiner ( wxUint32 texture_size , wxUint32 opaque )
{
int tmu ;
if ( voodoo . tmem_ptr [ GR_TMU0 ] + texture_size < voodoo . tex_max_addr [ 0 ] )
{
tmu = GR_TMU0 ;
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 ) ;
}
else
{
if ( voodoo . tmem_ptr [ GR_TMU1 ] + texture_size > = voodoo . tex_max_addr [ 1 ] )
ClearCache ( ) ;
tmu = GR_TMU1 ;
grTexCombine ( GR_TMU1 ,
GR_COMBINE_FUNCTION_LOCAL ,
GR_COMBINE_FACTOR_NONE ,
GR_COMBINE_FUNCTION_LOCAL ,
GR_COMBINE_FACTOR_NONE ,
FXFALSE ,
FXFALSE ) ;
grTexCombine ( GR_TMU0 ,
GR_COMBINE_FUNCTION_SCALE_OTHER ,
GR_COMBINE_FACTOR_ONE ,
GR_COMBINE_FUNCTION_SCALE_OTHER ,
GR_COMBINE_FACTOR_ONE ,
FXFALSE ,
FXFALSE ) ;
}
int filter = ( rdp . filter_mode ! = 2 ) ? GR_TEXTUREFILTER_POINT_SAMPLED : GR_TEXTUREFILTER_BILINEAR ;
grTexFilterMode ( tmu , filter , filter ) ;
grTexClampMode ( tmu ,
GR_TEXTURECLAMP_CLAMP ,
GR_TEXTURECLAMP_CLAMP ) ;
// grConstantColorValue (0xFFFFFFFF);
grColorCombine ( GR_COMBINE_FUNCTION_SCALE_OTHER ,
GR_COMBINE_FACTOR_ONE ,
GR_COMBINE_LOCAL_NONE ,
GR_COMBINE_OTHER_TEXTURE ,
// GR_COMBINE_OTHER_CONSTANT,
FXFALSE ) ;
grAlphaCombine ( GR_COMBINE_FUNCTION_SCALE_OTHER ,
GR_COMBINE_FACTOR_ONE ,
GR_COMBINE_LOCAL_NONE ,
GR_COMBINE_OTHER_TEXTURE ,
FXFALSE ) ;
if ( opaque )
{
grAlphaTestFunction ( GR_CMP_ALWAYS ) ;
grAlphaBlendFunction ( GR_BLEND_ONE ,
GR_BLEND_ZERO ,
GR_BLEND_ONE ,
GR_BLEND_ZERO ) ;
}
else
{
grAlphaBlendFunction ( GR_BLEND_SRC_ALPHA ,
GR_BLEND_ONE_MINUS_SRC_ALPHA ,
GR_BLEND_ONE ,
GR_BLEND_ZERO ) ;
}
grDepthBufferFunction ( GR_CMP_ALWAYS ) ;
grCullMode ( GR_CULL_DISABLE ) ;
grDepthMask ( FXFALSE ) ;
rdp . update | = UPDATE_COMBINE | UPDATE_ZBUF_ENABLED | UPDATE_CULL_MODE ;
return tmu ;
}
static void DrawRE2Video ( FB_TO_SCREEN_INFO & fb_info , float scale )
{
float scale_y = ( float ) fb_info . width / rdp . vi_height ;
float height = settings . scr_res_x / scale_y ;
float ul_x = 0.5f ;
float ul_y = ( settings . scr_res_y - height ) / 2.0f ;
float lr_y = settings . scr_res_y - ul_y - 1.0f ;
float lr_x = settings . scr_res_x - 1.0f ;
float lr_u = ( fb_info . width - 1 ) * scale ;
float lr_v = ( fb_info . height - 1 ) * scale ;
VERTEX v [ 4 ] = {
{ ul_x , ul_y , 1 , 1 , 0.5f , 0.5f , 0.5f , 0.5f , { 0.5f , 0.5f , 0.5f , 0.5f } } ,
{ lr_x , ul_y , 1 , 1 , lr_u , 0.5f , lr_u , 0.5f , { lr_u , 0.5f , lr_u , 0.5f } } ,
{ ul_x , lr_y , 1 , 1 , 0.5f , lr_v , 0.5f , lr_v , { 0.5f , lr_v , 0.5f , lr_v } } ,
{ lr_x , lr_y , 1 , 1 , lr_u , lr_v , lr_u , lr_v , { lr_u , lr_v , lr_u , lr_v } }
} ;
grDrawTriangle ( & v [ 0 ] , & v [ 2 ] , & v [ 1 ] ) ;
grDrawTriangle ( & v [ 2 ] , & v [ 3 ] , & v [ 1 ] ) ;
}
static void DrawRE2Video256 ( FB_TO_SCREEN_INFO & fb_info )
{
FRDP ( " DrawRE2Video256. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx \n " , fb_info . ul_x , fb_info . ul_y , fb_info . lr_x , fb_info . lr_y , fb_info . size , fb_info . addr ) ;
wxUint32 * src = ( wxUint32 * ) ( gfx . RDRAM + fb_info . addr ) ;
GrTexInfo t_info ;
t_info . smallLodLog2 = GR_LOD_LOG2_256 ;
t_info . largeLodLog2 = GR_LOD_LOG2_256 ;
t_info . aspectRatioLog2 = GR_ASPECT_LOG2_1x1 ;
wxUint16 * tex = ( wxUint16 * ) texture_buffer ;
wxUint16 * dst = tex ;
wxUint32 col ;
wxUint8 r , g , b ;
fb_info . height = min ( 256 , fb_info . height ) ;
for ( wxUint32 h = 0 ; h < fb_info . height ; h + + )
{
for ( wxUint32 w = 0 ; w < 256 ; w + + )
{
col = * ( src + + ) ;
r = ( wxUint8 ) ( ( col > > 24 ) & 0xFF ) ;
r = ( wxUint8 ) ( ( float ) r / 255.0f * 31.0f ) ;
g = ( wxUint8 ) ( ( col > > 16 ) & 0xFF ) ;
g = ( wxUint8 ) ( ( float ) g / 255.0f * 63.0f ) ;
b = ( wxUint8 ) ( ( col > > 8 ) & 0xFF ) ;
b = ( wxUint8 ) ( ( float ) b / 255.0f * 31.0f ) ;
* ( dst + + ) = ( r < < 11 ) | ( g < < 5 ) | b ;
}
src + = ( fb_info . width - 256 ) ;
}
t_info . format = GR_TEXFMT_RGB_565 ;
t_info . data = tex ;
int tmu = SetupFBtoScreenCombiner ( grTexTextureMemRequired ( GR_MIPMAPLEVELMASK_BOTH , & t_info ) , fb_info . opaque ) ;
grTexDownloadMipMap ( tmu ,
voodoo . tex_min_addr [ tmu ] + voodoo . tmem_ptr [ tmu ] ,
GR_MIPMAPLEVELMASK_BOTH ,
& t_info ) ;
grTexSource ( tmu ,
voodoo . tex_min_addr [ tmu ] + voodoo . tmem_ptr [ tmu ] ,
GR_MIPMAPLEVELMASK_BOTH ,
& t_info ) ;
DrawRE2Video ( fb_info , 1.0f ) ;
}
static void DrawFrameBufferToScreen256 ( FB_TO_SCREEN_INFO & fb_info )
{
if ( settings . hacks & hack_RE2 )
{
DrawRE2Video256 ( fb_info ) ;
return ;
}
FRDP ( " DrawFrameBufferToScreen256. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx \n " , fb_info . ul_x , fb_info . ul_y , fb_info . lr_x , fb_info . lr_y , fb_info . size , fb_info . addr ) ;
wxUint32 width = fb_info . lr_x - fb_info . ul_x + 1 ;
wxUint32 height = fb_info . lr_y - fb_info . ul_y + 1 ;
GrTexInfo t_info ;
wxUint8 * image = gfx . RDRAM + fb_info . addr ;
wxUint32 width256 = ( ( width - 1 ) > > 8 ) + 1 ;
wxUint32 height256 = ( ( height - 1 ) > > 8 ) + 1 ;
t_info . smallLodLog2 = t_info . largeLodLog2 = GR_LOD_LOG2_256 ;
t_info . aspectRatioLog2 = GR_ASPECT_LOG2_1x1 ;
t_info . format = GR_TEXFMT_ARGB_1555 ;
wxUint16 * tex = ( wxUint16 * ) texture_buffer ;
t_info . data = tex ;
wxUint32 tex_size = grTexTextureMemRequired ( GR_MIPMAPLEVELMASK_BOTH , & t_info ) ;
int tmu = SetupFBtoScreenCombiner ( tex_size * width256 * height256 , fb_info . opaque ) ;
wxUint16 * src = ( wxUint16 * ) image ;
src + = fb_info . ul_x + fb_info . ul_y * fb_info . width ;
wxUint32 * src32 = ( wxUint32 * ) image ;
src32 + = fb_info . ul_x + fb_info . ul_y * fb_info . width ;
wxUint32 w_tail = width % 256 ;
wxUint32 h_tail = height % 256 ;
wxUint16 c ;
wxUint32 c32 ;
wxUint32 idx ;
wxUint32 bound = BMASK + 1 - fb_info . addr ;
bound = fb_info . size = = 2 ? bound > > 1 : bound > > 2 ;
wxUint8 r , g , b , a ;
wxUint32 cur_width , cur_height , cur_tail ;
wxUint32 tex_adr = voodoo . tex_min_addr [ tmu ] + voodoo . tmem_ptr [ tmu ] ;
if ( ( voodoo . tmem_ptr [ tmu ] < TEXMEM_2MB_EDGE ) & & ( voodoo . tmem_ptr [ tmu ] + tex_size * width256 * height256 > TEXMEM_2MB_EDGE ) )
{
tex_adr = TEXMEM_2MB_EDGE ;
}
for ( wxUint32 h = 0 ; h < height256 ; h + + )
{
for ( wxUint32 w = 0 ; w < width256 ; w + + )
{
cur_width = ( 256 * ( w + 1 ) < width ) ? 256 : w_tail ;
cur_height = ( 256 * ( h + 1 ) < height ) ? 256 : h_tail ;
cur_tail = 256 - cur_width ;
wxUint16 * dst = tex ;
if ( fb_info . size = = 2 )
{
for ( wxUint32 y = 0 ; y < cur_height ; y + + )
{
for ( wxUint32 x = 0 ; x < cur_width ; x + + )
{
idx = ( x + 256 * w + ( y + 256 * h ) * fb_info . width ) ^ 1 ;
if ( idx > = bound )
break ;
c = src [ idx ] ;
* ( dst + + ) = ( c > > 1 ) | ( ( c & 1 ) < < 15 ) ;
}
dst + = cur_tail ;
}
}
else
{
for ( wxUint32 y = 0 ; y < cur_height ; y + + )
{
for ( wxUint32 x = 0 ; x < cur_width ; x + + )
{
idx = ( x + 256 * w + ( y + 256 * h ) * fb_info . width ) ;
if ( idx > = bound )
break ;
c32 = src32 [ idx ] ;
r = ( wxUint8 ) ( ( c32 > > 24 ) & 0xFF ) ;
r = ( wxUint8 ) ( ( float ) r / 255.0f * 31.0f ) ;
g = ( wxUint8 ) ( ( c32 > > 16 ) & 0xFF ) ;
g = ( wxUint8 ) ( ( float ) g / 255.0f * 63.0f ) ;
b = ( wxUint8 ) ( ( c32 > > 8 ) & 0xFF ) ;
b = ( wxUint8 ) ( ( float ) b / 255.0f * 31.0f ) ;
a = ( c32 & 0xFF ) ? 1 : 0 ;
* ( dst + + ) = ( a < < 15 ) | ( r < < 10 ) | ( g < < 5 ) | b ;
}
dst + = cur_tail ;
}
}
grTexDownloadMipMap ( tmu , tex_adr , GR_MIPMAPLEVELMASK_BOTH , & t_info ) ;
grTexSource ( tmu , tex_adr , GR_MIPMAPLEVELMASK_BOTH , & t_info ) ;
tex_adr + = tex_size ;
float ul_x = ( float ) ( fb_info . ul_x + 256 * w ) ;
float ul_y = ( float ) ( fb_info . ul_y + 256 * h ) ;
float lr_x = ( ul_x + ( float ) ( cur_width ) ) * rdp . scale_x ;
float lr_y = ( ul_y + ( float ) ( cur_height ) ) * rdp . scale_y ;
ul_x * = rdp . scale_x ;
ul_y * = rdp . scale_y ;
ul_x + = rdp . offset_x ;
ul_y + = rdp . offset_y ;
lr_x + = rdp . offset_x ;
lr_y + = rdp . offset_y ;
float lr_u = ( float ) ( cur_width - 1 ) ;
float lr_v = ( float ) ( cur_height - 1 ) ;
// Make the vertices
VERTEX v [ 4 ] = {
{ ul_x , ul_y , 1 , 1 , 0.5f , 0.5f , 0.5f , 0.5f , { 0.5f , 0.5f , 0.5f , 0.5f } } ,
{ lr_x , ul_y , 1 , 1 , lr_u , 0.5f , lr_u , 0.5f , { lr_u , 0.5f , lr_u , 0.5f } } ,
{ ul_x , lr_y , 1 , 1 , 0.5f , lr_v , 0.5f , lr_v , { 0.5f , lr_v , 0.5f , lr_v } } ,
{ lr_x , lr_y , 1 , 1 , lr_u , lr_v , lr_u , lr_v , { lr_u , lr_v , lr_u , lr_v } }
} ;
grDrawTriangle ( & v [ 0 ] , & v [ 2 ] , & v [ 1 ] ) ;
grDrawTriangle ( & v [ 2 ] , & v [ 3 ] , & v [ 1 ] ) ;
}
}
}
bool DrawFrameBufferToScreen ( FB_TO_SCREEN_INFO & fb_info )
{
if ( fb_info . width < 200 | | fb_info . size < 2 )
return false ;
wxUint32 width = fb_info . lr_x - fb_info . ul_x + 1 ;
wxUint32 height = fb_info . lr_y - fb_info . ul_y + 1 ;
wxUint32 max_size = min ( voodoo . max_tex_size , 512 ) ;
if ( width > ( wxUint32 ) max_size | | height > ( wxUint32 ) max_size )
{
DrawFrameBufferToScreen256 ( fb_info ) ;
return true ;
}
FRDP ( " DrawFrameBufferToScreen. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx \n " , fb_info . ul_x , fb_info . ul_y , fb_info . lr_x , fb_info . lr_y , fb_info . size , fb_info . addr ) ;
GrTexInfo t_info ;
wxUint8 * image = gfx . RDRAM + fb_info . addr ;
2015-10-11 10:12:32 +00:00
wxUint32 texwidth ;
2013-04-04 21:22:19 +00:00
float scale ;
if ( width < = 256 )
{
texwidth = 256 ;
scale = 1.0f ;
t_info . smallLodLog2 = t_info . largeLodLog2 = GR_LOD_LOG2_256 ;
}
else
{
texwidth = 512 ;
scale = 0.5f ;
t_info . smallLodLog2 = t_info . largeLodLog2 = GR_LOD_LOG2_512 ;
}
if ( height < = ( texwidth > > 1 ) )
{
t_info . aspectRatioLog2 = GR_ASPECT_LOG2_2x1 ;
}
else
{
t_info . aspectRatioLog2 = GR_ASPECT_LOG2_1x1 ;
}
if ( fb_info . size = = 2 )
{
wxUint16 * tex = ( wxUint16 * ) texture_buffer ;
wxUint16 * dst = tex ;
wxUint16 * src = ( wxUint16 * ) image ;
src + = fb_info . ul_x + fb_info . ul_y * fb_info . width ;
wxUint16 c ;
wxUint32 idx ;
const wxUint32 bound = ( BMASK + 1 - fb_info . addr ) > > 1 ;
bool empty = true ;
for ( wxUint32 y = 0 ; y < height ; y + + )
{
for ( wxUint32 x = 0 ; x < width ; x + + )
{
idx = ( x + y * fb_info . width ) ^ 1 ;
if ( idx > = bound )
break ;
c = src [ idx ] ;
if ( c ) empty = false ;
* ( dst + + ) = ( c > > 1 ) | ( ( c & 1 ) < < 15 ) ;
}
dst + = texwidth - width ;
}
if ( empty )
return false ;
t_info . format = GR_TEXFMT_ARGB_1555 ;
t_info . data = tex ;
}
else
{
wxUint32 * tex = ( wxUint32 * ) texture_buffer ;
wxUint32 * dst = tex ;
wxUint32 * src = ( wxUint32 * ) image ;
src + = fb_info . ul_x + fb_info . ul_y * fb_info . width ;
wxUint32 col ;
wxUint32 idx ;
const wxUint32 bound = ( BMASK + 1 - fb_info . addr ) > > 2 ;
for ( wxUint32 y = 0 ; y < height ; y + + )
{
for ( wxUint32 x = 0 ; x < width ; x + + )
{
idx = x + y * fb_info . width ;
if ( idx > = bound )
break ;
col = src [ idx ] ;
* ( dst + + ) = ( col > > 8 ) | 0xFF000000 ;
}
dst + = texwidth - width ;
}
t_info . format = GR_TEXFMT_ARGB_8888 ;
t_info . data = tex ;
}
int tmu = SetupFBtoScreenCombiner ( grTexTextureMemRequired ( GR_MIPMAPLEVELMASK_BOTH , & t_info ) , fb_info . opaque ) ;
grTexDownloadMipMap ( tmu ,
voodoo . tex_min_addr [ tmu ] + voodoo . tmem_ptr [ tmu ] ,
GR_MIPMAPLEVELMASK_BOTH ,
& t_info ) ;
grTexSource ( tmu ,
voodoo . tex_min_addr [ tmu ] + voodoo . tmem_ptr [ tmu ] ,
GR_MIPMAPLEVELMASK_BOTH ,
& t_info ) ;
if ( settings . hacks & hack_RE2 )
{
DrawRE2Video ( fb_info , scale ) ;
}
else
{
float ul_x = fb_info . ul_x * rdp . scale_x + rdp . offset_x ;
float ul_y = fb_info . ul_y * rdp . scale_y + rdp . offset_y ;
float lr_x = fb_info . lr_x * rdp . scale_x + rdp . offset_x ;
float lr_y = fb_info . lr_y * rdp . scale_y + rdp . offset_y ;
float lr_u = ( width - 1 ) * scale ;
float lr_v = ( height - 1 ) * scale ;
// Make the vertices
VERTEX v [ 4 ] = {
{ ul_x , ul_y , 1 , 1 , 0.5f , 0.5f , 0.5f , 0.5f , { 0.5f , 0.5f , 0.5f , 0.5f } } ,
{ lr_x , ul_y , 1 , 1 , lr_u , 0.5f , lr_u , 0.5f , { lr_u , 0.5f , lr_u , 0.5f } } ,
{ ul_x , lr_y , 1 , 1 , 0.5f , lr_v , 0.5f , lr_v , { 0.5f , lr_v , 0.5f , lr_v } } ,
{ lr_x , lr_y , 1 , 1 , lr_u , lr_v , lr_u , lr_v , { lr_u , lr_v , lr_u , lr_v } }
} ;
grDrawTriangle ( & v [ 0 ] , & v [ 2 ] , & v [ 1 ] ) ;
grDrawTriangle ( & v [ 2 ] , & v [ 3 ] , & v [ 1 ] ) ;
}
return true ;
}
static void DrawDepthBufferToScreen256 ( FB_TO_SCREEN_INFO & fb_info )
{
FRDP ( " DrawDepthBufferToScreen256. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx \n " , fb_info . ul_x , fb_info . ul_y , fb_info . lr_x , fb_info . lr_y , fb_info . size , fb_info . addr ) ;
wxUint32 width = fb_info . lr_x - fb_info . ul_x + 1 ;
wxUint32 height = fb_info . lr_y - fb_info . ul_y + 1 ;
GrTexInfo t_info ;
wxUint8 * image = gfx . RDRAM + fb_info . addr ;
wxUint32 width256 = ( ( width - 1 ) > > 8 ) + 1 ;
wxUint32 height256 = ( ( height - 1 ) > > 8 ) + 1 ;
t_info . smallLodLog2 = t_info . largeLodLog2 = GR_LOD_LOG2_256 ;
t_info . aspectRatioLog2 = GR_ASPECT_LOG2_1x1 ;
t_info . format = GR_TEXFMT_ALPHA_INTENSITY_88 ;
wxUint16 * tex = ( wxUint16 * ) texture_buffer ;
t_info . data = tex ;
wxUint32 tex_size = grTexTextureMemRequired ( GR_MIPMAPLEVELMASK_BOTH , & t_info ) ;
int tmu = SetupFBtoScreenCombiner ( tex_size * width256 * height256 , fb_info . opaque ) ;
grConstantColorValue ( rdp . fog_color ) ;
grColorCombine ( GR_COMBINE_FUNCTION_SCALE_OTHER ,
GR_COMBINE_FACTOR_ONE ,
GR_COMBINE_LOCAL_NONE ,
GR_COMBINE_OTHER_CONSTANT ,
FXFALSE ) ;
wxUint16 * src = ( wxUint16 * ) image ;
src + = fb_info . ul_x + fb_info . ul_y * fb_info . width ;
wxUint32 w_tail = width % 256 ;
wxUint32 h_tail = height % 256 ;
wxUint32 cur_width , cur_height , cur_tail ;
wxUint32 tex_adr = voodoo . tex_min_addr [ tmu ] + voodoo . tmem_ptr [ tmu ] ;
if ( ( voodoo . tmem_ptr [ tmu ] < TEXMEM_2MB_EDGE ) & & ( voodoo . tmem_ptr [ tmu ] + tex_size * width256 * height256 > TEXMEM_2MB_EDGE ) )
{
tex_adr = TEXMEM_2MB_EDGE ;
}
for ( wxUint32 h = 0 ; h < height256 ; h + + )
{
for ( wxUint32 w = 0 ; w < width256 ; w + + )
{
cur_width = ( 256 * ( w + 1 ) < width ) ? 256 : w_tail ;
cur_height = ( 256 * ( h + 1 ) < height ) ? 256 : h_tail ;
cur_tail = 256 - cur_width ;
wxUint16 * dst = tex ;
for ( wxUint32 y = 0 ; y < cur_height ; y + + )
{
for ( wxUint32 x = 0 ; x < cur_width ; x + + )
{
* ( dst + + ) = rdp . pal_8 [ src [ ( x + 256 * w + ( y + 256 * h ) * fb_info . width ) ^ 1 ] > > 8 ] ;
}
dst + = cur_tail ;
}
grTexDownloadMipMap ( tmu , tex_adr , GR_MIPMAPLEVELMASK_BOTH , & t_info ) ;
grTexSource ( tmu , tex_adr , GR_MIPMAPLEVELMASK_BOTH , & t_info ) ;
tex_adr + = tex_size ;
float ul_x = ( float ) ( fb_info . ul_x + 256 * w ) ;
float ul_y = ( float ) ( fb_info . ul_y + 256 * h ) ;
float lr_x = ( ul_x + ( float ) ( cur_width ) ) * rdp . scale_x + rdp . offset_x ;
float lr_y = ( ul_y + ( float ) ( cur_height ) ) * rdp . scale_y + rdp . offset_y ;
ul_x = ul_x * rdp . scale_x + rdp . offset_x ;
ul_y = ul_y * rdp . scale_y + rdp . offset_y ;
float lr_u = ( float ) ( cur_width - 1 ) ;
float lr_v = ( float ) ( cur_height - 1 ) ;
// Make the vertices
VERTEX v [ 4 ] = {
{ ul_x , ul_y , 1 , 1 , 0.5f , 0.5f , 0.5f , 0.5f , { 0.5f , 0.5f , 0.5f , 0.5f } } ,
{ lr_x , ul_y , 1 , 1 , lr_u , 0.5f , lr_u , 0.5f , { lr_u , 0.5f , lr_u , 0.5f } } ,
{ ul_x , lr_y , 1 , 1 , 0.5f , lr_v , 0.5f , lr_v , { 0.5f , lr_v , 0.5f , lr_v } } ,
{ lr_x , lr_y , 1 , 1 , lr_u , lr_v , lr_u , lr_v , { lr_u , lr_v , lr_u , lr_v } }
} ;
grDrawTriangle ( & v [ 0 ] , & v [ 2 ] , & v [ 1 ] ) ;
grDrawTriangle ( & v [ 2 ] , & v [ 3 ] , & v [ 1 ] ) ;
}
}
}
static void DrawHiresDepthBufferToScreen ( FB_TO_SCREEN_INFO & fb_info )
{
FRDP ( " DrawHiresDepthBufferToScreen. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx \n " , fb_info . ul_x , fb_info . ul_y , fb_info . lr_x , fb_info . lr_y , fb_info . size , fb_info . addr ) ;
GrTexInfo t_info ;
float scale = 0.25f ;
GrLOD_t LOD = GR_LOD_LOG2_1024 ;
if ( settings . scr_res_x > 1024 )
{
scale = 0.125f ;
LOD = GR_LOD_LOG2_2048 ;
}
t_info . format = GR_TEXFMT_ALPHA_INTENSITY_88 ;
t_info . smallLodLog2 = t_info . largeLodLog2 = LOD ;
t_info . aspectRatioLog2 = GR_ASPECT_LOG2_1x1 ;
grConstantColorValue ( rdp . fog_color ) ;
grColorCombine ( GR_COMBINE_FUNCTION_LOCAL ,
GR_COMBINE_FACTOR_NONE ,
GR_COMBINE_LOCAL_CONSTANT ,
GR_COMBINE_OTHER_NONE ,
FXFALSE ) ;
grAlphaCombine ( GR_COMBINE_FUNCTION_SCALE_OTHER ,
GR_COMBINE_FACTOR_ONE ,
GR_COMBINE_LOCAL_NONE ,
GR_COMBINE_OTHER_TEXTURE ,
FXFALSE ) ;
grAlphaBlendFunction ( GR_BLEND_SRC_ALPHA ,
GR_BLEND_ONE_MINUS_SRC_ALPHA ,
GR_BLEND_ONE ,
GR_BLEND_ZERO ) ;
grDepthBufferFunction ( GR_CMP_ALWAYS ) ;
grDepthMask ( FXFALSE ) ;
grCullMode ( GR_CULL_DISABLE ) ;
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 ) ;
// grAuxBufferExt( GR_BUFFER_AUXBUFFER );
grTexSource ( rdp . texbufs [ 0 ] . tmu , rdp . texbufs [ 0 ] . begin , GR_MIPMAPLEVELMASK_BOTH , & ( t_info ) ) ;
float ul_x = ( float ) rdp . scissor . ul_x ;
float ul_y = ( float ) rdp . scissor . ul_y ;
float lr_x = ( float ) rdp . scissor . lr_x ;
float lr_y = ( float ) rdp . scissor . lr_y ;
float ul_u = ( float ) rdp . scissor . ul_x * scale ;
float ul_v = ( float ) rdp . scissor . ul_y * scale ;
float lr_u = ( float ) rdp . scissor . lr_x * scale ;
float lr_v = ( float ) rdp . scissor . lr_y * scale ;
// Make the vertices
VERTEX v [ 4 ] = {
{ ul_x , ul_y , 1 , 1 , ul_u , ul_v , ul_u , ul_v , { ul_u , ul_v , ul_u , ul_v } } ,
{ lr_x , ul_y , 1 , 1 , lr_u , ul_v , lr_u , ul_v , { lr_u , ul_v , lr_u , ul_v } } ,
{ ul_x , lr_y , 1 , 1 , ul_u , lr_v , ul_u , lr_v , { ul_u , lr_v , ul_u , lr_v } } ,
{ lr_x , lr_y , 1 , 1 , lr_u , lr_v , lr_u , lr_v , { lr_u , lr_v , lr_u , lr_v } }
} ;
grDrawTriangle ( & v [ 0 ] , & v [ 2 ] , & v [ 1 ] ) ;
grDrawTriangle ( & v [ 2 ] , & v [ 3 ] , & v [ 1 ] ) ;
// grAuxBufferExt( GR_BUFFER_TEXTUREAUXBUFFER_EXT );
rdp . update | = UPDATE_COMBINE | UPDATE_ZBUF_ENABLED | UPDATE_CULL_MODE ;
}
void DrawDepthBufferToScreen ( FB_TO_SCREEN_INFO & fb_info )
{
wxUint32 width = fb_info . lr_x - fb_info . ul_x + 1 ;
wxUint32 height = fb_info . lr_y - fb_info . ul_y + 1 ;
if ( width > ( wxUint32 ) voodoo . max_tex_size | | height > ( wxUint32 ) voodoo . max_tex_size | | width > 512 )
{
DrawDepthBufferToScreen256 ( fb_info ) ;
return ;
}
if ( fb_hwfbe_enabled & & ! evoodoo )
{
DrawHiresDepthBufferToScreen ( fb_info ) ;
return ;
}
FRDP ( " DrawDepthBufferToScreen. ul_x=%d, ul_y=%d, lr_x=%d, lr_y=%d, size=%d, addr=%08lx \n " , fb_info . ul_x , fb_info . ul_y , fb_info . lr_x , fb_info . lr_y , fb_info . size , fb_info . addr ) ;
GrTexInfo t_info ;
wxUint8 * image = gfx . RDRAM + fb_info . addr ;
2015-10-11 10:12:32 +00:00
wxUint32 texwidth ;
2013-04-04 21:22:19 +00:00
float scale ;
if ( width < = 256 )
{
texwidth = 256 ;
scale = 1.0f ;
t_info . smallLodLog2 = t_info . largeLodLog2 = GR_LOD_LOG2_256 ;
}
else
{
texwidth = 512 ;
scale = 0.5f ;
t_info . smallLodLog2 = t_info . largeLodLog2 = GR_LOD_LOG2_512 ;
}
if ( height < = ( texwidth > > 1 ) )
{
t_info . aspectRatioLog2 = GR_ASPECT_LOG2_2x1 ;
}
else
{
t_info . aspectRatioLog2 = GR_ASPECT_LOG2_1x1 ;
}
wxUint16 * tex = ( wxUint16 * ) texture_buffer ;
wxUint16 * dst = tex ;
wxUint16 * src = ( wxUint16 * ) image ;
src + = fb_info . ul_x + fb_info . ul_y * fb_info . width ;
for ( wxUint32 y = 0 ; y < height ; y + + )
{
for ( wxUint32 x = 0 ; x < width ; x + + )
{
* ( dst + + ) = rdp . pal_8 [ src [ ( x + y * fb_info . width ) ^ 1 ] > > 8 ] ;
}
dst + = texwidth - width ;
}
t_info . format = GR_TEXFMT_ALPHA_INTENSITY_88 ;
t_info . data = tex ;
int tmu = SetupFBtoScreenCombiner ( grTexTextureMemRequired ( GR_MIPMAPLEVELMASK_BOTH , & t_info ) , fb_info . opaque ) ;
grConstantColorValue ( rdp . fog_color ) ;
grColorCombine ( GR_COMBINE_FUNCTION_SCALE_OTHER ,
GR_COMBINE_FACTOR_ONE ,
GR_COMBINE_LOCAL_NONE ,
GR_COMBINE_OTHER_CONSTANT ,
FXFALSE ) ;
grTexDownloadMipMap ( tmu ,
voodoo . tex_min_addr [ tmu ] + voodoo . tmem_ptr [ tmu ] ,
GR_MIPMAPLEVELMASK_BOTH ,
& t_info ) ;
grTexSource ( tmu ,
voodoo . tex_min_addr [ tmu ] + voodoo . tmem_ptr [ tmu ] ,
GR_MIPMAPLEVELMASK_BOTH ,
& t_info ) ;
float ul_x = fb_info . ul_x * rdp . scale_x + rdp . offset_x ;
float ul_y = fb_info . ul_y * rdp . scale_y + rdp . offset_y ;
float lr_x = fb_info . lr_x * rdp . scale_x + rdp . offset_x ;
float lr_y = fb_info . lr_y * rdp . scale_y + rdp . offset_y ;
float lr_u = ( width - 1 ) * scale ;
float lr_v = ( height - 1 ) * scale ;
float zero = scale * 0.5f ;
// Make the vertices
VERTEX v [ 4 ] = {
{ ul_x , ul_y , 1 , 1 , zero , zero , zero , zero , { zero , zero , zero , zero } } ,
{ lr_x , ul_y , 1 , 1 , lr_u , zero , lr_u , zero , { lr_u , zero , lr_u , zero } } ,
{ ul_x , lr_y , 1 , 1 , zero , lr_v , zero , lr_v , { zero , lr_v , zero , lr_v } } ,
{ lr_x , lr_y , 1 , 1 , lr_u , lr_v , lr_u , lr_v , { lr_u , lr_v , lr_u , lr_v } }
} ;
grDrawTriangle ( & v [ 0 ] , & v [ 2 ] , & v [ 1 ] ) ;
grDrawTriangle ( & v [ 2 ] , & v [ 3 ] , & v [ 1 ] ) ;
}