Path: blob/master/libmupen64plus/mupen64plus-video-glide64mk2/src/Glide64/FBtoScreen.cpp
2 views
/*1* Glide64 - Glide video plugin for Nintendo 64 emulators.2* Copyright (c) 2002 Dave20013* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License as published by7* the Free Software Foundation; either version 2 of the License, or8* any later version.9*10* This program is distributed in the hope that it will be useful,11* but WITHOUT ANY WARRANTY; without even the implied warranty of12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13* GNU General Public License for more details.14*15* You should have received a copy of the GNU General Public License16* along with this program; if not, write to the Free Software17* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18*/1920//****************************************************************21//22// Glide64 - Glide Plugin for Nintendo 64 emulators23// Project started on December 29th, 200124//25// Authors:26// Dave2001, original author, founded the project in 2001, left it in 200227// Gugaman, joined the project in 2002, left it in 200228// Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 200229// Hiroshi 'KoolSmoky' Morii, joined the project in 200730//31//****************************************************************32//33// To modify Glide64:34// * 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.35// * 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.36//37//****************************************************************38//39// Draw N64 frame buffer to screen.40// Created by Gonetz, 200741//42//****************************************************************434445#include "Gfx_1.3.h"46#include "FBtoScreen.h"47#include "TexCache.h"4849static int SetupFBtoScreenCombiner(wxUint32 texture_size, wxUint32 opaque)50{51int tmu;52if (voodoo.tmem_ptr[GR_TMU0]+texture_size < voodoo.tex_max_addr[0])53{54tmu = GR_TMU0;55grTexCombine( GR_TMU1,56GR_COMBINE_FUNCTION_NONE,57GR_COMBINE_FACTOR_NONE,58GR_COMBINE_FUNCTION_NONE,59GR_COMBINE_FACTOR_NONE,60FXFALSE,61FXFALSE );62grTexCombine( GR_TMU0,63GR_COMBINE_FUNCTION_LOCAL,64GR_COMBINE_FACTOR_NONE,65GR_COMBINE_FUNCTION_LOCAL,66GR_COMBINE_FACTOR_NONE,67FXFALSE,68FXFALSE );69}70else71{72if (voodoo.tmem_ptr[GR_TMU1]+texture_size >= voodoo.tex_max_addr[1])73ClearCache ();74tmu = GR_TMU1;75grTexCombine( GR_TMU1,76GR_COMBINE_FUNCTION_LOCAL,77GR_COMBINE_FACTOR_NONE,78GR_COMBINE_FUNCTION_LOCAL,79GR_COMBINE_FACTOR_NONE,80FXFALSE,81FXFALSE );82grTexCombine( GR_TMU0,83GR_COMBINE_FUNCTION_SCALE_OTHER,84GR_COMBINE_FACTOR_ONE,85GR_COMBINE_FUNCTION_SCALE_OTHER,86GR_COMBINE_FACTOR_ONE,87FXFALSE,88FXFALSE );89}90int filter = (rdp.filter_mode!=2)?GR_TEXTUREFILTER_POINT_SAMPLED:GR_TEXTUREFILTER_BILINEAR;91grTexFilterMode (tmu, filter, filter);92grTexClampMode (tmu,93GR_TEXTURECLAMP_CLAMP,94GR_TEXTURECLAMP_CLAMP);95// grConstantColorValue (0xFFFFFFFF);96grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,97GR_COMBINE_FACTOR_ONE,98GR_COMBINE_LOCAL_NONE,99GR_COMBINE_OTHER_TEXTURE,100// GR_COMBINE_OTHER_CONSTANT,101FXFALSE);102grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,103GR_COMBINE_FACTOR_ONE,104GR_COMBINE_LOCAL_NONE,105GR_COMBINE_OTHER_TEXTURE,106FXFALSE);107if (opaque)108{109grAlphaTestFunction (GR_CMP_ALWAYS);110grAlphaBlendFunction( GR_BLEND_ONE,111GR_BLEND_ZERO,112GR_BLEND_ONE,113GR_BLEND_ZERO);114}115else116{117grAlphaBlendFunction( GR_BLEND_SRC_ALPHA,118GR_BLEND_ONE_MINUS_SRC_ALPHA,119GR_BLEND_ONE,120GR_BLEND_ZERO);121}122grDepthBufferFunction (GR_CMP_ALWAYS);123grCullMode(GR_CULL_DISABLE);124grDepthMask (FXFALSE);125rdp.update |= UPDATE_COMBINE | UPDATE_ZBUF_ENABLED | UPDATE_CULL_MODE;126return tmu;127}128129static void DrawRE2Video(FB_TO_SCREEN_INFO & fb_info, float scale)130{131float scale_y = (float)fb_info.width/rdp.vi_height;132float height = settings.scr_res_x/scale_y;133float ul_x = 0.5f;134float ul_y = (settings.scr_res_y - height)/2.0f;135float lr_y = settings.scr_res_y - ul_y - 1.0f;136float lr_x = settings.scr_res_x - 1.0f;137float lr_u = (fb_info.width - 1)*scale;138float lr_v = (fb_info.height - 1)*scale;139VERTEX v[4] = {140{ ul_x, ul_y, 1, 1, 0.5f, 0.5f, 0.5f, 0.5f, {0.5f, 0.5f, 0.5f, 0.5f} },141{ lr_x, ul_y, 1, 1, lr_u, 0.5f, lr_u, 0.5f, {lr_u, 0.5f, lr_u, 0.5f} },142{ ul_x, lr_y, 1, 1, 0.5f, lr_v, 0.5f, lr_v, {0.5f, lr_v, 0.5f, lr_v} },143{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }144};145grDrawTriangle (&v[0], &v[2], &v[1]);146grDrawTriangle (&v[2], &v[3], &v[1]);147}148149static void DrawRE2Video256(FB_TO_SCREEN_INFO & fb_info)150{151FRDP("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);152wxUint32 * src = (wxUint32*)(gfx.RDRAM+fb_info.addr);153GrTexInfo t_info;154t_info.smallLodLog2 = GR_LOD_LOG2_256;155t_info.largeLodLog2 = GR_LOD_LOG2_256;156t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;157wxUint16 * tex = (wxUint16*)texture_buffer;158wxUint16 * dst = tex;159wxUint32 col;160wxUint8 r, g, b;161fb_info.height = min(256, fb_info.height);162for (wxUint32 h = 0; h < fb_info.height; h++)163{164for (wxUint32 w = 0; w < 256; w++)165{166col = *(src++);167r = (wxUint8)((col >> 24)&0xFF);168r = (wxUint8)((float)r / 255.0f * 31.0f);169g = (wxUint8)((col >> 16)&0xFF);170g = (wxUint8)((float)g / 255.0f * 63.0f);171b = (wxUint8)((col >> 8)&0xFF);172b = (wxUint8)((float)b / 255.0f * 31.0f);173*(dst++) = (r << 11) | (g << 5) | b;174}175src += (fb_info.width - 256);176}177t_info.format = GR_TEXFMT_RGB_565;178t_info.data = tex;179int tmu = SetupFBtoScreenCombiner(grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &t_info), fb_info.opaque);180grTexDownloadMipMap (tmu,181voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu],182GR_MIPMAPLEVELMASK_BOTH,183&t_info);184grTexSource (tmu,185voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu],186GR_MIPMAPLEVELMASK_BOTH,187&t_info);188DrawRE2Video(fb_info, 1.0f);189}190191static void DrawFrameBufferToScreen256(FB_TO_SCREEN_INFO & fb_info)192{193if (settings.hacks&hack_RE2)194{195DrawRE2Video256(fb_info);196return;197}198FRDP("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);199wxUint32 width = fb_info.lr_x - fb_info.ul_x + 1;200wxUint32 height = fb_info.lr_y - fb_info.ul_y + 1;201GrTexInfo t_info;202wxUint8 * image = gfx.RDRAM+fb_info.addr;203wxUint32 width256 = ((width-1) >> 8) + 1;204wxUint32 height256 = ((height-1) >> 8) + 1;205t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256;206t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;207t_info.format = GR_TEXFMT_ARGB_1555;208wxUint16 * tex = (wxUint16*)texture_buffer;209t_info.data = tex;210wxUint32 tex_size = grTexTextureMemRequired (GR_MIPMAPLEVELMASK_BOTH, &t_info);211int tmu = SetupFBtoScreenCombiner(tex_size*width256*height256, fb_info.opaque);212wxUint16 * src = (wxUint16*)image;213src += fb_info.ul_x + fb_info.ul_y * fb_info.width;214wxUint32 * src32 = (wxUint32*)image;215src32 += fb_info.ul_x + fb_info.ul_y * fb_info.width;216wxUint32 w_tail = width%256;217wxUint32 h_tail = height%256;218wxUint16 c;219wxUint32 c32;220wxUint32 idx;221wxUint32 bound = BMASK+1-fb_info.addr;222bound = fb_info.size == 2 ? bound >> 1 : bound >> 2;223wxUint8 r, g, b, a;224wxUint32 cur_width, cur_height, cur_tail;225wxUint32 tex_adr = voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu];226if ((voodoo.tmem_ptr[tmu] < TEXMEM_2MB_EDGE) && (voodoo.tmem_ptr[tmu]+tex_size*width256*height256 > TEXMEM_2MB_EDGE))227{228tex_adr = TEXMEM_2MB_EDGE;229}230for (wxUint32 h = 0; h < height256; h++)231{232for (wxUint32 w = 0; w < width256; w++)233{234cur_width = (256*(w+1) < width) ? 256 : w_tail;235cur_height = (256*(h+1) < height) ? 256 : h_tail;236cur_tail = 256 - cur_width;237wxUint16 * dst = tex;238if (fb_info.size == 2)239{240for (wxUint32 y=0; y < cur_height; y++)241{242for (wxUint32 x=0; x < cur_width; x++)243{244idx = (x+256*w+(y+256*h)*fb_info.width)^1;245if (idx >= bound)246break;247c = src[idx];248*(dst++) = (c >> 1) | ((c&1)<<15);249}250dst += cur_tail;251}252}253else254{255for (wxUint32 y=0; y < cur_height; y++)256{257for (wxUint32 x=0; x < cur_width; x++)258{259idx = (x+256*w+(y+256*h)*fb_info.width);260if (idx >= bound)261break;262c32 = src32[idx];263r = (wxUint8)((c32 >> 24)&0xFF);264r = (wxUint8)((float)r / 255.0f * 31.0f);265g = (wxUint8)((c32 >> 16)&0xFF);266g = (wxUint8)((float)g / 255.0f * 63.0f);267b = (wxUint8)((c32 >> 8)&0xFF);268b = (wxUint8)((float)b / 255.0f * 31.0f);269a = (c32&0xFF) ? 1 : 0;270*(dst++) = (a<<15) | (r << 10) | (g << 5) | b;271}272dst += cur_tail;273}274}275grTexDownloadMipMap (tmu, tex_adr, GR_MIPMAPLEVELMASK_BOTH, &t_info);276grTexSource (tmu, tex_adr, GR_MIPMAPLEVELMASK_BOTH, &t_info);277tex_adr += tex_size;278float ul_x = (float)(fb_info.ul_x + 256*w);279float ul_y = (float)(fb_info.ul_y + 256*h);280float lr_x = (ul_x + (float)(cur_width)) * rdp.scale_x;281float lr_y = (ul_y + (float)(cur_height)) * rdp.scale_y;282ul_x *= rdp.scale_x;283ul_y *= rdp.scale_y;284ul_x += rdp.offset_x;285ul_y += rdp.offset_y;286lr_x += rdp.offset_x;287lr_y += rdp.offset_y;288289float lr_u = (float)(cur_width-1);290float lr_v = (float)(cur_height-1);291// Make the vertices292VERTEX v[4] = {293{ ul_x, ul_y, 1, 1, 0.5f, 0.5f, 0.5f, 0.5f, {0.5f, 0.5f, 0.5f, 0.5f} },294{ lr_x, ul_y, 1, 1, lr_u, 0.5f, lr_u, 0.5f, {lr_u, 0.5f, lr_u, 0.5f} },295{ ul_x, lr_y, 1, 1, 0.5f, lr_v, 0.5f, lr_v, {0.5f, lr_v, 0.5f, lr_v} },296{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }297};298grDrawTriangle (&v[0], &v[2], &v[1]);299grDrawTriangle (&v[2], &v[3], &v[1]);300}301}302}303304bool DrawFrameBufferToScreen(FB_TO_SCREEN_INFO & fb_info)305{306if (fb_info.width < 200 || fb_info.size < 2)307return false;308wxUint32 width = fb_info.lr_x - fb_info.ul_x + 1;309wxUint32 height = fb_info.lr_y - fb_info.ul_y + 1;310wxUint32 max_size = min(voodoo.max_tex_size, 512);311if (width > (wxUint32)max_size || height > (wxUint32)max_size)312{313DrawFrameBufferToScreen256(fb_info);314return true;315}316FRDP("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);317GrTexInfo t_info;318wxUint8 * image = gfx.RDRAM+fb_info.addr;319wxUint32 texwidth;320float scale;321if (width <= 256)322{323texwidth = 256;324scale = 1.0f;325t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256;326}327else328{329texwidth = 512;330scale = 0.5f;331t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_512;332}333334if (height <= (texwidth>>1))335{336t_info.aspectRatioLog2 = GR_ASPECT_LOG2_2x1;337}338else339{340t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;341}342343if (fb_info.size == 2)344{345wxUint16 * tex = (wxUint16*)texture_buffer;346wxUint16 * dst = tex;347wxUint16 * src = (wxUint16*)image;348src += fb_info.ul_x + fb_info.ul_y * fb_info.width;349wxUint16 c;350wxUint32 idx;351const wxUint32 bound = (BMASK+1-fb_info.addr) >> 1;352bool empty = true;353for (wxUint32 y=0; y < height; y++)354{355for (wxUint32 x=0; x < width; x++)356{357idx = (x+y*fb_info.width)^1;358if (idx >= bound)359break;360c = src[idx];361if (c) empty = false;362*(dst++) = (c >> 1) | ((c&1)<<15);363}364dst += texwidth-width;365}366if (empty)367return false;368t_info.format = GR_TEXFMT_ARGB_1555;369t_info.data = tex;370}371else372{373wxUint32 * tex = (wxUint32*)texture_buffer;374wxUint32 * dst = tex;375wxUint32 * src = (wxUint32*)image;376src += fb_info.ul_x + fb_info.ul_y * fb_info.width;377wxUint32 col;378wxUint32 idx;379const wxUint32 bound = (BMASK+1-fb_info.addr) >> 2;380for (wxUint32 y=0; y < height; y++)381{382for (wxUint32 x=0; x < width; x++)383{384idx = x+y*fb_info.width;385if (idx >= bound)386break;387col = src[idx];388*(dst++) = (col >> 8) | 0xFF000000;389}390dst += texwidth-width;391}392t_info.format = GR_TEXFMT_ARGB_8888;393t_info.data = tex;394}395396int tmu = SetupFBtoScreenCombiner(grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &t_info), fb_info.opaque);397grTexDownloadMipMap (tmu,398voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu],399GR_MIPMAPLEVELMASK_BOTH,400&t_info);401grTexSource (tmu,402voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu],403GR_MIPMAPLEVELMASK_BOTH,404&t_info);405if (settings.hacks&hack_RE2)406{407DrawRE2Video(fb_info, scale);408}409else410{411float ul_x = fb_info.ul_x * rdp.scale_x + rdp.offset_x;412float ul_y = fb_info.ul_y * rdp.scale_y + rdp.offset_y;413float lr_x = fb_info.lr_x * rdp.scale_x + rdp.offset_x;414float lr_y = fb_info.lr_y * rdp.scale_y + rdp.offset_y;415float lr_u = (width-1)*scale;416float lr_v = (height-1)*scale;417// Make the vertices418VERTEX v[4] = {419{ ul_x, ul_y, 1, 1, 0.5f, 0.5f, 0.5f, 0.5f, {0.5f, 0.5f, 0.5f, 0.5f} },420{ lr_x, ul_y, 1, 1, lr_u, 0.5f, lr_u, 0.5f, {lr_u, 0.5f, lr_u, 0.5f} },421{ ul_x, lr_y, 1, 1, 0.5f, lr_v, 0.5f, lr_v, {0.5f, lr_v, 0.5f, lr_v} },422{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }423};424grDrawTriangle (&v[0], &v[2], &v[1]);425grDrawTriangle (&v[2], &v[3], &v[1]);426}427return true;428}429430static void DrawDepthBufferToScreen256(FB_TO_SCREEN_INFO & fb_info)431{432FRDP("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);433wxUint32 width = fb_info.lr_x - fb_info.ul_x + 1;434wxUint32 height = fb_info.lr_y - fb_info.ul_y + 1;435GrTexInfo t_info;436wxUint8 * image = gfx.RDRAM+fb_info.addr;437wxUint32 width256 = ((width-1) >> 8) + 1;438wxUint32 height256 = ((height-1) >> 8) + 1;439t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256;440t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;441t_info.format = GR_TEXFMT_ALPHA_INTENSITY_88;442wxUint16 * tex = (wxUint16*)texture_buffer;443t_info.data = tex;444wxUint32 tex_size = grTexTextureMemRequired (GR_MIPMAPLEVELMASK_BOTH, &t_info);445int tmu = SetupFBtoScreenCombiner(tex_size*width256*height256, fb_info.opaque);446grConstantColorValue (rdp.fog_color);447grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,448GR_COMBINE_FACTOR_ONE,449GR_COMBINE_LOCAL_NONE,450GR_COMBINE_OTHER_CONSTANT,451FXFALSE);452wxUint16 * src = (wxUint16*)image;453src += fb_info.ul_x + fb_info.ul_y * fb_info.width;454wxUint32 w_tail = width%256;455wxUint32 h_tail = height%256;456wxUint32 cur_width, cur_height, cur_tail;457wxUint32 tex_adr = voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu];458if ((voodoo.tmem_ptr[tmu] < TEXMEM_2MB_EDGE) && (voodoo.tmem_ptr[tmu]+tex_size*width256*height256 > TEXMEM_2MB_EDGE))459{460tex_adr = TEXMEM_2MB_EDGE;461}462for (wxUint32 h = 0; h < height256; h++)463{464for (wxUint32 w = 0; w < width256; w++)465{466cur_width = (256*(w+1) < width) ? 256 : w_tail;467cur_height = (256*(h+1) < height) ? 256 : h_tail;468cur_tail = 256 - cur_width;469wxUint16 * dst = tex;470for (wxUint32 y=0; y < cur_height; y++)471{472for (wxUint32 x=0; x < cur_width; x++)473{474*(dst++) = rdp.pal_8[src[(x+256*w+(y+256*h)*fb_info.width)^1]>>8];475}476dst += cur_tail;477}478grTexDownloadMipMap (tmu, tex_adr, GR_MIPMAPLEVELMASK_BOTH, &t_info);479grTexSource (tmu, tex_adr, GR_MIPMAPLEVELMASK_BOTH, &t_info);480tex_adr += tex_size;481float ul_x = (float)(fb_info.ul_x + 256*w);482float ul_y = (float)(fb_info.ul_y + 256*h);483float lr_x = (ul_x + (float)(cur_width)) * rdp.scale_x + rdp.offset_x;484float lr_y = (ul_y + (float)(cur_height)) * rdp.scale_y + rdp.offset_y;485ul_x = ul_x * rdp.scale_x + rdp.offset_x;486ul_y = ul_y * rdp.scale_y + rdp.offset_y;487float lr_u = (float)(cur_width-1);488float lr_v = (float)(cur_height-1);489// Make the vertices490VERTEX v[4] = {491{ ul_x, ul_y, 1, 1, 0.5f, 0.5f, 0.5f, 0.5f, {0.5f, 0.5f, 0.5f, 0.5f} },492{ lr_x, ul_y, 1, 1, lr_u, 0.5f, lr_u, 0.5f, {lr_u, 0.5f, lr_u, 0.5f} },493{ ul_x, lr_y, 1, 1, 0.5f, lr_v, 0.5f, lr_v, {0.5f, lr_v, 0.5f, lr_v} },494{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }495};496grDrawTriangle (&v[0], &v[2], &v[1]);497grDrawTriangle (&v[2], &v[3], &v[1]);498}499}500}501502static void DrawHiresDepthBufferToScreen(FB_TO_SCREEN_INFO & fb_info)503{504FRDP("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);505GrTexInfo t_info;506float scale = 0.25f;507GrLOD_t LOD = GR_LOD_LOG2_1024;508if (settings.scr_res_x > 1024)509{510scale = 0.125f;511LOD = GR_LOD_LOG2_2048;512}513t_info.format = GR_TEXFMT_ALPHA_INTENSITY_88;514t_info.smallLodLog2 = t_info.largeLodLog2 = LOD;515t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;516grConstantColorValue (rdp.fog_color);517grColorCombine (GR_COMBINE_FUNCTION_LOCAL,518GR_COMBINE_FACTOR_NONE,519GR_COMBINE_LOCAL_CONSTANT,520GR_COMBINE_OTHER_NONE,521FXFALSE);522grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,523GR_COMBINE_FACTOR_ONE,524GR_COMBINE_LOCAL_NONE,525GR_COMBINE_OTHER_TEXTURE,526FXFALSE);527grAlphaBlendFunction( GR_BLEND_SRC_ALPHA,528GR_BLEND_ONE_MINUS_SRC_ALPHA,529GR_BLEND_ONE,530GR_BLEND_ZERO);531grDepthBufferFunction (GR_CMP_ALWAYS);532grDepthMask (FXFALSE);533grCullMode (GR_CULL_DISABLE);534grTexCombine( GR_TMU1,535GR_COMBINE_FUNCTION_NONE,536GR_COMBINE_FACTOR_NONE,537GR_COMBINE_FUNCTION_NONE,538GR_COMBINE_FACTOR_NONE,539FXFALSE,540FXFALSE );541grTexCombine( GR_TMU0,542GR_COMBINE_FUNCTION_LOCAL,543GR_COMBINE_FACTOR_NONE,544GR_COMBINE_FUNCTION_LOCAL,545GR_COMBINE_FACTOR_NONE,546FXFALSE,547FXFALSE);548// grAuxBufferExt( GR_BUFFER_AUXBUFFER );549grTexSource( rdp.texbufs[0].tmu, rdp.texbufs[0].begin, GR_MIPMAPLEVELMASK_BOTH, &(t_info) );550float ul_x = (float)rdp.scissor.ul_x;551float ul_y = (float)rdp.scissor.ul_y;552float lr_x = (float)rdp.scissor.lr_x;553float lr_y = (float)rdp.scissor.lr_y;554float ul_u = (float)rdp.scissor.ul_x * scale;555float ul_v = (float)rdp.scissor.ul_y * scale;556float lr_u = (float)rdp.scissor.lr_x * scale;557float lr_v = (float)rdp.scissor.lr_y * scale;558// Make the vertices559VERTEX v[4] = {560{ ul_x, ul_y, 1, 1, ul_u, ul_v, ul_u, ul_v, {ul_u, ul_v, ul_u, ul_v} },561{ lr_x, ul_y, 1, 1, lr_u, ul_v, lr_u, ul_v, {lr_u, ul_v, lr_u, ul_v} },562{ ul_x, lr_y, 1, 1, ul_u, lr_v, ul_u, lr_v, {ul_u, lr_v, ul_u, lr_v} },563{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }564};565grDrawTriangle (&v[0], &v[2], &v[1]);566grDrawTriangle (&v[2], &v[3], &v[1]);567// grAuxBufferExt( GR_BUFFER_TEXTUREAUXBUFFER_EXT );568rdp.update |= UPDATE_COMBINE | UPDATE_ZBUF_ENABLED | UPDATE_CULL_MODE;569}570571void DrawDepthBufferToScreen(FB_TO_SCREEN_INFO & fb_info)572{573wxUint32 width = fb_info.lr_x - fb_info.ul_x + 1;574wxUint32 height = fb_info.lr_y - fb_info.ul_y + 1;575if (width > (wxUint32)voodoo.max_tex_size || height > (wxUint32)voodoo.max_tex_size || width > 512)576{577DrawDepthBufferToScreen256(fb_info);578return;579}580if (fb_hwfbe_enabled && !evoodoo)581{582DrawHiresDepthBufferToScreen(fb_info);583return;584}585FRDP("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);586GrTexInfo t_info;587wxUint8 * image = gfx.RDRAM+fb_info.addr;588wxUint32 texwidth;589float scale;590if (width <= 256)591{592texwidth = 256;593scale = 1.0f;594t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_256;595}596else597{598texwidth = 512;599scale = 0.5f;600t_info.smallLodLog2 = t_info.largeLodLog2 = GR_LOD_LOG2_512;601}602603if (height <= (texwidth>>1))604{605t_info.aspectRatioLog2 = GR_ASPECT_LOG2_2x1;606}607else608{609t_info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;610}611612wxUint16 * tex = (wxUint16*)texture_buffer;613wxUint16 * dst = tex;614wxUint16 * src = (wxUint16*)image;615src += fb_info.ul_x + fb_info.ul_y * fb_info.width;616for (wxUint32 y=0; y < height; y++)617{618for (wxUint32 x=0; x < width; x++)619{620*(dst++) = rdp.pal_8[src[(x+y*fb_info.width)^1]>>8];621}622dst += texwidth-width;623}624t_info.format = GR_TEXFMT_ALPHA_INTENSITY_88;625t_info.data = tex;626627int tmu = SetupFBtoScreenCombiner(grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &t_info), fb_info.opaque);628grConstantColorValue (rdp.fog_color);629grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,630GR_COMBINE_FACTOR_ONE,631GR_COMBINE_LOCAL_NONE,632GR_COMBINE_OTHER_CONSTANT,633FXFALSE);634grTexDownloadMipMap (tmu,635voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu],636GR_MIPMAPLEVELMASK_BOTH,637&t_info);638grTexSource (tmu,639voodoo.tex_min_addr[tmu]+voodoo.tmem_ptr[tmu],640GR_MIPMAPLEVELMASK_BOTH,641&t_info);642float ul_x = fb_info.ul_x * rdp.scale_x + rdp.offset_x;643float ul_y = fb_info.ul_y * rdp.scale_y + rdp.offset_y;644float lr_x = fb_info.lr_x * rdp.scale_x + rdp.offset_x;645float lr_y = fb_info.lr_y * rdp.scale_y + rdp.offset_y;646float lr_u = (width-1)*scale;647float lr_v = (height-1)*scale;648float zero = scale*0.5f;649// Make the vertices650VERTEX v[4] = {651{ ul_x, ul_y, 1, 1, zero, zero, zero, zero, {zero, zero, zero, zero} },652{ lr_x, ul_y, 1, 1, lr_u, zero, lr_u, zero, {lr_u, zero, lr_u, zero} },653{ ul_x, lr_y, 1, 1, zero, lr_v, zero, lr_v, {zero, lr_v, zero, lr_v} },654{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v, {lr_u, lr_v, lr_u, lr_v} }655};656grDrawTriangle (&v[0], &v[2], &v[1]);657grDrawTriangle (&v[2], &v[3], &v[1]);658}659660661