Replace Tmem_nasm.asm with C++ code. Patch by pyro.
[Glide64.git] / TexBuffer.cpp
blob2d8cb94aa9ec95feb560dd1d76a381110df519d1
1 /*
2 * Glide64 - Glide video plugin for Nintendo 64 emulators.
3 * Copyright (c) 2002 Dave2001
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 //****************************************************************
22 // Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
23 // Project started on December 29th, 2001
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.
29 // Official Glide64 development channel: #Glide64 on EFnet
31 //****************************************************************
33 // Dec 2003 created by Gonetz
35 //****************************************************************
37 #include "Gfx1.3.h"
38 #include "TexBuffer.h"
40 #ifndef _WIN32
41 #include <string.h>
42 #endif // _WIN32
44 #define max(a,b) ((a) > (b) ? (a) : (b))
46 static HIRES_COLOR_IMAGE * AllocateTextureBuffer(COLOR_IMAGE & cimage)
48 HIRES_COLOR_IMAGE texbuf;
49 texbuf.addr = cimage.addr;
50 texbuf.end_addr = cimage.addr + cimage.width*cimage.height*cimage.size;
51 texbuf.width = cimage.width;
52 texbuf.height = cimage.height;
53 texbuf.format = (WORD)cimage.format;
54 texbuf.scr_width = min(cimage.width * rdp.scale_x, settings.scr_res_x);
55 float height = min(rdp.vi_height,cimage.height);
56 if (cimage.status == ci_copy_self || (cimage.status == ci_copy && cimage.width == rdp.frame_buffers[rdp.main_ci_index].width))
57 height = rdp.vi_height;
58 texbuf.scr_height = height * rdp.scale_y;
60 WORD max_size = max((WORD)texbuf.scr_width, (WORD)texbuf.scr_height);
61 if (max_size > max_tex_size) //texture size is too large
62 return 0;
63 DWORD tex_size;
64 //calculate LOD
65 switch ((max_size-1) >> 6)
67 case 0:
68 // ZIGGY : fixed (was GR_LOD_LOG2_128)
69 texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_64;
70 tex_size = 64;
71 break;
72 case 1:
73 texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_128;
74 tex_size = 128;
75 break;
76 case 2:
77 case 3:
78 texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_256;
79 tex_size = 256;
80 break;
81 case 4:
82 case 5:
83 case 6:
84 case 7:
85 texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_512;
86 tex_size = 512;
87 break;
88 case 8:
89 case 9:
90 case 10:
91 case 11:
92 case 12:
93 case 13:
94 case 14:
95 case 15:
96 texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_1024;
97 tex_size = 1024;
98 break;
99 default:
100 texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_2048;
101 tex_size = 2048;
103 //calculate aspect
104 if (texbuf.scr_width >= texbuf.scr_height)
106 if ((texbuf.scr_width/texbuf.scr_height) >= 2)
108 texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_2x1;
109 texbuf.tex_width = tex_size;
110 texbuf.tex_height = tex_size >> 1;
112 else
114 texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
115 texbuf.tex_width = texbuf.tex_height = tex_size;
118 else
120 if ((texbuf.scr_height/texbuf.scr_width) >= 2)
122 texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_1x2;
123 texbuf.tex_width = tex_size >> 1;
124 texbuf.tex_height = tex_size;
126 else
128 texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
129 texbuf.tex_width = texbuf.tex_height = tex_size;
132 if ((cimage.format != 0))// && (cimage.width <= 64))
133 texbuf.info.format = GR_TEXFMT_ALPHA_INTENSITY_88;
134 else
135 texbuf.info.format = GR_TEXFMT_RGB_565;
137 float lr_u = 256.0f * texbuf.scr_width / (float)tex_size;// + 1.0f;
138 float lr_v = 256.0f * texbuf.scr_height / (float)tex_size;// + 1.0f;
139 texbuf.tile = 0;
140 texbuf.tile_uls = 0;
141 texbuf.tile_ult = 0;
142 texbuf.u_shift = 0;
143 texbuf.v_shift = 0;
144 texbuf.drawn = FALSE;
145 texbuf.clear = FALSE;
146 texbuf.info.data = NULL;
147 texbuf.u_scale = lr_u / (float)(texbuf.width);
148 texbuf.v_scale = lr_v / (float)(texbuf.height);
150 FRDP("\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);
152 DWORD required = grTexCalcMemRequired(texbuf.info.smallLodLog2, texbuf.info.largeLodLog2,
153 texbuf.info.aspectRatioLog2, texbuf.info.format);
154 //find free space
155 for (int i = 0; i < num_tmu; i++)
157 DWORD available = 0;
158 DWORD top = 0;
159 if (rdp.texbufs[i].count)
161 HIRES_COLOR_IMAGE & t = rdp.texbufs[i].images[rdp.texbufs[i].count - 1];
162 if (rdp.read_whole_frame)
164 if ((cimage.status == ci_aux) && (rdp.cur_tex_buf == i))
166 top = /*rdp.texbufs[i].begin + */t.tex_addr + t.tex_width * (int)(t.scr_height+1) * 2;
167 if (rdp.texbufs[i].end - top < required)
168 return 0;
170 else
171 top = rdp.texbufs[i].end;
173 else
174 top = /*rdp.texbufs[i].begin + */t.tex_addr + t.tex_width * t.tex_height * 2;
175 available = rdp.texbufs[i].end - top;
177 else
179 available = rdp.texbufs[i].end - rdp.texbufs[i].begin;
180 top = rdp.texbufs[i].begin;
182 //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);
183 if (available >= required)
185 rdp.texbufs[i].count++;
186 rdp.texbufs[i].clear_allowed = FALSE;
187 texbuf.tex_addr = top;
188 rdp.cur_tex_buf = i;
189 // ZIGGY strange fix
190 texbuf.tmu = rdp.texbufs[i].tmu;
191 rdp.texbufs[i].images[rdp.texbufs[i].count - 1] = texbuf;
192 return &(rdp.texbufs[i].images[rdp.texbufs[i].count - 1]);
195 //not found. keep recently accessed bank, clear second one
196 if (!rdp.texbufs[rdp.cur_tex_buf^1].clear_allowed) { //can't clear => can't allocate
197 printf("Can't allocate texture buffer\n");
198 return 0;
200 rdp.cur_tex_buf ^= 1;
201 rdp.texbufs[rdp.cur_tex_buf].count = 1;
202 rdp.texbufs[rdp.cur_tex_buf].clear_allowed = FALSE;
203 // ZIGGY strange fix
204 texbuf.tmu = rdp.texbufs[rdp.cur_tex_buf].tmu;
205 texbuf.tex_addr = rdp.texbufs[rdp.cur_tex_buf].begin;
206 rdp.texbufs[rdp.cur_tex_buf].images[0] = texbuf;
207 return &(rdp.texbufs[rdp.cur_tex_buf].images[0]);
210 BOOL OpenTextureBuffer(COLOR_IMAGE & cimage)
212 FRDP("OpenTextureBuffer. cur_tex_buf: %d, addr: %08lx, width: %d, height: %d", rdp.cur_tex_buf, cimage.addr, cimage.width, cimage.height);
213 if (!fullscreen) return FALSE;
215 BOOL found = FALSE, search = TRUE;
216 HIRES_COLOR_IMAGE *texbuf = 0;
217 DWORD addr = cimage.addr;
218 DWORD end_addr = addr + cimage.width*cimage.height*cimage.size;
219 if (rdp.motionblur)
221 if (cimage.format != 0)
222 return FALSE;
223 search = FALSE;
225 if (rdp.read_whole_frame)
227 if (settings.PM) //motion blur effects in Paper Mario
229 rdp.cur_tex_buf = rdp.acc_tex_buf;
230 FRDP("read_whole_frame. last allocated bank: %d\n", rdp.acc_tex_buf);
232 else
234 if (!rdp.texbufs[0].clear_allowed || !rdp.texbufs[1].clear_allowed)
236 if (cimage.status == ci_main)
238 texbuf = &(rdp.texbufs[rdp.cur_tex_buf].images[0]);
239 found = TRUE;
241 else
243 for (int t = 0; (t < rdp.texbufs[rdp.cur_tex_buf].count) && !found; t++)
245 texbuf = &(rdp.texbufs[rdp.cur_tex_buf].images[t]);
246 if (addr == texbuf->addr && cimage.width == texbuf->width)
248 texbuf->drawn = FALSE;
249 found = TRUE;
254 search = FALSE;
257 if (search)
259 for (int i = 0; (i < num_tmu) && !found; i++)
261 for (int j = 0; (j < rdp.texbufs[i].count) && !found; j++)
263 texbuf = &(rdp.texbufs[i].images[j]);
264 if (addr == texbuf->addr && cimage.width == texbuf->width)
266 //texbuf->height = cimage.height;
267 //texbuf->end_addr = end_addr;
268 texbuf->drawn = FALSE;
269 texbuf->format = (WORD)cimage.format;
270 if ((cimage.format != 0))
271 texbuf->info.format = GR_TEXFMT_ALPHA_INTENSITY_88;
272 else
273 texbuf->info.format = GR_TEXFMT_RGB_565;
274 found = TRUE;
275 rdp.cur_tex_buf = i;
276 rdp.texbufs[i].clear_allowed = FALSE;
278 else //check intersection
280 if (!((end_addr <= texbuf->addr) || (addr >= texbuf->end_addr))) //intersected, remove
282 grTextureBufferExt( texbuf->tmu, texbuf->tex_addr, texbuf->info.smallLodLog2, texbuf->info.largeLodLog2,
283 texbuf->info.aspectRatioLog2, texbuf->info.format, GR_MIPMAPLEVELMASK_BOTH );
284 grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );
285 grDepthMask (FXFALSE);
286 grBufferClear (0, 0, 0xFFFF);
287 grDepthMask (FXTRUE);
288 grRenderBuffer( GR_BUFFER_BACKBUFFER );
289 rdp.texbufs[i].count--;
290 if (j < rdp.texbufs[i].count)
291 memcpy(&(rdp.texbufs[i].images[j]), &(rdp.texbufs[i].images[j+1]), sizeof(HIRES_COLOR_IMAGE)*(rdp.texbufs[i].count-j));
298 if (!found)
300 RDP (" not found");
301 texbuf = AllocateTextureBuffer(cimage);
303 else
305 RDP (" found");
308 if (!texbuf)
310 RDP(" KO\n");
311 return FALSE;
314 rdp.acc_tex_buf = rdp.cur_tex_buf;
315 rdp.cur_image = texbuf;
316 grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );
317 //printf("texadr %gMb\n", rdp.cur_image->tex_addr/1024.0f/1024);
318 grTextureBufferExt( rdp.cur_image->tmu, rdp.cur_image->tex_addr, rdp.cur_image->info.smallLodLog2, rdp.cur_image->info.largeLodLog2,
319 rdp.cur_image->info.aspectRatioLog2, rdp.cur_image->info.format, GR_MIPMAPLEVELMASK_BOTH );
320 ///*
321 if (rdp.cur_image->clear && settings.fb_hires_buf_clear && cimage.changed)
323 rdp.cur_image->clear = FALSE;
324 grDepthMask (FXFALSE);
325 grBufferClear (0, 0, 0xFFFF);
326 grDepthMask (FXTRUE);
328 //*/
329 // memset(gfx.RDRAM+cimage.addr, 0, cimage.width*cimage.height*cimage.size);
330 FRDP(" 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);
331 return TRUE;
334 static GrTextureFormat_t TexBufSetupCombiner(BOOL force_rgb = FALSE)
336 grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,
337 GR_COMBINE_FACTOR_ONE,
338 GR_COMBINE_LOCAL_NONE,
339 GR_COMBINE_OTHER_TEXTURE,
340 FXFALSE);
341 grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
342 GR_COMBINE_FACTOR_ONE,
343 GR_COMBINE_LOCAL_NONE,
344 GR_COMBINE_OTHER_TEXTURE,
345 FXFALSE);
346 grAlphaBlendFunction (GR_BLEND_ONE, // use alpha compare, but not T0 alpha
347 GR_BLEND_ZERO,
348 GR_BLEND_ONE,
349 GR_BLEND_ZERO);
350 grClipWindow (0, 0, settings.scr_res_x, settings.scr_res_y);
351 grDepthBufferFunction (GR_CMP_ALWAYS);
352 grDepthMask (FXFALSE);
353 grCullMode (GR_CULL_DISABLE);
354 grFogMode (GR_FOG_DISABLE);
355 GrTextureFormat_t buf_format = (rdp.hires_tex) ? rdp.hires_tex->info.format : GR_TEXFMT_RGB_565;
356 GrCombineFunction_t color_source = GR_COMBINE_FUNCTION_LOCAL;
357 if (!force_rgb && rdp.black_ci_index > 0 && rdp.black_ci_index <= rdp.copy_ci_index)
359 color_source = GR_COMBINE_FUNCTION_LOCAL_ALPHA;
360 buf_format = GR_TEXFMT_ALPHA_INTENSITY_88;
362 if (rdp.hires_tex->tmu == GR_TMU0)
364 grTexCombine( GR_TMU1,
365 GR_COMBINE_FUNCTION_NONE,
366 GR_COMBINE_FACTOR_NONE,
367 GR_COMBINE_FUNCTION_NONE,
368 GR_COMBINE_FACTOR_NONE,
369 FXFALSE,
370 FXFALSE );
371 grTexCombine( GR_TMU0,
372 color_source,
373 GR_COMBINE_FACTOR_NONE,
374 GR_COMBINE_FUNCTION_ZERO,
375 GR_COMBINE_FACTOR_NONE,
376 FXFALSE,
377 FXTRUE );
379 else
381 grTexCombine( GR_TMU1,
382 color_source,
383 GR_COMBINE_FACTOR_NONE,
384 GR_COMBINE_FUNCTION_ZERO,
385 GR_COMBINE_FACTOR_NONE,
386 FXFALSE,
387 FXTRUE );
388 grTexCombine( GR_TMU0,
389 GR_COMBINE_FUNCTION_SCALE_OTHER,
390 GR_COMBINE_FACTOR_ONE,
391 GR_COMBINE_FUNCTION_SCALE_OTHER,
392 GR_COMBINE_FACTOR_ONE,
393 FXFALSE,
394 FXFALSE );
396 return buf_format;
399 BOOL CloseTextureBuffer(BOOL draw)
401 if (!fullscreen || !rdp.cur_image)
403 RDP("CloseTextureBuffer KO\n");
404 return FALSE;
406 grRenderBuffer( GR_BUFFER_BACKBUFFER );
407 if (!draw)
409 RDP("CloseTextureBuffer no draw, OK\n");
410 rdp.cur_image = 0;
411 return TRUE;
414 rdp.hires_tex = rdp.cur_image;
415 rdp.cur_image = 0;
416 GrTextureFormat_t buf_format = rdp.hires_tex->info.format;
417 rdp.hires_tex->info.format = TexBufSetupCombiner();
418 float ul_x = 0.0f;
419 float ul_y = 0.0f;
420 float ul_u = 0.0f;
421 float ul_v = 0.0f;
422 float lr_x = (float)rdp.hires_tex->scr_width;
423 float lr_y = (float)rdp.hires_tex->scr_height;
424 float lr_u = rdp.hires_tex->u_scale * (float)(rdp.hires_tex->width);//255.0f - (1024 - settings.res_x)*0.25f;
425 float lr_v = rdp.hires_tex->v_scale * (float)(rdp.hires_tex->height);//255.0f - (1024 - settings.res_y)*0.25f;
426 FRDP("lr_x: %f, lr_y: %f, lr_u: %f, lr_v: %f\n", lr_x, lr_y, lr_u, lr_v);
429 // Make the vertices
430 VERTEX v[4] = {
431 { ul_x, ul_y, 1, 1, ul_u, ul_v, ul_u, ul_v },
432 { lr_x, ul_y, 1, 1, lr_u, ul_v, lr_u, ul_v },
433 { ul_x, lr_y, 1, 1, ul_u, lr_v, ul_u, lr_v },
434 { lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v } };
435 ConvertCoordsConvert (v, 4);
437 grTexSource( rdp.hires_tex->tmu, rdp.hires_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.hires_tex->info) );
438 grDrawTriangle (&v[0], &v[2], &v[1]);
439 grDrawTriangle (&v[2], &v[3], &v[1]);
440 rdp.hires_tex->info.format = buf_format;
441 rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE;
442 if (settings.fog && (rdp.flags & FOG_ENABLED))
444 grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
446 RDP("CloseTextureBuffer draw, OK\n");
447 rdp.hires_tex = 0;
448 return TRUE;
451 BOOL CopyTextureBuffer(COLOR_IMAGE & fb_from, COLOR_IMAGE & fb_to)
453 if (!fullscreen)
454 return FALSE;
455 RDP("CopyTextureBuffer. ");
456 if (rdp.cur_image)
458 if (rdp.cur_image->addr == fb_to.addr)
459 return CloseTextureBuffer(TRUE);
460 rdp.hires_tex = rdp.cur_image;
462 else if (!FindTextureBuffer(fb_from.addr, (WORD)fb_from.width))
464 RDP("Can't find 'from' buffer.\n");
465 return FALSE;
467 if (!OpenTextureBuffer(fb_to))
469 RDP("Can't open new buffer.\n");
470 return CloseTextureBuffer(TRUE);
472 GrTextureFormat_t buf_format = rdp.hires_tex->info.format;
473 rdp.hires_tex->info.format = GR_TEXFMT_RGB_565;
474 TexBufSetupCombiner(TRUE);
475 float ul_x = 0.0f;
476 float ul_y = 0.0f;
477 float lr_x = (float)rdp.hires_tex->scr_width;
478 float lr_y = (float)rdp.hires_tex->scr_height;
479 float lr_u = rdp.hires_tex->u_scale * (float)(rdp.hires_tex->width);//255.0f - (1024 - settings.res_x)*0.25f;
480 float lr_v = rdp.hires_tex->v_scale * (float)(rdp.hires_tex->height);//255.0f - (1024 - settings.res_y)*0.25f;
481 FRDP("lr_x: %f, lr_y: %f\n", lr_x, lr_y);
484 // Make the vertices
485 VERTEX v[4] = {
486 { ul_x, ul_y, 1, 1, 0, 0, 0, 0 },
487 { lr_x, ul_y, 1, 1, lr_u, 0, lr_u, 0},
488 { ul_x, lr_y, 1, 1, 0, lr_v, 0, lr_v},
489 { lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v} };
490 ConvertCoordsConvert (v, 4);
492 grTexSource( rdp.hires_tex->tmu, rdp.hires_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.hires_tex->info) );
493 grDrawTriangle (&v[0], &v[2], &v[1]);
494 grDrawTriangle (&v[2], &v[3], &v[1]);
495 grRenderBuffer( GR_BUFFER_BACKBUFFER );
496 grDrawTriangle (&v[0], &v[2], &v[1]);
497 grDrawTriangle (&v[2], &v[3], &v[1]);
498 rdp.hires_tex->info.format = buf_format;
500 rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE;
501 if (settings.fog && (rdp.flags & FOG_ENABLED))
502 grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
503 RDP("CopyTextureBuffer draw, OK\n");
504 rdp.hires_tex = 0;
505 rdp.cur_image = 0;
506 return TRUE;
509 BOOL SwapTextureBuffer()
511 if (!fullscreen || !rdp.hires_tex)
512 return FALSE;
513 RDP("SwapTextureBuffer.");
514 HIRES_COLOR_IMAGE * texbuf = AllocateTextureBuffer(rdp.frame_buffers[rdp.main_ci_index]);
515 if (!texbuf)
517 RDP(" failed!\n");
518 return FALSE;
520 TexBufSetupCombiner();
522 float ul_x = 0.0f;
523 float ul_y = 0.0f;
524 float lr_x = (float)rdp.hires_tex->scr_width;
525 float lr_y = (float)rdp.hires_tex->scr_height;
526 float lr_u = rdp.hires_tex->u_scale * (float)(rdp.hires_tex->width);//255.0f - (1024 - settings.res_x)*0.25f;
527 float lr_v = rdp.hires_tex->v_scale * (float)(rdp.hires_tex->height);//255.0f - (1024 - settings.res_y)*0.25f;
529 // Make the vertices
530 VERTEX v[4] = {
531 { ul_x, ul_y, 1, 1, 0, 0, 0, 0 },
532 { lr_x, ul_y, 1, 1, lr_u, 0, lr_u, 0},
533 { ul_x, lr_y, 1, 1, 0, lr_v, 0, lr_v},
534 { lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v} };
535 int tex = rdp.tex;
536 rdp.tex = 1;
537 ConvertCoordsConvert (v, 4);
538 rdp.tex = tex;
540 grTexSource( rdp.hires_tex->tmu, rdp.hires_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.hires_tex->info) );
541 texbuf->tile_uls = rdp.hires_tex->tile_uls;
542 texbuf->tile_ult = rdp.hires_tex->tile_ult;
543 texbuf->v_shift = rdp.hires_tex->v_shift;
544 rdp.cur_image = texbuf;
545 grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );
546 grSstOrigin(GR_ORIGIN_UPPER_LEFT);
547 grTextureBufferExt( rdp.cur_image->tmu, rdp.cur_image->tex_addr, rdp.cur_image->info.smallLodLog2, rdp.cur_image->info.largeLodLog2,
548 rdp.cur_image->info.aspectRatioLog2, rdp.cur_image->info.format, GR_MIPMAPLEVELMASK_BOTH );
549 grDrawTriangle (&v[0], &v[2], &v[1]);
550 grDrawTriangle (&v[2], &v[3], &v[1]);
551 rdp.texbufs[rdp.hires_tex->tmu].clear_allowed = TRUE;
552 rdp.texbufs[rdp.hires_tex->tmu].count = 0;
553 rdp.hires_tex = rdp.cur_image;
554 rdp.cur_image = 0;
555 grRenderBuffer( GR_BUFFER_BACKBUFFER );
557 rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE;
558 if (settings.fog && (rdp.flags & FOG_ENABLED))
560 grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
562 RDP("SwapTextureBuffer draw, OK\n");
563 return TRUE;
566 BOOL FindTextureBuffer(DWORD addr, WORD width)
568 if (rdp.skip_drawing)
569 return FALSE;
570 FRDP("FindTextureBuffer. addr: %08lx, width: %d, scale_x: %f\n", addr, width, rdp.scale_x);
571 BOOL found = FALSE;
572 DWORD shift = 0;
573 for (int i = 0; i < num_tmu && !found; i++)
575 BYTE index = rdp.cur_tex_buf^i;
576 for (int j = 0; j < rdp.texbufs[index].count && !found; j++)
578 rdp.hires_tex = &(rdp.texbufs[index].images[j]);
579 if(addr >= rdp.hires_tex->addr && addr < rdp.hires_tex->end_addr)// && rdp.timg.format == 0)
581 if (width == 1 || rdp.hires_tex->width == width)
583 shift = addr - rdp.hires_tex->addr;
584 if (!rdp.motionblur)
585 rdp.cur_tex_buf = index;
586 found = TRUE;
587 // FRDP("FindTextureBuffer, found in TMU%d buffer: %d\n", rdp.hires_tex->tmu, j);
589 else //new texture is loaded into this place, texture buffer is not valid anymore
591 rdp.texbufs[index].count--;
592 if (j < rdp.texbufs[index].count)
593 memcpy(&(rdp.texbufs[index].images[j]), &(rdp.texbufs[index].images[j+1]), sizeof(HIRES_COLOR_IMAGE)*(rdp.texbufs[index].count-j));
598 if (found)
600 rdp.hires_tex->tile_uls = 0;
601 rdp.hires_tex->tile_ult = 0;
602 if (shift > 0)
604 shift >>= 1;
605 rdp.hires_tex->v_shift = shift / rdp.hires_tex->width;
606 rdp.hires_tex->u_shift = shift % rdp.hires_tex->width;
608 else
610 rdp.hires_tex->v_shift = 0;
611 rdp.hires_tex->u_shift = 0;
614 if (rdp.timg.format == 0) //RGB
615 rdp.hires_tex->info.format = GR_TEXFMT_RGB_565;
616 else //IA
617 rdp.hires_tex->info.format = GR_TEXFMT_ALPHA_INTENSITY_88;
619 FRDP("FindTextureBuffer, found, v_shift: %d, format: %d\n", rdp.hires_tex->v_shift, rdp.hires_tex->info.format);
620 return TRUE;
622 rdp.hires_tex = 0;
623 RDP("FindTextureBuffer, not found\n");
624 return FALSE;