X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=source%2Fgles2glide64%2Fsrc%2FGlide64%2FFBtoScreen.cpp;fp=source%2Fgles2glide64%2Fsrc%2FGlide64%2FFBtoScreen.cpp;h=46c06faf2f6fb0f56606651f77944e1465e2a448;hb=98e75f2d18c02c233da543560f76282f04fc796c;hp=0000000000000000000000000000000000000000;hpb=0ced54f867d36e8b324155bef49e8abfebfc3237;p=mupen64plus-pandora.git diff --git a/source/gles2glide64/src/Glide64/FBtoScreen.cpp b/source/gles2glide64/src/Glide64/FBtoScreen.cpp new file mode 100755 index 0000000..46c06fa --- /dev/null +++ b/source/gles2glide64/src/Glide64/FBtoScreen.cpp @@ -0,0 +1,665 @@ +/* +* 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 +// +//**************************************************************** + + +#include "Gfx_1.3.h" +#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+3))&0x1F); + g = (wxUint8)((col >> (16+2))&0x3F); + b = (wxUint8)((col >> (8+3))&0x1F); +/* 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);*/ //*SEB* + *(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+3))&0x1F); + g = (wxUint8)((c32 >> (16+2))&0x3F); + b = (wxUint8)((c32 >> (8+3))&0x1F); +/* 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);*/ //*SEB* + 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; + wxUint32 texwidth; + 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; + wxUint32 texwidth; + 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]); +}