Path: blob/master/libmupen64plus/mupen64plus-video-glide64/src/TexBuffer.cpp
2 views
/*1* Glide64 - Glide video plugin for Nintendo 64 emulators.2* Copyright (c) 2002 Dave20013*4* This program is free software; you can redistribute it and/or modify5* it under the terms of the GNU General Public License as published by6* the Free Software Foundation; either version 2 of the License, or7* any later version.8*9* This program is distributed in the hope that it will be useful,10* but WITHOUT ANY WARRANTY; without even the implied warranty of11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12* GNU General Public License for more details.13*14* You should have received a copy of the GNU General Public15* Licence along with this program; if not, write to the Free16* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,17* Boston, MA 02110-1301, USA18*/1920//****************************************************************21//22// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)23// Project started on December 29th, 200124//25// To modify Glide64:26// * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.27// * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.28//29// Official Glide64 development channel: #Glide64 on EFnet30//31//****************************************************************32//33// Dec 2003 created by Gonetz34//35//****************************************************************3637#define M64P_PLUGIN_PROTOTYPES 138#include "m64p_types.h"39#include "m64p_plugin.h"40#include "m64p_config.h"41#include "m64p_vidext.h"42#include "rdp.h"43#include "TexBuffer.h"44#include "Gfx1.3.h"454647#ifndef _WIN3248#include <string.h>49#endif // _WIN325051#define max(a,b) ((a) > (b) ? (a) : (b))52#define min(a,b) ((a) < (b) ? (a) : (b))5354static HIRES_COLOR_IMAGE * AllocateTextureBuffer(COLOR_IMAGE & cimage)55{56HIRES_COLOR_IMAGE texbuf;57texbuf.addr = cimage.addr;58texbuf.end_addr = cimage.addr + cimage.width*cimage.height*cimage.size;59texbuf.width = cimage.width;60texbuf.height = cimage.height;61texbuf.format = (WORD)cimage.format;62texbuf.scr_width = min(cimage.width * rdp.scale_x, settings.scr_res_x);63float height = min(rdp.vi_height,cimage.height);64if (cimage.status == ci_copy_self || (cimage.status == ci_copy && cimage.width == rdp.frame_buffers[rdp.main_ci_index].width))65height = rdp.vi_height;66texbuf.scr_height = height * rdp.scale_y;6768WORD max_size = max((WORD)texbuf.scr_width, (WORD)texbuf.scr_height);69if (max_size > max_tex_size) //texture size is too large70return 0;71DWORD tex_size;72//calculate LOD73switch ((max_size-1) >> 6)74{75case 0:76// ZIGGY : fixed (was GR_LOD_LOG2_128)77texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_64;78tex_size = 64;79break;80case 1:81texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_128;82tex_size = 128;83break;84case 2:85case 3:86texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_256;87tex_size = 256;88break;89case 4:90case 5:91case 6:92case 7:93texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_512;94tex_size = 512;95break;96case 8:97case 9:98case 10:99case 11:100case 12:101case 13:102case 14:103case 15:104texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_1024;105tex_size = 1024;106break;107default:108texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_2048;109tex_size = 2048;110}111//calculate aspect112if (texbuf.scr_width >= texbuf.scr_height)113{114if ((texbuf.scr_width/texbuf.scr_height) >= 2)115{116texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_2x1;117texbuf.tex_width = tex_size;118texbuf.tex_height = tex_size >> 1;119}120else121{122texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;123texbuf.tex_width = texbuf.tex_height = tex_size;124}125}126else127{128if ((texbuf.scr_height/texbuf.scr_width) >= 2)129{130texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_1x2;131texbuf.tex_width = tex_size >> 1;132texbuf.tex_height = tex_size;133}134else135{136texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;137texbuf.tex_width = texbuf.tex_height = tex_size;138}139}140if ((cimage.format != 0))// && (cimage.width <= 64))141texbuf.info.format = GR_TEXFMT_ALPHA_INTENSITY_88;142else143texbuf.info.format = GR_TEXFMT_RGB_565;144145float lr_u = 256.0f * texbuf.scr_width / (float)tex_size;// + 1.0f;146float lr_v = 256.0f * texbuf.scr_height / (float)tex_size;// + 1.0f;147texbuf.tile = 0;148texbuf.tile_uls = 0;149texbuf.tile_ult = 0;150texbuf.u_shift = 0;151texbuf.v_shift = 0;152texbuf.drawn = FALSE;153texbuf.clear = FALSE;154texbuf.info.data = NULL;155texbuf.u_scale = lr_u / (float)(texbuf.width);156texbuf.v_scale = lr_v / (float)(texbuf.height);157158FRDP("\nAllocateTextureBuffer. width: %d, height: %d, scr_width: %f, scr_height: %f, vi_width: %f, vi_height:%f, scale_x: %f, scale_y: %f, lr_u: %f, lr_v: %f, u_scale: %f, v_scale: %f\n", texbuf.width, texbuf.height, texbuf.scr_width, texbuf.scr_height, rdp.vi_width, rdp.vi_height, rdp.scale_x, rdp.scale_y, lr_u, lr_v, texbuf.u_scale, texbuf.v_scale);159160DWORD required = grTexCalcMemRequired(texbuf.info.smallLodLog2, texbuf.info.largeLodLog2,161texbuf.info.aspectRatioLog2, texbuf.info.format);162//find free space163for (int i = 0; i < num_tmu; i++)164{165DWORD available = 0;166DWORD top = 0;167if (rdp.texbufs[i].count)168{169HIRES_COLOR_IMAGE & t = rdp.texbufs[i].images[rdp.texbufs[i].count - 1];170if (rdp.read_whole_frame)171{172if ((cimage.status == ci_aux) && (rdp.cur_tex_buf == i))173{174top = /*rdp.texbufs[i].begin + */t.tex_addr + t.tex_width * (int)(t.scr_height+1) * 2;175if (rdp.texbufs[i].end - top < required)176return 0;177}178else179top = rdp.texbufs[i].end;180}181else182top = /*rdp.texbufs[i].begin + */t.tex_addr + t.tex_width * t.tex_height * 2;183available = rdp.texbufs[i].end - top;184}185else186{187available = rdp.texbufs[i].end - rdp.texbufs[i].begin;188top = rdp.texbufs[i].begin;189}190//printf("i %d count %d end %gMb avail %gMb req %gMb\n", i, rdp.texbufs[i].count, rdp.texbufs[i].end/1024.0f/1024, available/1024.0f/1024, required/1024.0f/1024);191if (available >= required)192{193rdp.texbufs[i].count++;194rdp.texbufs[i].clear_allowed = FALSE;195texbuf.tex_addr = top;196rdp.cur_tex_buf = i;197// ZIGGY strange fix198texbuf.tmu = rdp.texbufs[i].tmu;199rdp.texbufs[i].images[rdp.texbufs[i].count - 1] = texbuf;200return &(rdp.texbufs[i].images[rdp.texbufs[i].count - 1]);201}202}203//not found. keep recently accessed bank, clear second one204if (!rdp.texbufs[rdp.cur_tex_buf^1].clear_allowed) { //can't clear => can't allocate205WriteLog(M64MSG_WARNING, "Can't allocate texture buffer\n");206return 0;207}208rdp.cur_tex_buf ^= 1;209rdp.texbufs[rdp.cur_tex_buf].count = 1;210rdp.texbufs[rdp.cur_tex_buf].clear_allowed = FALSE;211// ZIGGY strange fix212texbuf.tmu = rdp.texbufs[rdp.cur_tex_buf].tmu;213texbuf.tex_addr = rdp.texbufs[rdp.cur_tex_buf].begin;214rdp.texbufs[rdp.cur_tex_buf].images[0] = texbuf;215return &(rdp.texbufs[rdp.cur_tex_buf].images[0]);216}217218BOOL OpenTextureBuffer(COLOR_IMAGE & cimage)219{220FRDP("OpenTextureBuffer. cur_tex_buf: %d, addr: %08lx, width: %d, height: %d", rdp.cur_tex_buf, cimage.addr, cimage.width, cimage.height);221if (!fullscreen) return FALSE;222223BOOL found = FALSE, search = TRUE;224HIRES_COLOR_IMAGE *texbuf = 0;225DWORD addr = cimage.addr;226DWORD end_addr = addr + cimage.width*cimage.height*cimage.size;227if (rdp.motionblur)228{229if (cimage.format != 0)230return FALSE;231search = FALSE;232}233if (rdp.read_whole_frame)234{235if (settings.PM) //motion blur effects in Paper Mario236{237rdp.cur_tex_buf = rdp.acc_tex_buf;238FRDP("read_whole_frame. last allocated bank: %d\n", rdp.acc_tex_buf);239}240else241{242if (!rdp.texbufs[0].clear_allowed || !rdp.texbufs[1].clear_allowed)243{244if (cimage.status == ci_main)245{246texbuf = &(rdp.texbufs[rdp.cur_tex_buf].images[0]);247found = TRUE;248}249else250{251for (int t = 0; (t < rdp.texbufs[rdp.cur_tex_buf].count) && !found; t++)252{253texbuf = &(rdp.texbufs[rdp.cur_tex_buf].images[t]);254if (addr == texbuf->addr && cimage.width == texbuf->width)255{256texbuf->drawn = FALSE;257found = TRUE;258}259}260}261}262search = FALSE;263}264}265if (search)266{267for (int i = 0; (i < num_tmu) && !found; i++)268{269for (int j = 0; (j < rdp.texbufs[i].count) && !found; j++)270{271texbuf = &(rdp.texbufs[i].images[j]);272if (addr == texbuf->addr && cimage.width == texbuf->width)273{274//texbuf->height = cimage.height;275//texbuf->end_addr = end_addr;276texbuf->drawn = FALSE;277texbuf->format = (WORD)cimage.format;278if ((cimage.format != 0))279texbuf->info.format = GR_TEXFMT_ALPHA_INTENSITY_88;280else281texbuf->info.format = GR_TEXFMT_RGB_565;282found = TRUE;283rdp.cur_tex_buf = i;284rdp.texbufs[i].clear_allowed = FALSE;285}286else //check intersection287{288if (!((end_addr <= texbuf->addr) || (addr >= texbuf->end_addr))) //intersected, remove289{290grTextureBufferExt( texbuf->tmu, texbuf->tex_addr, texbuf->info.smallLodLog2, texbuf->info.largeLodLog2,291texbuf->info.aspectRatioLog2, texbuf->info.format, GR_MIPMAPLEVELMASK_BOTH );292grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );293grDepthMask (FXFALSE);294grBufferClear (0, 0, 0xFFFF);295grDepthMask (FXTRUE);296grRenderBuffer( GR_BUFFER_BACKBUFFER );297rdp.texbufs[i].count--;298if (j < rdp.texbufs[i].count)299memcpy(&(rdp.texbufs[i].images[j]), &(rdp.texbufs[i].images[j+1]), sizeof(HIRES_COLOR_IMAGE)*(rdp.texbufs[i].count-j));300}301}302}303}304}305306if (!found)307{308RDP (" not found");309texbuf = AllocateTextureBuffer(cimage);310}311else312{313RDP (" found");314}315316if (!texbuf)317{318RDP(" KO\n");319return FALSE;320}321322rdp.acc_tex_buf = rdp.cur_tex_buf;323rdp.cur_image = texbuf;324grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );325//printf("texadr %gMb\n", rdp.cur_image->tex_addr/1024.0f/1024);326grTextureBufferExt( rdp.cur_image->tmu, rdp.cur_image->tex_addr, rdp.cur_image->info.smallLodLog2, rdp.cur_image->info.largeLodLog2,327rdp.cur_image->info.aspectRatioLog2, rdp.cur_image->info.format, GR_MIPMAPLEVELMASK_BOTH );328///*329if (rdp.cur_image->clear && settings.fb_hires_buf_clear && cimage.changed)330{331rdp.cur_image->clear = FALSE;332grDepthMask (FXFALSE);333grBufferClear (0, 0, 0xFFFF);334grDepthMask (FXTRUE);335}336//*/337// memset(gfx.RDRAM+cimage.addr, 0, cimage.width*cimage.height*cimage.size);338FRDP(" texaddr: %08lx, tex_width: %d, tex_height: %d, cur_tex_buf: %d, texformat: %d, motionblur: %d\n", rdp.cur_image->tex_addr, rdp.cur_image->tex_width, rdp.cur_image->tex_height, rdp.cur_tex_buf, rdp.cur_image->info.format, rdp.motionblur);339return TRUE;340}341342static GrTextureFormat_t TexBufSetupCombiner(BOOL force_rgb = FALSE)343{344grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,345GR_COMBINE_FACTOR_ONE,346GR_COMBINE_LOCAL_NONE,347GR_COMBINE_OTHER_TEXTURE,348FXFALSE);349grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,350GR_COMBINE_FACTOR_ONE,351GR_COMBINE_LOCAL_NONE,352GR_COMBINE_OTHER_TEXTURE,353FXFALSE);354grAlphaBlendFunction (GR_BLEND_ONE, // use alpha compare, but not T0 alpha355GR_BLEND_ZERO,356GR_BLEND_ONE,357GR_BLEND_ZERO);358grClipWindow (0, 0, settings.scr_res_x, settings.scr_res_y);359grDepthBufferFunction (GR_CMP_ALWAYS);360grDepthMask (FXFALSE);361grCullMode (GR_CULL_DISABLE);362grFogMode (GR_FOG_DISABLE);363GrTextureFormat_t buf_format = (rdp.hires_tex) ? rdp.hires_tex->info.format : GR_TEXFMT_RGB_565;364GrCombineFunction_t color_source = GR_COMBINE_FUNCTION_LOCAL;365if (!force_rgb && rdp.black_ci_index > 0 && rdp.black_ci_index <= rdp.copy_ci_index)366{367color_source = GR_COMBINE_FUNCTION_LOCAL_ALPHA;368buf_format = GR_TEXFMT_ALPHA_INTENSITY_88;369}370if (rdp.hires_tex->tmu == GR_TMU0)371{372grTexCombine( GR_TMU1,373GR_COMBINE_FUNCTION_NONE,374GR_COMBINE_FACTOR_NONE,375GR_COMBINE_FUNCTION_NONE,376GR_COMBINE_FACTOR_NONE,377FXFALSE,378FXFALSE );379grTexCombine( GR_TMU0,380color_source,381GR_COMBINE_FACTOR_NONE,382GR_COMBINE_FUNCTION_ZERO,383GR_COMBINE_FACTOR_NONE,384FXFALSE,385FXTRUE );386}387else388{389grTexCombine( GR_TMU1,390color_source,391GR_COMBINE_FACTOR_NONE,392GR_COMBINE_FUNCTION_ZERO,393GR_COMBINE_FACTOR_NONE,394FXFALSE,395FXTRUE );396grTexCombine( GR_TMU0,397GR_COMBINE_FUNCTION_SCALE_OTHER,398GR_COMBINE_FACTOR_ONE,399GR_COMBINE_FUNCTION_SCALE_OTHER,400GR_COMBINE_FACTOR_ONE,401FXFALSE,402FXFALSE );403}404return buf_format;405}406407BOOL CloseTextureBuffer(BOOL draw)408{409if (!fullscreen || !rdp.cur_image)410{411RDP("CloseTextureBuffer KO\n");412return FALSE;413}414grRenderBuffer( GR_BUFFER_BACKBUFFER );415if (!draw)416{417RDP("CloseTextureBuffer no draw, OK\n");418rdp.cur_image = 0;419return TRUE;420}421422rdp.hires_tex = rdp.cur_image;423rdp.cur_image = 0;424GrTextureFormat_t buf_format = rdp.hires_tex->info.format;425rdp.hires_tex->info.format = TexBufSetupCombiner();426float ul_x = 0.0f;427float ul_y = 0.0f;428float ul_u = 0.0f;429float ul_v = 0.0f;430float lr_x = (float)rdp.hires_tex->scr_width;431float lr_y = (float)rdp.hires_tex->scr_height;432float lr_u = rdp.hires_tex->u_scale * (float)(rdp.hires_tex->width);//255.0f - (1024 - settings.res_x)*0.25f;433float lr_v = rdp.hires_tex->v_scale * (float)(rdp.hires_tex->height);//255.0f - (1024 - settings.res_y)*0.25f;434FRDP("lr_x: %f, lr_y: %f, lr_u: %f, lr_v: %f\n", lr_x, lr_y, lr_u, lr_v);435436437// Make the vertices438VERTEX v[4] = {439{ ul_x, ul_y, 1, 1, ul_u, ul_v, ul_u, ul_v },440{ lr_x, ul_y, 1, 1, lr_u, ul_v, lr_u, ul_v },441{ ul_x, lr_y, 1, 1, ul_u, lr_v, ul_u, lr_v },442{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v } };443ConvertCoordsConvert (v, 4);444445grTexSource( rdp.hires_tex->tmu, rdp.hires_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.hires_tex->info) );446grDrawTriangle (&v[0], &v[2], &v[1]);447grDrawTriangle (&v[2], &v[3], &v[1]);448rdp.hires_tex->info.format = buf_format;449rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE;450if (settings.fog && (rdp.flags & FOG_ENABLED))451{452grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);453}454RDP("CloseTextureBuffer draw, OK\n");455rdp.hires_tex = 0;456return TRUE;457}458459BOOL CopyTextureBuffer(COLOR_IMAGE & fb_from, COLOR_IMAGE & fb_to)460{461if (!fullscreen)462return FALSE;463RDP("CopyTextureBuffer. ");464if (rdp.cur_image)465{466if (rdp.cur_image->addr == fb_to.addr)467return CloseTextureBuffer(TRUE);468rdp.hires_tex = rdp.cur_image;469}470else if (!FindTextureBuffer(fb_from.addr, (WORD)fb_from.width))471{472RDP("Can't find 'from' buffer.\n");473return FALSE;474}475if (!OpenTextureBuffer(fb_to))476{477RDP("Can't open new buffer.\n");478return CloseTextureBuffer(TRUE);479}480GrTextureFormat_t buf_format = rdp.hires_tex->info.format;481rdp.hires_tex->info.format = GR_TEXFMT_RGB_565;482TexBufSetupCombiner(TRUE);483float ul_x = 0.0f;484float ul_y = 0.0f;485float lr_x = (float)rdp.hires_tex->scr_width;486float lr_y = (float)rdp.hires_tex->scr_height;487float lr_u = rdp.hires_tex->u_scale * (float)(rdp.hires_tex->width);//255.0f - (1024 - settings.res_x)*0.25f;488float lr_v = rdp.hires_tex->v_scale * (float)(rdp.hires_tex->height);//255.0f - (1024 - settings.res_y)*0.25f;489FRDP("lr_x: %f, lr_y: %f\n", lr_x, lr_y);490491492// Make the vertices493VERTEX v[4] = {494{ ul_x, ul_y, 1, 1, 0, 0, 0, 0 },495{ lr_x, ul_y, 1, 1, lr_u, 0, lr_u, 0},496{ ul_x, lr_y, 1, 1, 0, lr_v, 0, lr_v},497{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v} };498ConvertCoordsConvert (v, 4);499500grTexSource( rdp.hires_tex->tmu, rdp.hires_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.hires_tex->info) );501grDrawTriangle (&v[0], &v[2], &v[1]);502grDrawTriangle (&v[2], &v[3], &v[1]);503grRenderBuffer( GR_BUFFER_BACKBUFFER );504grDrawTriangle (&v[0], &v[2], &v[1]);505grDrawTriangle (&v[2], &v[3], &v[1]);506rdp.hires_tex->info.format = buf_format;507508rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE;509if (settings.fog && (rdp.flags & FOG_ENABLED))510grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);511RDP("CopyTextureBuffer draw, OK\n");512rdp.hires_tex = 0;513rdp.cur_image = 0;514return TRUE;515}516517BOOL SwapTextureBuffer()518{519if (!fullscreen || !rdp.hires_tex)520return FALSE;521RDP("SwapTextureBuffer.");522HIRES_COLOR_IMAGE * texbuf = AllocateTextureBuffer(rdp.frame_buffers[rdp.main_ci_index]);523if (!texbuf)524{525RDP(" failed!\n");526return FALSE;527}528TexBufSetupCombiner();529530float ul_x = 0.0f;531float ul_y = 0.0f;532float lr_x = (float)rdp.hires_tex->scr_width;533float lr_y = (float)rdp.hires_tex->scr_height;534float lr_u = rdp.hires_tex->u_scale * (float)(rdp.hires_tex->width);//255.0f - (1024 - settings.res_x)*0.25f;535float lr_v = rdp.hires_tex->v_scale * (float)(rdp.hires_tex->height);//255.0f - (1024 - settings.res_y)*0.25f;536537// Make the vertices538VERTEX v[4] = {539{ ul_x, ul_y, 1, 1, 0, 0, 0, 0 },540{ lr_x, ul_y, 1, 1, lr_u, 0, lr_u, 0},541{ ul_x, lr_y, 1, 1, 0, lr_v, 0, lr_v},542{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v} };543int tex = rdp.tex;544rdp.tex = 1;545ConvertCoordsConvert (v, 4);546rdp.tex = tex;547548grTexSource( rdp.hires_tex->tmu, rdp.hires_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.hires_tex->info) );549texbuf->tile_uls = rdp.hires_tex->tile_uls;550texbuf->tile_ult = rdp.hires_tex->tile_ult;551texbuf->v_shift = rdp.hires_tex->v_shift;552rdp.cur_image = texbuf;553grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );554grSstOrigin(GR_ORIGIN_UPPER_LEFT);555grTextureBufferExt( rdp.cur_image->tmu, rdp.cur_image->tex_addr, rdp.cur_image->info.smallLodLog2, rdp.cur_image->info.largeLodLog2,556rdp.cur_image->info.aspectRatioLog2, rdp.cur_image->info.format, GR_MIPMAPLEVELMASK_BOTH );557grDrawTriangle (&v[0], &v[2], &v[1]);558grDrawTriangle (&v[2], &v[3], &v[1]);559rdp.texbufs[rdp.hires_tex->tmu].clear_allowed = TRUE;560rdp.texbufs[rdp.hires_tex->tmu].count = 0;561rdp.hires_tex = rdp.cur_image;562rdp.cur_image = 0;563grRenderBuffer( GR_BUFFER_BACKBUFFER );564565rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE;566if (settings.fog && (rdp.flags & FOG_ENABLED))567{568grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);569}570RDP("SwapTextureBuffer draw, OK\n");571return TRUE;572}573574BOOL FindTextureBuffer(DWORD addr, WORD width)575{576if (rdp.skip_drawing)577return FALSE;578FRDP("FindTextureBuffer. addr: %08lx, width: %d, scale_x: %f\n", addr, width, rdp.scale_x);579BOOL found = FALSE;580DWORD shift = 0;581for (int i = 0; i < num_tmu && !found; i++)582{583BYTE index = rdp.cur_tex_buf^i;584for (int j = 0; j < rdp.texbufs[index].count && !found; j++)585{586rdp.hires_tex = &(rdp.texbufs[index].images[j]);587if(addr >= rdp.hires_tex->addr && addr < rdp.hires_tex->end_addr)// && rdp.timg.format == 0)588{589if (width == 1 || rdp.hires_tex->width == width)590{591shift = addr - rdp.hires_tex->addr;592if (!rdp.motionblur)593rdp.cur_tex_buf = index;594found = TRUE;595// FRDP("FindTextureBuffer, found in TMU%d buffer: %d\n", rdp.hires_tex->tmu, j);596}597else //new texture is loaded into this place, texture buffer is not valid anymore598{599rdp.texbufs[index].count--;600if (j < rdp.texbufs[index].count)601memcpy(&(rdp.texbufs[index].images[j]), &(rdp.texbufs[index].images[j+1]), sizeof(HIRES_COLOR_IMAGE)*(rdp.texbufs[index].count-j));602}603}604}605}606if (found)607{608rdp.hires_tex->tile_uls = 0;609rdp.hires_tex->tile_ult = 0;610if (shift > 0)611{612shift >>= 1;613rdp.hires_tex->v_shift = shift / rdp.hires_tex->width;614rdp.hires_tex->u_shift = shift % rdp.hires_tex->width;615}616else617{618rdp.hires_tex->v_shift = 0;619rdp.hires_tex->u_shift = 0;620}621/*622if (rdp.timg.format == 0) //RGB623rdp.hires_tex->info.format = GR_TEXFMT_RGB_565;624else //IA625rdp.hires_tex->info.format = GR_TEXFMT_ALPHA_INTENSITY_88;626*/627FRDP("FindTextureBuffer, found, v_shift: %d, format: %d\n", rdp.hires_tex->v_shift, rdp.hires_tex->info.format);628return TRUE;629}630rdp.hires_tex = 0;631RDP("FindTextureBuffer, not found\n");632return FALSE;633}634635636637