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