Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-video-glide64/src/TexBuffer.cpp
2 views
1
/*
2
* Glide64 - Glide video plugin for Nintendo 64 emulators.
3
* Copyright (c) 2002 Dave2001
4
*
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.
9
*
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.
14
*
15
* You should have received a copy of the GNU General Public
16
* Licence along with this program; if not, write to the Free
17
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18
* Boston, MA 02110-1301, USA
19
*/
20
21
//****************************************************************
22
//
23
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
24
// Project started on December 29th, 2001
25
//
26
// To modify Glide64:
27
// * 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.
28
// * 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
//
30
// Official Glide64 development channel: #Glide64 on EFnet
31
//
32
//****************************************************************
33
//
34
// Dec 2003 created by Gonetz
35
//
36
//****************************************************************
37
38
#define M64P_PLUGIN_PROTOTYPES 1
39
#include "m64p_types.h"
40
#include "m64p_plugin.h"
41
#include "m64p_config.h"
42
#include "m64p_vidext.h"
43
#include "rdp.h"
44
#include "TexBuffer.h"
45
#include "Gfx1.3.h"
46
47
48
#ifndef _WIN32
49
#include <string.h>
50
#endif // _WIN32
51
52
#define max(a,b) ((a) > (b) ? (a) : (b))
53
#define min(a,b) ((a) < (b) ? (a) : (b))
54
55
static HIRES_COLOR_IMAGE * AllocateTextureBuffer(COLOR_IMAGE & cimage)
56
{
57
HIRES_COLOR_IMAGE texbuf;
58
texbuf.addr = cimage.addr;
59
texbuf.end_addr = cimage.addr + cimage.width*cimage.height*cimage.size;
60
texbuf.width = cimage.width;
61
texbuf.height = cimage.height;
62
texbuf.format = (WORD)cimage.format;
63
texbuf.scr_width = min(cimage.width * rdp.scale_x, settings.scr_res_x);
64
float height = min(rdp.vi_height,cimage.height);
65
if (cimage.status == ci_copy_self || (cimage.status == ci_copy && cimage.width == rdp.frame_buffers[rdp.main_ci_index].width))
66
height = rdp.vi_height;
67
texbuf.scr_height = height * rdp.scale_y;
68
69
WORD max_size = max((WORD)texbuf.scr_width, (WORD)texbuf.scr_height);
70
if (max_size > max_tex_size) //texture size is too large
71
return 0;
72
DWORD tex_size;
73
//calculate LOD
74
switch ((max_size-1) >> 6)
75
{
76
case 0:
77
// ZIGGY : fixed (was GR_LOD_LOG2_128)
78
texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_64;
79
tex_size = 64;
80
break;
81
case 1:
82
texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_128;
83
tex_size = 128;
84
break;
85
case 2:
86
case 3:
87
texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_256;
88
tex_size = 256;
89
break;
90
case 4:
91
case 5:
92
case 6:
93
case 7:
94
texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_512;
95
tex_size = 512;
96
break;
97
case 8:
98
case 9:
99
case 10:
100
case 11:
101
case 12:
102
case 13:
103
case 14:
104
case 15:
105
texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_1024;
106
tex_size = 1024;
107
break;
108
default:
109
texbuf.info.smallLodLog2 = texbuf.info.largeLodLog2 = GR_LOD_LOG2_2048;
110
tex_size = 2048;
111
}
112
//calculate aspect
113
if (texbuf.scr_width >= texbuf.scr_height)
114
{
115
if ((texbuf.scr_width/texbuf.scr_height) >= 2)
116
{
117
texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_2x1;
118
texbuf.tex_width = tex_size;
119
texbuf.tex_height = tex_size >> 1;
120
}
121
else
122
{
123
texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
124
texbuf.tex_width = texbuf.tex_height = tex_size;
125
}
126
}
127
else
128
{
129
if ((texbuf.scr_height/texbuf.scr_width) >= 2)
130
{
131
texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_1x2;
132
texbuf.tex_width = tex_size >> 1;
133
texbuf.tex_height = tex_size;
134
}
135
else
136
{
137
texbuf.info.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
138
texbuf.tex_width = texbuf.tex_height = tex_size;
139
}
140
}
141
if ((cimage.format != 0))// && (cimage.width <= 64))
142
texbuf.info.format = GR_TEXFMT_ALPHA_INTENSITY_88;
143
else
144
texbuf.info.format = GR_TEXFMT_RGB_565;
145
146
float lr_u = 256.0f * texbuf.scr_width / (float)tex_size;// + 1.0f;
147
float lr_v = 256.0f * texbuf.scr_height / (float)tex_size;// + 1.0f;
148
texbuf.tile = 0;
149
texbuf.tile_uls = 0;
150
texbuf.tile_ult = 0;
151
texbuf.u_shift = 0;
152
texbuf.v_shift = 0;
153
texbuf.drawn = FALSE;
154
texbuf.clear = FALSE;
155
texbuf.info.data = NULL;
156
texbuf.u_scale = lr_u / (float)(texbuf.width);
157
texbuf.v_scale = lr_v / (float)(texbuf.height);
158
159
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);
160
161
DWORD required = grTexCalcMemRequired(texbuf.info.smallLodLog2, texbuf.info.largeLodLog2,
162
texbuf.info.aspectRatioLog2, texbuf.info.format);
163
//find free space
164
for (int i = 0; i < num_tmu; i++)
165
{
166
DWORD available = 0;
167
DWORD top = 0;
168
if (rdp.texbufs[i].count)
169
{
170
HIRES_COLOR_IMAGE & t = rdp.texbufs[i].images[rdp.texbufs[i].count - 1];
171
if (rdp.read_whole_frame)
172
{
173
if ((cimage.status == ci_aux) && (rdp.cur_tex_buf == i))
174
{
175
top = /*rdp.texbufs[i].begin + */t.tex_addr + t.tex_width * (int)(t.scr_height+1) * 2;
176
if (rdp.texbufs[i].end - top < required)
177
return 0;
178
}
179
else
180
top = rdp.texbufs[i].end;
181
}
182
else
183
top = /*rdp.texbufs[i].begin + */t.tex_addr + t.tex_width * t.tex_height * 2;
184
available = rdp.texbufs[i].end - top;
185
}
186
else
187
{
188
available = rdp.texbufs[i].end - rdp.texbufs[i].begin;
189
top = rdp.texbufs[i].begin;
190
}
191
//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);
192
if (available >= required)
193
{
194
rdp.texbufs[i].count++;
195
rdp.texbufs[i].clear_allowed = FALSE;
196
texbuf.tex_addr = top;
197
rdp.cur_tex_buf = i;
198
// ZIGGY strange fix
199
texbuf.tmu = rdp.texbufs[i].tmu;
200
rdp.texbufs[i].images[rdp.texbufs[i].count - 1] = texbuf;
201
return &(rdp.texbufs[i].images[rdp.texbufs[i].count - 1]);
202
}
203
}
204
//not found. keep recently accessed bank, clear second one
205
if (!rdp.texbufs[rdp.cur_tex_buf^1].clear_allowed) { //can't clear => can't allocate
206
WriteLog(M64MSG_WARNING, "Can't allocate texture buffer\n");
207
return 0;
208
}
209
rdp.cur_tex_buf ^= 1;
210
rdp.texbufs[rdp.cur_tex_buf].count = 1;
211
rdp.texbufs[rdp.cur_tex_buf].clear_allowed = FALSE;
212
// ZIGGY strange fix
213
texbuf.tmu = rdp.texbufs[rdp.cur_tex_buf].tmu;
214
texbuf.tex_addr = rdp.texbufs[rdp.cur_tex_buf].begin;
215
rdp.texbufs[rdp.cur_tex_buf].images[0] = texbuf;
216
return &(rdp.texbufs[rdp.cur_tex_buf].images[0]);
217
}
218
219
BOOL OpenTextureBuffer(COLOR_IMAGE & cimage)
220
{
221
FRDP("OpenTextureBuffer. cur_tex_buf: %d, addr: %08lx, width: %d, height: %d", rdp.cur_tex_buf, cimage.addr, cimage.width, cimage.height);
222
if (!fullscreen) return FALSE;
223
224
BOOL found = FALSE, search = TRUE;
225
HIRES_COLOR_IMAGE *texbuf = 0;
226
DWORD addr = cimage.addr;
227
DWORD end_addr = addr + cimage.width*cimage.height*cimage.size;
228
if (rdp.motionblur)
229
{
230
if (cimage.format != 0)
231
return FALSE;
232
search = FALSE;
233
}
234
if (rdp.read_whole_frame)
235
{
236
if (settings.PM) //motion blur effects in Paper Mario
237
{
238
rdp.cur_tex_buf = rdp.acc_tex_buf;
239
FRDP("read_whole_frame. last allocated bank: %d\n", rdp.acc_tex_buf);
240
}
241
else
242
{
243
if (!rdp.texbufs[0].clear_allowed || !rdp.texbufs[1].clear_allowed)
244
{
245
if (cimage.status == ci_main)
246
{
247
texbuf = &(rdp.texbufs[rdp.cur_tex_buf].images[0]);
248
found = TRUE;
249
}
250
else
251
{
252
for (int t = 0; (t < rdp.texbufs[rdp.cur_tex_buf].count) && !found; t++)
253
{
254
texbuf = &(rdp.texbufs[rdp.cur_tex_buf].images[t]);
255
if (addr == texbuf->addr && cimage.width == texbuf->width)
256
{
257
texbuf->drawn = FALSE;
258
found = TRUE;
259
}
260
}
261
}
262
}
263
search = FALSE;
264
}
265
}
266
if (search)
267
{
268
for (int i = 0; (i < num_tmu) && !found; i++)
269
{
270
for (int j = 0; (j < rdp.texbufs[i].count) && !found; j++)
271
{
272
texbuf = &(rdp.texbufs[i].images[j]);
273
if (addr == texbuf->addr && cimage.width == texbuf->width)
274
{
275
//texbuf->height = cimage.height;
276
//texbuf->end_addr = end_addr;
277
texbuf->drawn = FALSE;
278
texbuf->format = (WORD)cimage.format;
279
if ((cimage.format != 0))
280
texbuf->info.format = GR_TEXFMT_ALPHA_INTENSITY_88;
281
else
282
texbuf->info.format = GR_TEXFMT_RGB_565;
283
found = TRUE;
284
rdp.cur_tex_buf = i;
285
rdp.texbufs[i].clear_allowed = FALSE;
286
}
287
else //check intersection
288
{
289
if (!((end_addr <= texbuf->addr) || (addr >= texbuf->end_addr))) //intersected, remove
290
{
291
grTextureBufferExt( texbuf->tmu, texbuf->tex_addr, texbuf->info.smallLodLog2, texbuf->info.largeLodLog2,
292
texbuf->info.aspectRatioLog2, texbuf->info.format, GR_MIPMAPLEVELMASK_BOTH );
293
grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );
294
grDepthMask (FXFALSE);
295
grBufferClear (0, 0, 0xFFFF);
296
grDepthMask (FXTRUE);
297
grRenderBuffer( GR_BUFFER_BACKBUFFER );
298
rdp.texbufs[i].count--;
299
if (j < rdp.texbufs[i].count)
300
memcpy(&(rdp.texbufs[i].images[j]), &(rdp.texbufs[i].images[j+1]), sizeof(HIRES_COLOR_IMAGE)*(rdp.texbufs[i].count-j));
301
}
302
}
303
}
304
}
305
}
306
307
if (!found)
308
{
309
RDP (" not found");
310
texbuf = AllocateTextureBuffer(cimage);
311
}
312
else
313
{
314
RDP (" found");
315
}
316
317
if (!texbuf)
318
{
319
RDP(" KO\n");
320
return FALSE;
321
}
322
323
rdp.acc_tex_buf = rdp.cur_tex_buf;
324
rdp.cur_image = texbuf;
325
grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );
326
//printf("texadr %gMb\n", rdp.cur_image->tex_addr/1024.0f/1024);
327
grTextureBufferExt( rdp.cur_image->tmu, rdp.cur_image->tex_addr, rdp.cur_image->info.smallLodLog2, rdp.cur_image->info.largeLodLog2,
328
rdp.cur_image->info.aspectRatioLog2, rdp.cur_image->info.format, GR_MIPMAPLEVELMASK_BOTH );
329
///*
330
if (rdp.cur_image->clear && settings.fb_hires_buf_clear && cimage.changed)
331
{
332
rdp.cur_image->clear = FALSE;
333
grDepthMask (FXFALSE);
334
grBufferClear (0, 0, 0xFFFF);
335
grDepthMask (FXTRUE);
336
}
337
//*/
338
// memset(gfx.RDRAM+cimage.addr, 0, cimage.width*cimage.height*cimage.size);
339
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);
340
return TRUE;
341
}
342
343
static GrTextureFormat_t TexBufSetupCombiner(BOOL force_rgb = FALSE)
344
{
345
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,
346
GR_COMBINE_FACTOR_ONE,
347
GR_COMBINE_LOCAL_NONE,
348
GR_COMBINE_OTHER_TEXTURE,
349
FXFALSE);
350
grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
351
GR_COMBINE_FACTOR_ONE,
352
GR_COMBINE_LOCAL_NONE,
353
GR_COMBINE_OTHER_TEXTURE,
354
FXFALSE);
355
grAlphaBlendFunction (GR_BLEND_ONE, // use alpha compare, but not T0 alpha
356
GR_BLEND_ZERO,
357
GR_BLEND_ONE,
358
GR_BLEND_ZERO);
359
grClipWindow (0, 0, settings.scr_res_x, settings.scr_res_y);
360
grDepthBufferFunction (GR_CMP_ALWAYS);
361
grDepthMask (FXFALSE);
362
grCullMode (GR_CULL_DISABLE);
363
grFogMode (GR_FOG_DISABLE);
364
GrTextureFormat_t buf_format = (rdp.hires_tex) ? rdp.hires_tex->info.format : GR_TEXFMT_RGB_565;
365
GrCombineFunction_t color_source = GR_COMBINE_FUNCTION_LOCAL;
366
if (!force_rgb && rdp.black_ci_index > 0 && rdp.black_ci_index <= rdp.copy_ci_index)
367
{
368
color_source = GR_COMBINE_FUNCTION_LOCAL_ALPHA;
369
buf_format = GR_TEXFMT_ALPHA_INTENSITY_88;
370
}
371
if (rdp.hires_tex->tmu == GR_TMU0)
372
{
373
grTexCombine( GR_TMU1,
374
GR_COMBINE_FUNCTION_NONE,
375
GR_COMBINE_FACTOR_NONE,
376
GR_COMBINE_FUNCTION_NONE,
377
GR_COMBINE_FACTOR_NONE,
378
FXFALSE,
379
FXFALSE );
380
grTexCombine( GR_TMU0,
381
color_source,
382
GR_COMBINE_FACTOR_NONE,
383
GR_COMBINE_FUNCTION_ZERO,
384
GR_COMBINE_FACTOR_NONE,
385
FXFALSE,
386
FXTRUE );
387
}
388
else
389
{
390
grTexCombine( GR_TMU1,
391
color_source,
392
GR_COMBINE_FACTOR_NONE,
393
GR_COMBINE_FUNCTION_ZERO,
394
GR_COMBINE_FACTOR_NONE,
395
FXFALSE,
396
FXTRUE );
397
grTexCombine( GR_TMU0,
398
GR_COMBINE_FUNCTION_SCALE_OTHER,
399
GR_COMBINE_FACTOR_ONE,
400
GR_COMBINE_FUNCTION_SCALE_OTHER,
401
GR_COMBINE_FACTOR_ONE,
402
FXFALSE,
403
FXFALSE );
404
}
405
return buf_format;
406
}
407
408
BOOL CloseTextureBuffer(BOOL draw)
409
{
410
if (!fullscreen || !rdp.cur_image)
411
{
412
RDP("CloseTextureBuffer KO\n");
413
return FALSE;
414
}
415
grRenderBuffer( GR_BUFFER_BACKBUFFER );
416
if (!draw)
417
{
418
RDP("CloseTextureBuffer no draw, OK\n");
419
rdp.cur_image = 0;
420
return TRUE;
421
}
422
423
rdp.hires_tex = rdp.cur_image;
424
rdp.cur_image = 0;
425
GrTextureFormat_t buf_format = rdp.hires_tex->info.format;
426
rdp.hires_tex->info.format = TexBufSetupCombiner();
427
float ul_x = 0.0f;
428
float ul_y = 0.0f;
429
float ul_u = 0.0f;
430
float ul_v = 0.0f;
431
float lr_x = (float)rdp.hires_tex->scr_width;
432
float lr_y = (float)rdp.hires_tex->scr_height;
433
float lr_u = rdp.hires_tex->u_scale * (float)(rdp.hires_tex->width);//255.0f - (1024 - settings.res_x)*0.25f;
434
float lr_v = rdp.hires_tex->v_scale * (float)(rdp.hires_tex->height);//255.0f - (1024 - settings.res_y)*0.25f;
435
FRDP("lr_x: %f, lr_y: %f, lr_u: %f, lr_v: %f\n", lr_x, lr_y, lr_u, lr_v);
436
437
438
// Make the vertices
439
VERTEX v[4] = {
440
{ ul_x, ul_y, 1, 1, ul_u, ul_v, ul_u, ul_v },
441
{ lr_x, ul_y, 1, 1, lr_u, ul_v, lr_u, ul_v },
442
{ ul_x, lr_y, 1, 1, ul_u, lr_v, ul_u, lr_v },
443
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v } };
444
ConvertCoordsConvert (v, 4);
445
446
grTexSource( rdp.hires_tex->tmu, rdp.hires_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.hires_tex->info) );
447
grDrawTriangle (&v[0], &v[2], &v[1]);
448
grDrawTriangle (&v[2], &v[3], &v[1]);
449
rdp.hires_tex->info.format = buf_format;
450
rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE;
451
if (settings.fog && (rdp.flags & FOG_ENABLED))
452
{
453
grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
454
}
455
RDP("CloseTextureBuffer draw, OK\n");
456
rdp.hires_tex = 0;
457
return TRUE;
458
}
459
460
BOOL CopyTextureBuffer(COLOR_IMAGE & fb_from, COLOR_IMAGE & fb_to)
461
{
462
if (!fullscreen)
463
return FALSE;
464
RDP("CopyTextureBuffer. ");
465
if (rdp.cur_image)
466
{
467
if (rdp.cur_image->addr == fb_to.addr)
468
return CloseTextureBuffer(TRUE);
469
rdp.hires_tex = rdp.cur_image;
470
}
471
else if (!FindTextureBuffer(fb_from.addr, (WORD)fb_from.width))
472
{
473
RDP("Can't find 'from' buffer.\n");
474
return FALSE;
475
}
476
if (!OpenTextureBuffer(fb_to))
477
{
478
RDP("Can't open new buffer.\n");
479
return CloseTextureBuffer(TRUE);
480
}
481
GrTextureFormat_t buf_format = rdp.hires_tex->info.format;
482
rdp.hires_tex->info.format = GR_TEXFMT_RGB_565;
483
TexBufSetupCombiner(TRUE);
484
float ul_x = 0.0f;
485
float ul_y = 0.0f;
486
float lr_x = (float)rdp.hires_tex->scr_width;
487
float lr_y = (float)rdp.hires_tex->scr_height;
488
float lr_u = rdp.hires_tex->u_scale * (float)(rdp.hires_tex->width);//255.0f - (1024 - settings.res_x)*0.25f;
489
float lr_v = rdp.hires_tex->v_scale * (float)(rdp.hires_tex->height);//255.0f - (1024 - settings.res_y)*0.25f;
490
FRDP("lr_x: %f, lr_y: %f\n", lr_x, lr_y);
491
492
493
// Make the vertices
494
VERTEX v[4] = {
495
{ ul_x, ul_y, 1, 1, 0, 0, 0, 0 },
496
{ lr_x, ul_y, 1, 1, lr_u, 0, lr_u, 0},
497
{ ul_x, lr_y, 1, 1, 0, lr_v, 0, lr_v},
498
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v} };
499
ConvertCoordsConvert (v, 4);
500
501
grTexSource( rdp.hires_tex->tmu, rdp.hires_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.hires_tex->info) );
502
grDrawTriangle (&v[0], &v[2], &v[1]);
503
grDrawTriangle (&v[2], &v[3], &v[1]);
504
grRenderBuffer( GR_BUFFER_BACKBUFFER );
505
grDrawTriangle (&v[0], &v[2], &v[1]);
506
grDrawTriangle (&v[2], &v[3], &v[1]);
507
rdp.hires_tex->info.format = buf_format;
508
509
rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE;
510
if (settings.fog && (rdp.flags & FOG_ENABLED))
511
grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
512
RDP("CopyTextureBuffer draw, OK\n");
513
rdp.hires_tex = 0;
514
rdp.cur_image = 0;
515
return TRUE;
516
}
517
518
BOOL SwapTextureBuffer()
519
{
520
if (!fullscreen || !rdp.hires_tex)
521
return FALSE;
522
RDP("SwapTextureBuffer.");
523
HIRES_COLOR_IMAGE * texbuf = AllocateTextureBuffer(rdp.frame_buffers[rdp.main_ci_index]);
524
if (!texbuf)
525
{
526
RDP(" failed!\n");
527
return FALSE;
528
}
529
TexBufSetupCombiner();
530
531
float ul_x = 0.0f;
532
float ul_y = 0.0f;
533
float lr_x = (float)rdp.hires_tex->scr_width;
534
float lr_y = (float)rdp.hires_tex->scr_height;
535
float lr_u = rdp.hires_tex->u_scale * (float)(rdp.hires_tex->width);//255.0f - (1024 - settings.res_x)*0.25f;
536
float lr_v = rdp.hires_tex->v_scale * (float)(rdp.hires_tex->height);//255.0f - (1024 - settings.res_y)*0.25f;
537
538
// Make the vertices
539
VERTEX v[4] = {
540
{ ul_x, ul_y, 1, 1, 0, 0, 0, 0 },
541
{ lr_x, ul_y, 1, 1, lr_u, 0, lr_u, 0},
542
{ ul_x, lr_y, 1, 1, 0, lr_v, 0, lr_v},
543
{ lr_x, lr_y, 1, 1, lr_u, lr_v, lr_u, lr_v} };
544
int tex = rdp.tex;
545
rdp.tex = 1;
546
ConvertCoordsConvert (v, 4);
547
rdp.tex = tex;
548
549
grTexSource( rdp.hires_tex->tmu, rdp.hires_tex->tex_addr, GR_MIPMAPLEVELMASK_BOTH, &(rdp.hires_tex->info) );
550
texbuf->tile_uls = rdp.hires_tex->tile_uls;
551
texbuf->tile_ult = rdp.hires_tex->tile_ult;
552
texbuf->v_shift = rdp.hires_tex->v_shift;
553
rdp.cur_image = texbuf;
554
grRenderBuffer( GR_BUFFER_TEXTUREBUFFER_EXT );
555
grSstOrigin(GR_ORIGIN_UPPER_LEFT);
556
grTextureBufferExt( rdp.cur_image->tmu, rdp.cur_image->tex_addr, rdp.cur_image->info.smallLodLog2, rdp.cur_image->info.largeLodLog2,
557
rdp.cur_image->info.aspectRatioLog2, rdp.cur_image->info.format, GR_MIPMAPLEVELMASK_BOTH );
558
grDrawTriangle (&v[0], &v[2], &v[1]);
559
grDrawTriangle (&v[2], &v[3], &v[1]);
560
rdp.texbufs[rdp.hires_tex->tmu].clear_allowed = TRUE;
561
rdp.texbufs[rdp.hires_tex->tmu].count = 0;
562
rdp.hires_tex = rdp.cur_image;
563
rdp.cur_image = 0;
564
grRenderBuffer( GR_BUFFER_BACKBUFFER );
565
566
rdp.update |= UPDATE_ZBUF_ENABLED | UPDATE_COMBINE | UPDATE_TEXTURE | UPDATE_ALPHA_COMPARE;
567
if (settings.fog && (rdp.flags & FOG_ENABLED))
568
{
569
grFogMode (GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
570
}
571
RDP("SwapTextureBuffer draw, OK\n");
572
return TRUE;
573
}
574
575
BOOL FindTextureBuffer(DWORD addr, WORD width)
576
{
577
if (rdp.skip_drawing)
578
return FALSE;
579
FRDP("FindTextureBuffer. addr: %08lx, width: %d, scale_x: %f\n", addr, width, rdp.scale_x);
580
BOOL found = FALSE;
581
DWORD shift = 0;
582
for (int i = 0; i < num_tmu && !found; i++)
583
{
584
BYTE index = rdp.cur_tex_buf^i;
585
for (int j = 0; j < rdp.texbufs[index].count && !found; j++)
586
{
587
rdp.hires_tex = &(rdp.texbufs[index].images[j]);
588
if(addr >= rdp.hires_tex->addr && addr < rdp.hires_tex->end_addr)// && rdp.timg.format == 0)
589
{
590
if (width == 1 || rdp.hires_tex->width == width)
591
{
592
shift = addr - rdp.hires_tex->addr;
593
if (!rdp.motionblur)
594
rdp.cur_tex_buf = index;
595
found = TRUE;
596
// FRDP("FindTextureBuffer, found in TMU%d buffer: %d\n", rdp.hires_tex->tmu, j);
597
}
598
else //new texture is loaded into this place, texture buffer is not valid anymore
599
{
600
rdp.texbufs[index].count--;
601
if (j < rdp.texbufs[index].count)
602
memcpy(&(rdp.texbufs[index].images[j]), &(rdp.texbufs[index].images[j+1]), sizeof(HIRES_COLOR_IMAGE)*(rdp.texbufs[index].count-j));
603
}
604
}
605
}
606
}
607
if (found)
608
{
609
rdp.hires_tex->tile_uls = 0;
610
rdp.hires_tex->tile_ult = 0;
611
if (shift > 0)
612
{
613
shift >>= 1;
614
rdp.hires_tex->v_shift = shift / rdp.hires_tex->width;
615
rdp.hires_tex->u_shift = shift % rdp.hires_tex->width;
616
}
617
else
618
{
619
rdp.hires_tex->v_shift = 0;
620
rdp.hires_tex->u_shift = 0;
621
}
622
/*
623
if (rdp.timg.format == 0) //RGB
624
rdp.hires_tex->info.format = GR_TEXFMT_RGB_565;
625
else //IA
626
rdp.hires_tex->info.format = GR_TEXFMT_ALPHA_INTENSITY_88;
627
*/
628
FRDP("FindTextureBuffer, found, v_shift: %d, format: %d\n", rdp.hires_tex->v_shift, rdp.hires_tex->info.format);
629
return TRUE;
630
}
631
rdp.hires_tex = 0;
632
RDP("FindTextureBuffer, not found\n");
633
return FALSE;
634
}
635
636
637