Glide Plugin GLES2 port from mupen64plus-ae, but with special FrameSkip code
[mupen64plus-pandora.git] / source / gles2glide64 / src / Glide64 / Debugger.cpp
CommitLineData
98e75f2d 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#include "Gfx_1.3.h"
41#include "Util.h"
42#include "Debugger.h"
43
44GLIDE64_DEBUGGER _debugger;
45
46#define SX(x) ((x)*rdp.scale_1024)
47#define SY(x) ((x)*rdp.scale_768)
48
49#ifdef COLORED_DEBUGGER
50#define COL_CATEGORY() grConstantColorValue(0xD288F400)
51#define COL_UCC() grConstantColorValue(0xFF000000)
52#define COL_CC() grConstantColorValue(0x88C3F400)
53#define COL_UAC() grConstantColorValue(0xFF808000)
54#define COL_AC() grConstantColorValue(0x3CEE5E00)
55#define COL_TEXT() grConstantColorValue(0xFFFFFF00)
56#define COL_SEL(x) grConstantColorValue((x)?0x00FF00FF:0x800000FF)
57#else
58#define COL_CATEGORY()
59#define COL_UCC()
60#define COL_CC()
61#define COL_UAC()
62#define COL_AC()
63#define COL_TEXT()
64#define COL_SEL(x)
65#endif
66
67#define COL_GRID 0xFFFFFF80
68
69int grid = 0;
70static const char *tri_type[4] = { "TRIANGLE", "TEXRECT", "FILLRECT", "BACKGROUND" };
71
72//Platform-specific stuff
73#ifndef WIN32
74typedef struct dbgPOINT {
75 int x;
76 int y;
77} POINT;
78#endif
79void DbgCursorPos(POINT * pt)
80{
81#ifdef __WINDOWS__
82 GetCursorPos (pt);
83#else //!todo find a way to get cursor position on Unix
84 pt->x = pt->y = 0;
85#endif
86}
87
88//
89// debug_init - initialize the debugger
90//
91
92void debug_init ()
93{
94 _debugger.capture = 0;
95 _debugger.selected = SELECTED_TRI;
96 _debugger.screen = NULL;
97 _debugger.tri_list = NULL;
98 _debugger.tri_last = NULL;
99 _debugger.tri_sel = NULL;
100 _debugger.tmu = 0;
101
102 _debugger.tex_scroll = 0;
103 _debugger.tex_sel = 0;
104
105 _debugger.draw_mode = 0;
106}
107
108//
109// debug_cacheviewer - views the debugger's cache
110//
111
112void debug_cacheviewer ()
113{
114 grCullMode (GR_CULL_DISABLE);
115
116 int i;
117 for (i=0; i<2; i++)
118 {
119 grTexFilterMode (i,
120 (settings.filter_cache)?GR_TEXTUREFILTER_BILINEAR:GR_TEXTUREFILTER_POINT_SAMPLED,
121 (settings.filter_cache)?GR_TEXTUREFILTER_BILINEAR:GR_TEXTUREFILTER_POINT_SAMPLED);
122 grTexClampMode (i,
123 GR_TEXTURECLAMP_CLAMP,
124 GR_TEXTURECLAMP_CLAMP);
125 }
126
127 switch (_debugger.draw_mode)
128 {
129 case 0:
130 grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
131 GR_COMBINE_FACTOR_ONE,
132 GR_COMBINE_LOCAL_NONE,
133 GR_COMBINE_OTHER_TEXTURE,
134 FXFALSE);
135 grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
136 GR_COMBINE_FACTOR_ONE,
137 GR_COMBINE_LOCAL_NONE,
138 GR_COMBINE_OTHER_TEXTURE,
139 FXFALSE);
140 break;
141 case 1:
142 grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
143 GR_COMBINE_FACTOR_ONE,
144 GR_COMBINE_LOCAL_NONE,
145 GR_COMBINE_OTHER_TEXTURE,
146 FXFALSE);
147 grAlphaCombine (GR_COMBINE_FUNCTION_LOCAL,
148 GR_COMBINE_FACTOR_NONE,
149 GR_COMBINE_LOCAL_CONSTANT,
150 GR_COMBINE_OTHER_NONE,
151 FXFALSE);
152 grConstantColorValue (0xFFFFFFFF);
153 break;
154 case 2:
155 grColorCombine (GR_COMBINE_FUNCTION_LOCAL,
156 GR_COMBINE_FACTOR_NONE,
157 GR_COMBINE_LOCAL_CONSTANT,
158 GR_COMBINE_OTHER_NONE,
159 FXFALSE);
160 grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
161 GR_COMBINE_FACTOR_ONE,
162 GR_COMBINE_LOCAL_NONE,
163 GR_COMBINE_OTHER_TEXTURE,
164 FXFALSE);
165 grConstantColorValue (0xFFFFFFFF);
166 }
167
168 if (_debugger.tmu == 1)
169 {
170 grTexCombine (GR_TMU1,
171 GR_COMBINE_FUNCTION_LOCAL,
172 GR_COMBINE_FACTOR_NONE,
173 GR_COMBINE_FUNCTION_LOCAL,
174 GR_COMBINE_FACTOR_NONE,
175 FXFALSE,
176 FXFALSE);
177
178 grTexCombine (GR_TMU0,
179 GR_COMBINE_FUNCTION_SCALE_OTHER,
180 GR_COMBINE_FACTOR_ONE,
181 GR_COMBINE_FUNCTION_SCALE_OTHER,
182 GR_COMBINE_FACTOR_ONE,
183 FXFALSE,
184 FXFALSE);
185 }
186 else
187 {
188 grTexCombine (GR_TMU0,
189 GR_COMBINE_FUNCTION_LOCAL,
190 GR_COMBINE_FACTOR_NONE,
191 GR_COMBINE_FUNCTION_LOCAL,
192 GR_COMBINE_FACTOR_NONE,
193 FXFALSE,
194 FXFALSE);
195 }
196
197 grAlphaBlendFunction (GR_BLEND_SRC_ALPHA,
198 GR_BLEND_ONE_MINUS_SRC_ALPHA,
199 GR_BLEND_ONE,
200 GR_BLEND_ZERO);
201
202 // Draw texture memory
203 for (i=0; i<4; i++)
204 {
205 for (wxUint32 x=0; x<16; x++)
206 {
207 wxUint32 y = i+_debugger.tex_scroll;
208 if (x+y*16 >= (wxUint32)rdp.n_cached[_debugger.tmu]) break;
209 CACHE_LUT * cache = voodoo.tex_UMA?rdp.cache[0]:rdp.cache[_debugger.tmu];
210
211 VERTEX v[4] = {
212 { SX(x*64.0f), SY(512+64.0f*i), 1, 1, 0, 0, 0, 0, {0, 0, 0, 0} },
213 { SX(x*64.0f+64.0f*cache[x+y*16].scale_x), SY(512+64.0f*i), 1, 1, 255*cache[x+y*16].scale_x, 0, 0, 0, {0, 0, 0, 0} },
214 { SX(x*64.0f), SY(512+64.0f*i+64.0f*cache[x+y*16].scale_y), 1, 1, 0, 255*cache[x+y*16].scale_y, 0, 0, {0, 0, 0, 0} },
215 { SX(x*64.0f+64.0f*cache[x+y*16].scale_x), SY(512+64.0f*i+64.0f*cache[x+y*16].scale_y), 1, 1, 255*cache[x+y*16].scale_x, 255*cache[x+y*16].scale_y, 0, 0, {0, 0, 0, 0} }
216 };
217 for
218 (int i=0; i<4; i++)
219 {
220 v[i].u1 = v[i].u0;
221 v[i].v1 = v[i].v0;
222 }
223
224 ConvertCoordsConvert (v, 4);
225
226 grTexSource(_debugger.tmu,
227 voodoo.tex_min_addr[_debugger.tmu] + cache[x+y*16].tmem_addr,
228 GR_MIPMAPLEVELMASK_BOTH,
229 &cache[x+y*16].t_info);
230
231 grDrawTriangle (&v[2], &v[1], &v[0]);
232 grDrawTriangle (&v[2], &v[3], &v[1]);
233 }
234 }
235
236}
237
238//
239// debug_capture - does a frame capture event (for debugging)
240//
241
242void debug_capture ()
243{
244 wxUint32 i,j;
245
246 if (_debugger.tri_list == NULL) goto END;
247 _debugger.tri_sel = _debugger.tri_list;
248 _debugger.selected = SELECTED_TRI;
249
250 // Connect the list
251 _debugger.tri_last->pNext = _debugger.tri_list;
252
253 while (!CheckKeyPressed(G64_VK_INSERT, 0x0001)) //INSERT
254 {
255 // Check for clicks
256 if (CheckKeyPressed(G64_VK_LBUTTON, 0x0001)) //LBUTTON
257 {
258 POINT pt;
259 DbgCursorPos(&pt);
260
261 //int diff = settings.scr_res_y-settings.res_y;
262
263 if (pt.y <= (int)settings.res_y)
264 {
265 int x = pt.x;
266 int y = pt.y;//settings.res_y - (pt.y - diff);
267
268 TRI_INFO *start;
269 TRI_INFO *tri;
270 if (_debugger.tri_sel == NULL) tri = _debugger.tri_list, start = _debugger.tri_list;
271 else tri = _debugger.tri_sel->pNext, start = _debugger.tri_sel;
272
273 // Select a triangle (start from the currently selected one)
274 do {
275 if (tri->v[0].x == tri->v[1].x &&
276 tri->v[0].y == tri->v[1].y)
277 {
278 tri = tri->pNext;
279 continue;
280 }
281
282 for (i=0; i<tri->nv; i++)
283 {
284 j=i+1;
285 if (j==tri->nv) j=0;
286
287 if ((y-tri->v[i].y)*(tri->v[j].x-tri->v[i].x) -
288 (x-tri->v[i].x)*(tri->v[j].y-tri->v[i].y) < 0)
289 break; // It's outside
290 }
291
292 if (i==tri->nv) // all lines passed
293 {
294 _debugger.tri_sel = tri;
295 break;
296 }
297
298 for (i=0; i<tri->nv; i++)
299 {
300 j=i+1;
301 if (j==tri->nv) j=0;
302
303 if ((y-tri->v[i].y)*(tri->v[j].x-tri->v[i].x) -
304 (x-tri->v[i].x)*(tri->v[j].y-tri->v[i].y) > 0)
305 break; // It's outside
306 }
307
308 if (i==tri->nv) // all lines passed
309 {
310 _debugger.tri_sel = tri;
311 break;
312 }
313
314 tri = tri->pNext;
315 } while (tri != start);
316 }
317 else
318 {
319 // on a texture
320 _debugger.tex_sel = (((wxUint32)((pt.y-SY(512))/SY(64))+_debugger.tex_scroll)*16) +
321 (wxUint32)(pt.x/SX(64));
322 }
323 }
324
325 debug_keys ();
326
327 grBufferClear (0, 0, 0xFFFF);
328
329 // Copy the screen capture back to the screen:
330 grLfbWriteRegion(GR_BUFFER_BACKBUFFER,
331 (wxUint32)rdp.offset_x,
332 (wxUint32)rdp.offset_y,
333 GR_LFB_SRC_FMT_565,
334 settings.res_x,
335 settings.res_y,
336 FXFALSE,
337 settings.res_x<<1,
338 _debugger.screen);
339
340 // Do the cacheviewer
341 debug_cacheviewer ();
342
343 // **
344 // 3/16/02: Moved texture viewer out of loop, remade it. Now it's simpler, and
345 // supports TMU1. [Dave2001]
346 // Original by Gugaman
347
348 CACHE_LUT * cache = voodoo.tex_UMA?rdp.cache[0]:rdp.cache[_debugger.tmu];
349 if (_debugger.page == PAGE_TEX_INFO)
350 {
351 grTexSource(_debugger.tmu,
352 voodoo.tex_min_addr[_debugger.tmu] + cache[_debugger.tex_sel].tmem_addr,
353 GR_MIPMAPLEVELMASK_BOTH,
354 &cache[_debugger.tex_sel].t_info);
355
356#ifdef SHOW_FULL_TEXVIEWER
357 float scx = 1.0f;
358 float scy = 1.0f;
359#else
360 float scx = cache[_debugger.tex_sel].scale_x;
361 float scy = cache[_debugger.tex_sel].scale_y;
362#endif
363 VERTEX v[4] = {
364 { SX(704.0f), SY(221.0f), 1, 1, 0, 0, 0, 0, {0, 0, 0, 0} },
365 { SX(704.0f+256.0f*scx), SY(221.0f), 1, 1, 255*scx, 0, 255*scx, 0, {0, 0, 0, 0} },
366 { SX(704.0f), SY(221.0f+256.0f*scy), 1, 1, 0, 255*scy, 0, 255*scy, {0, 0, 0, 0} },
367 { SX(704.0f+256.0f*scx), SY(221.0f+256.0f*scy), 1, 1, 255*scx, 255*scy, 255*scx, 255*scy, {0, 0, 0, 0} }
368 };
369 ConvertCoordsConvert (v, 4);
370 VERTEX *varr[4] = { &v[0], &v[1], &v[2], &v[3] };
371 grDrawVertexArray (GR_TRIANGLE_STRIP, 4, varr);
372 }
373
374 // **
375
376 grTexFilterMode (GR_TMU0,
377 GR_TEXTUREFILTER_BILINEAR,
378 GR_TEXTUREFILTER_BILINEAR);
379
380 grColorCombine (GR_COMBINE_FUNCTION_LOCAL,
381 GR_COMBINE_FACTOR_NONE,
382 GR_COMBINE_LOCAL_CONSTANT,
383 GR_COMBINE_OTHER_NONE,
384 FXFALSE);
385
386 grAlphaCombine (GR_COMBINE_FUNCTION_LOCAL,
387 GR_COMBINE_FACTOR_NONE,
388 GR_COMBINE_LOCAL_CONSTANT,
389 GR_COMBINE_OTHER_NONE,
390 FXFALSE);
391
392 grConstantColorValue (0x0000FFFF);
393
394 VERTEX *v[8];
395 if (_debugger.tri_sel)
396 {
397 // Draw the outline around the selected triangle
398 for (i=0; i<_debugger.tri_sel->nv; i++)
399 {
400 j=i+1;
401 if (j>=_debugger.tri_sel->nv) j=0;
402
403 grDrawLine (&_debugger.tri_sel->v[i], &_debugger.tri_sel->v[j]);
404
405 v[i] = &_debugger.tri_sel->v[i];
406 }
407 }
408
409 // and the selected texture
410 wxUint32 t_y = ((_debugger.tex_sel & 0xFFFFFFF0) >> 4) - _debugger.tex_scroll;
411 wxUint32 t_x = _debugger.tex_sel & 0xF;
412 VERTEX vt[4] = {
413 { SX(t_x*64.0f), SY(512+64.0f*t_y), 1, 1 },
414 { SX(t_x*64.0f+64.0f), SY(512+64.0f*t_y), 1, 1 },
415 { SX(t_x*64.0f), SY(512+64.0f*t_y+64.0f), 1, 1 },
416 { SX(t_x*64.0f+64.0f), SY(512+64.0f*t_y+64.0f), 1, 1 } };
417 if (t_y < 4)
418 {
419 grDrawLine (&vt[0], &vt[1]);
420 grDrawLine (&vt[1], &vt[3]);
421 grDrawLine (&vt[3], &vt[2]);
422 grDrawLine (&vt[2], &vt[0]);
423 }
424
425 grConstantColorValue (0xFF000020);
426
427 if (t_y < 4)
428 {
429 grDrawTriangle (&vt[2], &vt[1], &vt[0]);
430 grDrawTriangle (&vt[2], &vt[3], &vt[1]);
431 }
432
433 if (_debugger.tri_sel)
434 grDrawVertexArray (GR_TRIANGLE_FAN, _debugger.tri_sel->nv, &v);
435
436 // Draw the outline of the cacheviewer
437 if (_debugger.page == PAGE_TEX_INFO)
438 {
439 float scx = cache[_debugger.tex_sel].scale_x;
440 float scy = cache[_debugger.tex_sel].scale_y;
441
442 // And the grid
443 if (grid)
444 {
445 grConstantColorValue (COL_GRID);
446
447 float scale_y = (256.0f * scy) / (float)cache[_debugger.tex_sel].height;
448 for (int y=0; y<=(int)cache[_debugger.tex_sel].height; y++)
449 {
450 float y_val = SY(221.0f+y*scale_y);
451 VERTEX vh[2] = {
452 { SX(704.0f), y_val, 1, 1 },
453 { SX(704.0f+255.0f*scx), y_val, 1, 1 } };
454 grDrawLine (&vh[0], &vh[1]);
455 }
456
457 float scale_x = (256.0f * scx) / (float)cache[_debugger.tex_sel].width;
458 for (int x=0; x<=(int)cache[_debugger.tex_sel].width; x++)
459 {
460 float x_val = SX(704.0f+x*scale_x);
461 VERTEX vv[2] = {
462 { x_val, SX(221.0f), 1, 1 },
463 { x_val, SX(221.0f+256.0f*scy), 1, 1 } };
464 grDrawLine (&vv[0], &vv[1]);
465 }
466 }
467 }
468
469 grTexCombine (GR_TMU0,
470 GR_COMBINE_FUNCTION_LOCAL,
471 GR_COMBINE_FACTOR_NONE,
472 GR_COMBINE_FUNCTION_LOCAL,
473 GR_COMBINE_FACTOR_NONE,
474 FXFALSE,
475 FXFALSE);
476
477 grColorCombine (GR_COMBINE_FUNCTION_LOCAL,
478 GR_COMBINE_FACTOR_NONE,
479 GR_COMBINE_LOCAL_CONSTANT,
480 GR_COMBINE_OTHER_NONE,
481 FXFALSE);
482
483 grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
484 GR_COMBINE_FACTOR_ONE,
485 GR_COMBINE_LOCAL_NONE,
486 GR_COMBINE_OTHER_TEXTURE,
487 FXFALSE);
488
489 grConstantColorValue (0xFFFFFF00);
490
491 // Output the information about the selected triangle
492 grTexSource(GR_TMU0, // Text
493 voodoo.tex_min_addr[_debugger.tmu]+ offset_font,
494 GR_MIPMAPLEVELMASK_BOTH,
495 &fontTex);
496
497 static const char *cycle_mode_s[4] = { "1 cycle (0)", "2 cycle (1)", "copy (2)", "fill (3)" };
498
499#define OUTPUT(fmt,other) output(642,(float)i,1,fmt,other); i-=16;
500#define OUTPUT1(fmt,other,other1) output(642,(float)i,1,fmt,other,other1); i-=16;
501#define OUTPUT_(fmt,cc) COL_SEL(cc); x=642; output(x,(float)i,1,fmt,0); x+=8*(strlen(fmt)+1)
502#define _OUTPUT(fmt,cc) COL_SEL(cc); output(x,(float)i,1,fmt,0); x+=8*(strlen(fmt)+1)
503 i = 740;
504 float x;
505 if (_debugger.page == PAGE_GENERAL && _debugger.tri_sel)
506 {
507 COL_CATEGORY();
508 OUTPUT ("GENERAL (page 1):",0);
509 COL_TEXT();
510 OUTPUT ("tri #%d", _debugger.tri_sel->tri_n);
511 OUTPUT ("type: %s", tri_type[_debugger.tri_sel->type]);
512 OUTPUT ("geom: 0x%08lx", _debugger.tri_sel->geom_mode);
513 OUTPUT ("othermode_h: 0x%08lx", _debugger.tri_sel->othermode_h);
514 OUTPUT ("othermode_l: 0x%08lx", _debugger.tri_sel->othermode_l);
515 OUTPUT ("flags: 0x%08lx", _debugger.tri_sel->flags);
516 OUTPUT ("",0);
517 COL_CATEGORY();
518 OUTPUT ("COMBINE:",0);
519 COL_TEXT();
520 OUTPUT ("cycle_mode: %s", cycle_mode_s[_debugger.tri_sel->cycle_mode]);
521 OUTPUT ("cycle1: 0x%08lx", _debugger.tri_sel->cycle1);
522 OUTPUT ("cycle2: 0x%08lx", _debugger.tri_sel->cycle2);
523 if (_debugger.tri_sel->uncombined & 1)
524 COL_UCC();
525 else
526 COL_CC();
527 OUTPUT ("a0: %s", Mode0[(_debugger.tri_sel->cycle1)&0x0000000F]);
528 OUTPUT ("b0: %s", Mode1[(_debugger.tri_sel->cycle1>>4)&0x0000000F]);
529 OUTPUT ("c0: %s", Mode2[(_debugger.tri_sel->cycle1>>8)&0x0000001F]);
530 OUTPUT ("d0: %s", Mode3[(_debugger.tri_sel->cycle1>>13)&0x00000007]);
531 if (_debugger.tri_sel->uncombined & 2)
532 COL_UAC();
533 else
534 COL_AC();
535 OUTPUT ("Aa0: %s", Alpha0[(_debugger.tri_sel->cycle1>>16)&0x00000007]);
536 OUTPUT ("Ab0: %s", Alpha1[(_debugger.tri_sel->cycle1>>19)&0x00000007]);
537 OUTPUT ("Ac0: %s", Alpha2[(_debugger.tri_sel->cycle1>>22)&0x00000007]);
538 OUTPUT ("Ad0: %s", Alpha3[(_debugger.tri_sel->cycle1>>25)&0x00000007]);
539 if (_debugger.tri_sel->uncombined & 1)
540 COL_UCC();
541 else
542 COL_CC();
543 OUTPUT ("a1: %s", Mode0[(_debugger.tri_sel->cycle2)&0x0000000F]);
544 OUTPUT ("b1: %s", Mode1[(_debugger.tri_sel->cycle2>>4)&0x0000000F]);
545 OUTPUT ("c1: %s", Mode2[(_debugger.tri_sel->cycle2>>8)&0x0000001F]);
546 OUTPUT ("d1: %s", Mode3[(_debugger.tri_sel->cycle2>>13)&0x00000007]);
547 if (_debugger.tri_sel->uncombined & 2)
548 COL_UAC();
549 else
550 COL_AC();
551 OUTPUT ("Aa1: %s", Alpha0[(_debugger.tri_sel->cycle2>>16)&0x00000007]);
552 OUTPUT ("Ab1: %s", Alpha1[(_debugger.tri_sel->cycle2>>19)&0x00000007]);
553 OUTPUT ("Ac1: %s", Alpha2[(_debugger.tri_sel->cycle2>>22)&0x00000007]);
554 OUTPUT ("Ad1: %s", Alpha3[(_debugger.tri_sel->cycle2>>25)&0x00000007]);
555 }
556 if ((_debugger.page == PAGE_TEX1 || _debugger.page == PAGE_TEX2) && _debugger.tri_sel)
557 {
558 COL_CATEGORY ();
559 OUTPUT1 ("TEXTURE %d (page %d):", _debugger.page-PAGE_TEX1, 2+_debugger.page-PAGE_TEX1);
560 COL_TEXT();
561 int tmu = _debugger.page - PAGE_TEX1;
562 OUTPUT1 ("cur cache: %d,%d", _debugger.tri_sel->t[tmu].cur_cache[tmu]&0x0F, _debugger.tri_sel->t[tmu].cur_cache[tmu]>>4);
563 OUTPUT ("tex_size: %d", _debugger.tri_sel->t[tmu].size);
564 OUTPUT ("tex_format: %d", _debugger.tri_sel->t[tmu].format);
565 OUTPUT ("width: %d", _debugger.tri_sel->t[tmu].width);
566 OUTPUT ("height: %d", _debugger.tri_sel->t[tmu].height);
567 OUTPUT ("palette: %d", _debugger.tri_sel->t[tmu].palette);
568 OUTPUT ("clamp_s: %d", _debugger.tri_sel->t[tmu].clamp_s);
569 OUTPUT ("clamp_t: %d", _debugger.tri_sel->t[tmu].clamp_t);
570 OUTPUT ("mirror_s: %d", _debugger.tri_sel->t[tmu].mirror_s);
571 OUTPUT ("mirror_t: %d", _debugger.tri_sel->t[tmu].mirror_t);
572 OUTPUT ("mask_s: %d", _debugger.tri_sel->t[tmu].mask_s);
573 OUTPUT ("mask_t: %d", _debugger.tri_sel->t[tmu].mask_t);
574 OUTPUT ("shift_s: %d", _debugger.tri_sel->t[tmu].shift_s);
575 OUTPUT ("shift_t: %d", _debugger.tri_sel->t[tmu].shift_t);
576 OUTPUT ("ul_s: %d", _debugger.tri_sel->t[tmu].ul_s);
577 OUTPUT ("ul_t: %d", _debugger.tri_sel->t[tmu].ul_t);
578 OUTPUT ("lr_s: %d", _debugger.tri_sel->t[tmu].lr_s);
579 OUTPUT ("lr_t: %d", _debugger.tri_sel->t[tmu].lr_t);
580 OUTPUT ("t_ul_s: %d", _debugger.tri_sel->t[tmu].t_ul_s);
581 OUTPUT ("t_ul_t: %d", _debugger.tri_sel->t[tmu].t_ul_t);
582 OUTPUT ("t_lr_s: %d", _debugger.tri_sel->t[tmu].t_lr_s);
583 OUTPUT ("t_lr_t: %d", _debugger.tri_sel->t[tmu].t_lr_t);
584 OUTPUT ("scale_s: %f", _debugger.tri_sel->t[tmu].scale_s);
585 OUTPUT ("scale_t: %f", _debugger.tri_sel->t[tmu].scale_t);
586 OUTPUT ("s_mode: %s", str_cm[((_debugger.tri_sel->t[tmu].clamp_s << 1) | _debugger.tri_sel->t[tmu].mirror_s)&3]);
587 OUTPUT ("t_mode: %s", str_cm[((_debugger.tri_sel->t[tmu].clamp_t << 1) | _debugger.tri_sel->t[tmu].mirror_t)&3]);
588 }
589 if (_debugger.page == PAGE_COLORS && _debugger.tri_sel)
590 {
591 COL_CATEGORY();
592 OUTPUT ("COLORS (page 4)", 0);
593 COL_TEXT();
594 OUTPUT ("fill: %08lx", _debugger.tri_sel->fill_color);
595 OUTPUT ("prim: %08lx", _debugger.tri_sel->prim_color);
596 OUTPUT ("blend: %08lx", _debugger.tri_sel->blend_color);
597 OUTPUT ("env: %08lx", _debugger.tri_sel->env_color);
598 OUTPUT ("fog: %08lx", _debugger.tri_sel->fog_color);
599 OUTPUT ("prim_lodmin: %d", _debugger.tri_sel->prim_lodmin);
600 OUTPUT ("prim_lodfrac: %d", _debugger.tri_sel->prim_lodfrac);
601 }
602 if (_debugger.page == PAGE_FBL && _debugger.tri_sel)
603 {
604 COL_CATEGORY();
605 OUTPUT ("BLENDER", 0);
606 COL_TEXT();
607 OUTPUT ("fbl_a0: %s", FBLa[(_debugger.tri_sel->othermode_l>>30)&0x3]);
608 OUTPUT ("fbl_b0: %s", FBLb[(_debugger.tri_sel->othermode_l>>26)&0x3]);
609 OUTPUT ("fbl_c0: %s", FBLc[(_debugger.tri_sel->othermode_l>>22)&0x3]);
610 OUTPUT ("fbl_d0: %s", FBLd[(_debugger.tri_sel->othermode_l>>18)&0x3]);
611 OUTPUT ("fbl_a1: %s", FBLa[(_debugger.tri_sel->othermode_l>>28)&0x3]);
612 OUTPUT ("fbl_b1: %s", FBLb[(_debugger.tri_sel->othermode_l>>24)&0x3]);
613 OUTPUT ("fbl_c1: %s", FBLc[(_debugger.tri_sel->othermode_l>>20)&0x3]);
614 OUTPUT ("fbl_d1: %s", FBLd[(_debugger.tri_sel->othermode_l>>16)&0x3]);
615 OUTPUT ("", 0);
616 OUTPUT ("fbl: %08lx", _debugger.tri_sel->othermode_l&0xFFFF0000);
617 OUTPUT ("fbl #1: %08lx", _debugger.tri_sel->othermode_l&0xCCCC0000);
618 OUTPUT ("fbl #2: %08lx", _debugger.tri_sel->othermode_l&0x33330000);
619 }
620 if (_debugger.page == PAGE_OTHERMODE_L && _debugger.tri_sel)
621 {
622 wxUint32 othermode_l = _debugger.tri_sel->othermode_l;
623 COL_CATEGORY ();
624 OUTPUT ("OTHERMODE_L: %08lx", othermode_l);
625 OUTPUT_ ("AC_NONE", (othermode_l & 3) == 0);
626 _OUTPUT ("AC_THRESHOLD", (othermode_l & 3) == 1);
627 _OUTPUT ("AC_DITHER", (othermode_l & 3) == 3);
628 i -= 16;
629 OUTPUT_ ("ZS_PIXEL", !(othermode_l & 4));
630 _OUTPUT ("ZS_PRIM", (othermode_l & 4));
631 i -= 32;
632 COL_CATEGORY ();
633 OUTPUT ("RENDERMODE: %08lx", othermode_l);
634 OUTPUT_ ("AA_EN", othermode_l & 0x08);
635 i -= 16;
636 OUTPUT_ ("Z_CMP", othermode_l & 0x10);
637 i -= 16;
638 OUTPUT_ ("Z_UPD", othermode_l & 0x20);
639 i -= 16;
640 OUTPUT_ ("IM_RD", othermode_l & 0x40);
641 i -= 16;
642 OUTPUT_ ("CLR_ON_CVG", othermode_l & 0x80);
643 i -= 16;
644 OUTPUT_ ("CVG_DST_CLAMP", (othermode_l & 0x300) == 0x000);
645 _OUTPUT ("CVG_DST_WRAP", (othermode_l & 0x300) == 0x100);
646 _OUTPUT (".._FULL", (othermode_l & 0x300) == 0x200);
647 _OUTPUT (".._SAVE", (othermode_l & 0x300) == 0x300);
648 i -= 16;
649 OUTPUT_ ("ZM_OPA", (othermode_l & 0xC00) == 0x000);
650 _OUTPUT ("ZM_INTER", (othermode_l & 0xC00) == 0x400);
651 _OUTPUT ("ZM_XLU", (othermode_l & 0xC00) == 0x800);
652 _OUTPUT ("ZM_DEC", (othermode_l & 0xC00) == 0xC00);
653 i -= 16;
654 OUTPUT_ ("CVG_X_ALPHA", othermode_l & 0x1000);
655 i -= 16;
656 OUTPUT_ ("ALPHA_CVG_SEL", othermode_l & 0x2000);
657 i -= 16;
658 OUTPUT_ ("FORCE_BL", othermode_l & 0x4000);
659 }
660 if (_debugger.page == PAGE_OTHERMODE_H && _debugger.tri_sel)
661 {
662 wxUint32 othermode_h = _debugger.tri_sel->othermode_h;
663 COL_CATEGORY ();
664 OUTPUT ("OTHERMODE_H: %08lx", othermode_h);
665 OUTPUT_ ("CK_NONE", (othermode_h & 0x100) == 0);
666 _OUTPUT ("CK_KEY", (othermode_h & 0x100) == 1);
667 i -= 16;
668 OUTPUT_ ("TC_CONV", (othermode_h & 0xE00) == 0x200);
669 _OUTPUT ("TC_FILTCONV", (othermode_h & 0xE00) == 0xA00);
670 _OUTPUT ("TC_FILT", (othermode_h & 0xE00) == 0xC00);
671 i -= 16;
672 OUTPUT_ ("TF_POINT", (othermode_h & 0x3000) == 0x0000);
673 _OUTPUT ("TF_AVERAGE", (othermode_h & 0x3000) == 0x3000);
674 _OUTPUT ("TF_BILERP", (othermode_h & 0x3000) == 0x2000);
675 i -= 16;
676 OUTPUT_ ("TT_NONE", (othermode_h & 0xC000) == 0x0000);
677 _OUTPUT ("TT_RGBA16", (othermode_h & 0xC000) == 0x8000);
678 _OUTPUT ("TT_IA16", (othermode_h & 0xC000) == 0xC000);
679 i -= 16;
680 OUTPUT_ ("TL_TILE", (othermode_h & 0x10000) == 0x00000);
681 _OUTPUT ("TL_LOD", (othermode_h & 0x10000) == 0x10000);
682 i -= 16;
683 OUTPUT_ ("TD_CLAMP", (othermode_h & 0x60000) == 0x00000);
684 _OUTPUT ("TD_SHARPEN", (othermode_h & 0x60000) == 0x20000);
685 _OUTPUT ("TD_DETAIL", (othermode_h & 0x60000) == 0x40000);
686 i -= 16;
687 OUTPUT_ ("TP_NONE", (othermode_h & 0x80000) == 0x00000);
688 _OUTPUT ("TP_PERSP", (othermode_h & 0x80000) == 0x80000);
689 i -= 16;
690 OUTPUT_ ("1CYCLE", (othermode_h & 0x300000) == 0x000000);
691 _OUTPUT ("2CYCLE", (othermode_h & 0x300000) == 0x100000);
692 _OUTPUT ("COPY", (othermode_h & 0x300000) == 0x200000);
693 _OUTPUT ("FILL", (othermode_h & 0x300000) == 0x300000);
694 i -= 16;
695 OUTPUT_ ("PM_1PRIM", (othermode_h & 0x400000) == 0x000000);
696 _OUTPUT ("PM_NPRIM", (othermode_h & 0x400000) == 0x400000);
697 }
698 if (_debugger.page == PAGE_TEXELS && _debugger.tri_sel)
699 {
700 // change these to output whatever you need, ou for triangles, or u0 for texrects
701 COL_TEXT();
702 OUTPUT ("n: %d", _debugger.tri_sel->nv);
703 OUTPUT ("",0);
704 for (j=0; j<_debugger.tri_sel->nv; j++)
705 {
706 OUTPUT1 ("v[%d].s0: %f", j, _debugger.tri_sel->v[j].ou);
707 OUTPUT1 ("v[%d].t0: %f", j, _debugger.tri_sel->v[j].ov);
708 }
709 OUTPUT ("",0);
710 for (j=0; j<_debugger.tri_sel->nv; j++)
711 {
712 OUTPUT1 ("v[%d].s1: %f", j, _debugger.tri_sel->v[j].u0);
713 OUTPUT1 ("v[%d].t1: %f", j, _debugger.tri_sel->v[j].v0);
714 }
715 }
716 if (_debugger.page == PAGE_COORDS && _debugger.tri_sel)
717 {
718 COL_TEXT();
719 OUTPUT ("n: %d", _debugger.tri_sel->nv);
720 for (j=0; j<_debugger.tri_sel->nv; j++)
721 {
722 OUTPUT1 ("v[%d].x: %f", j, _debugger.tri_sel->v[j].x);
723 OUTPUT1 ("v[%d].y: %f", j, _debugger.tri_sel->v[j].y);
724 OUTPUT1 ("v[%d].z: %f", j, _debugger.tri_sel->v[j].z);
725 OUTPUT1 ("v[%d].w: %f", j, _debugger.tri_sel->v[j].w);
726 OUTPUT1 ("v[%d].f: %f", j, 1.0f/_debugger.tri_sel->v[j].f);
727 OUTPUT1 ("v[%d].r: %d", j, _debugger.tri_sel->v[j].r);
728 OUTPUT1 ("v[%d].g: %d", j, _debugger.tri_sel->v[j].g);
729 OUTPUT1 ("v[%d].b: %d", j, _debugger.tri_sel->v[j].b);
730 OUTPUT1 ("v[%d].a: %d", j, _debugger.tri_sel->v[j].a);
731 }
732 }
733 if (_debugger.page == PAGE_TEX_INFO && _debugger.tex_sel < (wxUint32)rdp.n_cached[_debugger.tmu])
734 {
735 COL_CATEGORY();
736 OUTPUT ("CACHE (page 0)", 0);
737 COL_TEXT();
738 //OUTPUT ("t_mem: %08lx", rdp.cache[0][_debugger.tex_sel].t_mem);
739 //OUTPUT ("crc: %08lx", rdp.cache[0][_debugger.tex_sel].crc);
740 OUTPUT ("addr: %08lx", cache[_debugger.tex_sel].addr);
741 OUTPUT ("scale_x: %f", cache[_debugger.tex_sel].scale_x);
742 OUTPUT ("scale_y: %f", cache[_debugger.tex_sel].scale_y);
743 OUTPUT ("tmem_addr: %08lx", cache[_debugger.tex_sel].tmem_addr);
744 OUTPUT ("palette: %08lx", cache[_debugger.tex_sel].palette);
745 OUTPUT ("set_by: %08lx", cache[_debugger.tex_sel].set_by);
746 OUTPUT ("texrecting: %d", cache[_debugger.tex_sel].texrecting);
747
748 OUTPUT ("mod: %08lx", cache[_debugger.tex_sel].mod);
749 OUTPUT ("mod_col: %08lx", cache[_debugger.tex_sel].mod_color);
750 OUTPUT ("mod_col1: %08lx", cache[_debugger.tex_sel].mod_color1);
751 i=740;
752 output(800,(float)i,1,"width: %d", cache[_debugger.tex_sel].width);
753 i-=16;
754 output(800,(float)i,1,"height: %d", cache[_debugger.tex_sel].height);
755 i-=16;
756 output(800,(float)i,1,"format: %d", cache[_debugger.tex_sel].format);
757 i-=16;
758 output(800,(float)i,1,"size: %d", cache[_debugger.tex_sel].size);
759 i-=16;
760 output(800,(float)i,1,"crc: %08lx", cache[_debugger.tex_sel].crc);
761 i-=16;
762#ifdef TEXTURE_FILTER
763 output(800,(float)i,1,"RiceCrc: %08lx", (wxUint32)(rdp.cache[_debugger.tmu][_debugger.tex_sel].ricecrc&0xFFFFFFFF));
764 i-=16;
765 output(800,(float)i,1,"RicePalCrc: %08lx", (wxUint32)(rdp.cache[_debugger.tmu][_debugger.tex_sel].ricecrc>>32));
766 i-=16;
767#endif
768 output(800,(float)i,1,"flags: %08lx", cache[_debugger.tex_sel].flags);
769 i-=16;
770 output(800,(float)i,1,"line: %d", cache[_debugger.tex_sel].line);
771 i-=16;
772 output(800,(float)i,1,"mod_factor: %08lx", cache[_debugger.tex_sel].mod_factor);
773 i-=32;
774
775 output(800,(float)i,1,"lod: %s", str_lod[cache[_debugger.tex_sel].lod]);
776 i-=16;
777 output(800,(float)i,1,"aspect: %s", str_aspect[cache[_debugger.tex_sel].aspect + 3]);
778
779// debug_texture(_debugger.tmu, cache[_debugger.tex_sel].addr, _debugger.tex_sel);
780 }
781
782 // Draw the vertex numbers
783 if (_debugger.tri_sel)
784 {
785 for (i=0; i<_debugger.tri_sel->nv; i++)
786 {
787 grConstantColorValue (0x000000FF);
788 output (_debugger.tri_sel->v[i].x+1, settings.scr_res_y-_debugger.tri_sel->v[i].y+1, 1,
789 "%d", i);
790 grConstantColorValue (0xFFFFFFFF);
791 output (_debugger.tri_sel->v[i].x, settings.scr_res_y-_debugger.tri_sel->v[i].y, 1,
792 "%d", i);
793 }
794 }
795
796 // Draw the cursor
797 debug_mouse ();
798
799 grBufferSwap (1);
800 }
801
802END:
803 // Release all data
804 delete [] _debugger.screen;
805 TRI_INFO *tri;
806 for (tri=_debugger.tri_list; tri != _debugger.tri_last;)
807 {
808 TRI_INFO *tmp = tri;
809 tri = tri->pNext;
810 delete [] tmp->v;
811 delete tmp;
812 }
813 delete [] tri->v;
814 delete tri;
815
816 // Reset all values
817 _debugger.capture = 0;
818 _debugger.selected = SELECTED_TRI;
819 _debugger.screen = NULL;
820 _debugger.tri_list = NULL;
821 _debugger.tri_last = NULL;
822 _debugger.tri_sel = NULL;
823 _debugger.tex_sel = 0;
824}
825
826//
827// debug_mouse - draws the debugger mouse
828//
829
830void debug_mouse ()
831{
832 grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
833 GR_COMBINE_FACTOR_ONE,
834 GR_COMBINE_LOCAL_NONE,
835 GR_COMBINE_OTHER_TEXTURE,
836 FXFALSE);
837
838 grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
839 GR_COMBINE_FACTOR_ONE,
840 GR_COMBINE_LOCAL_NONE,
841 GR_COMBINE_OTHER_TEXTURE,
842 FXFALSE);
843
844 // Draw the cursor
845 POINT pt;
846 DbgCursorPos(&pt);
847 float cx = (float)pt.x;
848 float cy = (float)pt.y;
849
850 VERTEX v[4] = {
851 { cx, cy, 1, 1, 0, 0, 0, 0, {0, 0, 0, 0} },
852 { cx+32, cy, 1, 1, 255, 0, 0, 0, {0, 0, 0, 0} },
853 { cx, cy+32, 1, 1, 0, 255, 0, 0, {0, 0, 0, 0} },
854 { cx+32, cy+32, 1, 1, 255, 255, 0, 0, {0, 0, 0, 0} }
855 };
856
857 ConvertCoordsKeep (v, 4);
858
859 grTexSource(GR_TMU0,
860 voodoo.tex_min_addr[GR_TMU0] + offset_cursor,
861 GR_MIPMAPLEVELMASK_BOTH,
862 &cursorTex);
863
864 if (voodoo.num_tmu >= 3)
865 grTexCombine (GR_TMU2,
866 GR_COMBINE_FUNCTION_NONE,
867 GR_COMBINE_FACTOR_NONE,
868 GR_COMBINE_FUNCTION_NONE,
869 GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
870 if (voodoo.num_tmu >= 2)
871 grTexCombine (GR_TMU1,
872 GR_COMBINE_FUNCTION_NONE,
873 GR_COMBINE_FACTOR_NONE,
874 GR_COMBINE_FUNCTION_NONE,
875 GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
876 grTexCombine (GR_TMU0,
877 GR_COMBINE_FUNCTION_LOCAL,
878 GR_COMBINE_FACTOR_NONE,
879 GR_COMBINE_FUNCTION_LOCAL,
880 GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
881
882 grDrawTriangle (&v[0], &v[1], &v[2]);
883 grDrawTriangle (&v[1], &v[3], &v[2]);
884}
885
886//
887// debug_keys - receives debugger key input
888//
889
890void debug_keys ()
891{
892 if (CheckKeyPressed(G64_VK_RIGHT, 0x0001) && _debugger.tri_sel)
893 {
894 TRI_INFO *start = _debugger.tri_sel;
895
896 while (_debugger.tri_sel->pNext != start)
897 _debugger.tri_sel = _debugger.tri_sel->pNext;
898 }
899
900 if (CheckKeyPressed(G64_VK_LEFT, 0x0001) && _debugger.tri_sel)
901 _debugger.tri_sel = _debugger.tri_sel->pNext;
902
903 // Check for page changes
904 if (CheckKeyPressed(G64_VK_1, 0x0001))
905 _debugger.page = PAGE_GENERAL;
906 if (CheckKeyPressed(G64_VK_2, 0x0001))
907 _debugger.page = PAGE_TEX1;
908 if (CheckKeyPressed(G64_VK_3, 0x0001))
909 _debugger.page = PAGE_TEX2;
910 if (CheckKeyPressed(G64_VK_4, 0x0001))
911 _debugger.page = PAGE_COLORS;
912 if (CheckKeyPressed(G64_VK_5, 0x0001))
913 _debugger.page = PAGE_FBL;
914 if (CheckKeyPressed(G64_VK_6, 0x0001))
915 _debugger.page = PAGE_OTHERMODE_L;
916 if (CheckKeyPressed(G64_VK_7, 0x0001))
917 _debugger.page = PAGE_OTHERMODE_H;
918 if (CheckKeyPressed(G64_VK_8, 0x0001))
919 _debugger.page = PAGE_TEXELS;
920 if (CheckKeyPressed(G64_VK_9, 0x0001))
921 _debugger.page = PAGE_COORDS;
922 if (CheckKeyPressed(G64_VK_0, 0x0001))
923 _debugger.page = PAGE_TEX_INFO;
924 if (CheckKeyPressed(G64_VK_Q, 0x0001))
925 _debugger.tmu = 0;
926 if (CheckKeyPressed(G64_VK_W, 0x0001))
927 _debugger.tmu = 1;
928
929 if (CheckKeyPressed(G64_VK_G, 0x0001))
930 grid = !grid;
931
932 // Go to texture
933 if (CheckKeyPressed(G64_VK_SPACE, 0x0001))
934 {
935 int tile = -1;
936 if (_debugger.page == PAGE_TEX2)
937 tile = 1;
938 else
939 tile = 0;
940 if (tile != -1)
941 {
942 _debugger.tmu = _debugger.tri_sel->t[tile].tmu;
943 _debugger.tex_sel = _debugger.tri_sel->t[tile].cur_cache[_debugger.tmu];
944 _debugger.tex_scroll = (_debugger.tri_sel->t[tile].cur_cache[_debugger.tmu] >> 4) - 1;
945 }
946 }
947
948 // Go to triangle
949 CACHE_LUT * cache = voodoo.tex_UMA?rdp.cache[0]:rdp.cache[_debugger.tmu];
950 if (CheckKeyPressed(G64_VK_CONTROL, 0x0001))
951 {
952 int count = rdp.debug_n - cache[_debugger.tex_sel].uses - 1;
953 if (cache[_debugger.tex_sel].last_used == frame_count)
954 {
955 TRI_INFO *t = _debugger.tri_list;
956 while (count && t) {
957 t = t->pNext;
958 count --;
959 }
960 _debugger.tri_sel = t;
961 }
962 else
963 _debugger.tri_sel = NULL;
964 }
965
966 if (CheckKeyPressed(G64_VK_A, 0x0001))
967 _debugger.draw_mode = 0; // texture & texture alpha
968 if (CheckKeyPressed(G64_VK_S, 0x0001))
969 _debugger.draw_mode = 1; // texture
970 if (CheckKeyPressed(G64_VK_D, 0x0001))
971 _debugger.draw_mode = 2; // texture alpha
972
973 // Check for texture scrolling
974 if (CheckKeyPressed(G64_VK_DOWN, 0x0001))
975 _debugger.tex_scroll ++;
976 if (CheckKeyPressed(G64_VK_UP, 0x0001))
977 _debugger.tex_scroll --;
978}
979
980//
981// output - output debugger text
982//
983
984void output (float x, float y, int scale, const char *fmt, ...)
985{
986 va_list ap;
987 va_start(ap,fmt);
988 vsprintf(out_buf, fmt, ap);
989 va_end(ap);
990
991 wxUint8 c,r;
992 for (wxUint32 i=0; i<strlen(out_buf); i++)
993 {
994 c = ((out_buf[i]-32) & 0x1F) * 8;//<< 3;
995 r = (((out_buf[i]-32) & 0xE0) >> 5) * 16;//<< 4;
996 VERTEX v[4] = { { SX(x), SY(768-y), 1, 1, (float)c, r+16.0f, 0, 0, {0, 0, 0, 0} },
997 { SX(x+8), SY(768-y), 1, 1, c+8.0f, r+16.0f, 0, 0, {0, 0, 0, 0} },
998 { SX(x), SY(768-y-16), 1, 1, (float)c, (float)r, 0, 0, {0, 0, 0, 0} },
999 { SX(x+8), SY(768-y-16), 1, 1, c+8.0f, (float)r, 0, 0, {0, 0, 0, 0} }
1000 };
1001 if (!scale)
1002 {
1003 v[0].x = x;
1004 v[0].y = y;
1005 v[1].x = x+8;
1006 v[1].y = y;
1007 v[2].x = x;
1008 v[2].y = y-16;
1009 v[3].x = x+8;
1010 v[3].y = y-16;
1011 }
1012
1013 ConvertCoordsKeep (v, 4);
1014
1015 grDrawTriangle (&v[0], &v[1], &v[2]);
1016 grDrawTriangle (&v[1], &v[3], &v[2]);
1017
1018 x+=8;
1019 }
1020}