Replace Tmem_nasm.asm with C++ code. Patch by pyro.
[Glide64.git] / Debugger.cpp
blob08cb0b4b8748ac346f7f1a7fd9fc09c1e252653e
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 // Original author: Dave2001 (Dave2999@hotmail.com)
32 // Other authors: Gonetz, Gugaman
34 //****************************************************************
36 #include "Gfx1.3.h"
37 #include "Util.h"
38 #include "Debugger.h"
40 #ifndef _WIN32
41 #include <stdarg.h>
42 #include <string.h>
43 #endif // _WIN32
45 DEBUGGER debug;
47 #define SX(x) ((x)*rdp.scale_1024)
48 #define SY(x) ((x)*rdp.scale_768)
50 #ifdef COLORED_DEBUGGER
51 #define COL_CATEGORY() grConstantColorValue(0xD288F400)
52 #define COL_UCC() grConstantColorValue(0xFF000000)
53 #define COL_CC() grConstantColorValue(0x88C3F400)
54 #define COL_UAC() grConstantColorValue(0xFF808000)
55 #define COL_AC() grConstantColorValue(0x3CEE5E00)
56 #define COL_TEXT() grConstantColorValue(0xFFFFFF00)
57 #define COL_SEL(x) grConstantColorValue((x)?0x00FF00FF:0x800000FF)
58 #else
59 #define COL_CATEGORY()
60 #define COL_UCC()
61 #define COL_CC()
62 #define COL_UAC()
63 #define COL_AC()
64 #define COL_TEXT()
65 #define COL_SEL(x)
66 #endif
68 #define COL_GRID 0xFFFFFF80
70 BOOL grid = 0;
73 // debug_init - initialize the debugger
76 void debug_init ()
78 debug.capture = 0;
79 debug.selected = SELECTED_TRI;
80 debug.screen = NULL;
81 debug.tri_list = NULL;
82 debug.tri_last = NULL;
83 debug.tri_sel = NULL;
84 debug.tmu = 0;
86 debug.tex_scroll = 0;
87 debug.tex_sel = 0;
89 debug.draw_mode = 0;
93 // debug_cacheviewer - views the debugger's cache
96 void debug_cacheviewer ()
98 grCullMode (GR_CULL_DISABLE);
100 int i;
101 for (i=0; i<2; i++)
103 grTexFilterMode (i,
104 (settings.filter_cache)?GR_TEXTUREFILTER_BILINEAR:GR_TEXTUREFILTER_POINT_SAMPLED,
105 (settings.filter_cache)?GR_TEXTUREFILTER_BILINEAR:GR_TEXTUREFILTER_POINT_SAMPLED);
106 grTexClampMode (i,
107 GR_TEXTURECLAMP_CLAMP,
108 GR_TEXTURECLAMP_CLAMP);
111 switch (debug.draw_mode)
113 case 0:
114 grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
115 GR_COMBINE_FACTOR_ONE,
116 GR_COMBINE_LOCAL_NONE,
117 GR_COMBINE_OTHER_TEXTURE,
118 FXFALSE);
119 grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
120 GR_COMBINE_FACTOR_ONE,
121 GR_COMBINE_LOCAL_NONE,
122 GR_COMBINE_OTHER_TEXTURE,
123 FXFALSE);
124 break;
125 case 1:
126 grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
127 GR_COMBINE_FACTOR_ONE,
128 GR_COMBINE_LOCAL_NONE,
129 GR_COMBINE_OTHER_TEXTURE,
130 FXFALSE);
131 grAlphaCombine (GR_COMBINE_FUNCTION_LOCAL,
132 GR_COMBINE_FACTOR_NONE,
133 GR_COMBINE_LOCAL_CONSTANT,
134 GR_COMBINE_OTHER_NONE,
135 FXFALSE);
136 grConstantColorValue (0xFFFFFFFF);
137 break;
138 case 2:
139 grColorCombine (GR_COMBINE_FUNCTION_LOCAL,
140 GR_COMBINE_FACTOR_NONE,
141 GR_COMBINE_LOCAL_CONSTANT,
142 GR_COMBINE_OTHER_NONE,
143 FXFALSE);
144 grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
145 GR_COMBINE_FACTOR_ONE,
146 GR_COMBINE_LOCAL_NONE,
147 GR_COMBINE_OTHER_TEXTURE,
148 FXFALSE);
149 grConstantColorValue (0xFFFFFFFF);
152 if (debug.tmu == 1)
154 grTexCombine (GR_TMU1,
155 GR_COMBINE_FUNCTION_LOCAL,
156 GR_COMBINE_FACTOR_NONE,
157 GR_COMBINE_FUNCTION_LOCAL,
158 GR_COMBINE_FACTOR_NONE,
159 FXFALSE,
160 FXFALSE);
162 grTexCombine (GR_TMU0,
163 GR_COMBINE_FUNCTION_SCALE_OTHER,
164 GR_COMBINE_FACTOR_ONE,
165 GR_COMBINE_FUNCTION_SCALE_OTHER,
166 GR_COMBINE_FACTOR_ONE,
167 FXFALSE,
168 FXFALSE);
170 else
172 grTexCombine (GR_TMU0,
173 GR_COMBINE_FUNCTION_LOCAL,
174 GR_COMBINE_FACTOR_NONE,
175 GR_COMBINE_FUNCTION_LOCAL,
176 GR_COMBINE_FACTOR_NONE,
177 FXFALSE,
178 FXFALSE);
181 grAlphaBlendFunction (GR_BLEND_SRC_ALPHA,
182 GR_BLEND_ONE_MINUS_SRC_ALPHA,
183 GR_BLEND_ONE,
184 GR_BLEND_ZERO);
186 // Draw texture memory
187 for (i=0; i<4; i++)
189 for (DWORD x=0; x<16; x++)
191 DWORD y = i+debug.tex_scroll;
192 if (x+y*16 >= (DWORD)rdp.n_cached[debug.tmu]) break;
194 VERTEX v[4] = {
195 { SX(x*64.0f), SY(512+64.0f*i), 1, 1, 0, 0, 0, 0, {0, 0, 0, 0} },
196 { SX(x*64.0f+64.0f*rdp.cache[debug.tmu][x+y*16].scale_x), SY(512+64.0f*i), 1, 1, 255*rdp.cache[debug.tmu][x+y*16].scale_x, 0, 0, 0, {0, 0, 0, 0} },
197 { SX(x*64.0f), SY(512+64.0f*i+64.0f*rdp.cache[debug.tmu][x+y*16].scale_y), 1, 1, 0, 255*rdp.cache[debug.tmu][x+y*16].scale_y, 0, 0, {0, 0, 0, 0} },
198 { SX(x*64.0f+64.0f*rdp.cache[debug.tmu][x+y*16].scale_x), SY(512+64.0f*i+64.0f*rdp.cache[debug.tmu][x+y*16].scale_y), 1, 1, 255*rdp.cache[debug.tmu][x+y*16].scale_x, 255*rdp.cache[debug.tmu][x+y*16].scale_y, 0, 0, {0, 0, 0, 0} } };
199 for (int i=0; i<4; i++)
201 v[i].u1 = v[i].u0;
202 v[i].v1 = v[i].v0;
205 ConvertCoordsConvert (v, 4);
207 grTexSource(debug.tmu,
208 grTexMinAddress(debug.tmu) + rdp.cache[debug.tmu][x+y*16].tmem_addr,
209 GR_MIPMAPLEVELMASK_BOTH,
210 &rdp.cache[debug.tmu][x+y*16].t_info);
212 grDrawTriangle (&v[2], &v[1], &v[0]);
213 grDrawTriangle (&v[2], &v[3], &v[1]);
217 /* for (i=0; i<4; i++)
219 for (DWORD x=0; x<16; x++)
221 DWORD y = i+debug.tex_scroll;
222 if (x+y*16 >= (DWORD)rdp.n_cached[debug.tmu]) break;
224 VERTEX v[4] = {
225 { SX(x*64.0f), SY(768-64.0f*i), 1, 1, 0, 0, 0, 0, 0, 0, 0 },
226 { SX(x*64.0f+64.0f), SY(768-64.0f*i), 1, 1, 255, 0, 0, 0, 0, 0, 0 },
227 { SX(x*64.0f), SY(768-64.0f*i-64.0f), 1, 1, 0, 255, 0, 0, 0, 0, 0 },
228 { SX(x*64.0f+64.0f), SY(768-64.0f*i-64.0f), 1, 1, 255, 255, 0, 0, 0, 0, 0 } };
229 for (int i=0; i<4; i++)
231 v[i].u1 = v[i].u0;
232 v[i].v1 = v[i].v0;
235 ConvertCoordsConvert (v, 4);
237 grTexSource(debug.tmu,
238 grTexMinAddress(debug.tmu) + rdp.cache[debug.tmu][x+y*16].tmem_addr,
239 GR_MIPMAPLEVELMASK_BOTH,
240 &rdp.cache[debug.tmu][x+y*16].t_info);
242 grDrawTriangle (&v[2], &v[1], &v[0]);
243 grDrawTriangle (&v[2], &v[3], &v[1]);
249 // debug_capture - does a frame capture event (for debugging)
251 #ifdef _WIN32
252 void debug_capture ()
254 DWORD i,j;
256 if (debug.tri_list == NULL) goto END;
257 debug.tri_sel = debug.tri_list;
258 debug.selected = SELECTED_TRI;
260 // Connect the list
261 debug.tri_last->pNext = debug.tri_list;
263 while (!(GetAsyncKeyState(VK_INSERT) & 0x0001))
265 // Check for clicks
266 if (GetAsyncKeyState(GetSystemMetrics(SM_SWAPBUTTON)?VK_RBUTTON:VK_LBUTTON) & 0x0001)
268 POINT pt;
269 GetCursorPos (&pt);
271 //int diff = settings.scr_res_y-settings.res_y;
273 if (pt.y <= (int)settings.res_y)
275 int x = pt.x;
276 int y = pt.y;//settings.res_y - (pt.y - diff);
278 TRI_INFO *start;
279 TRI_INFO *tri;
280 if (debug.tri_sel == NULL) tri = debug.tri_list, start = debug.tri_list;
281 else tri = debug.tri_sel->pNext, start = debug.tri_sel;
283 // Select a triangle (start from the currently selected one)
284 do {
285 if (tri->v[0].x == tri->v[1].x &&
286 tri->v[0].y == tri->v[1].y)
288 tri = tri->pNext;
289 continue;
292 for (i=0; i<tri->nv; i++)
294 j=i+1;
295 if (j==tri->nv) j=0;
297 if ((y-tri->v[i].y)*(tri->v[j].x-tri->v[i].x) -
298 (x-tri->v[i].x)*(tri->v[j].y-tri->v[i].y) < 0)
299 break; // It's outside
302 if (i==tri->nv) // all lines passed
304 debug.tri_sel = tri;
305 break;
308 for (i=0; i<tri->nv; i++)
310 j=i+1;
311 if (j==tri->nv) j=0;
313 if ((y-tri->v[i].y)*(tri->v[j].x-tri->v[i].x) -
314 (x-tri->v[i].x)*(tri->v[j].y-tri->v[i].y) > 0)
315 break; // It's outside
318 if (i==tri->nv) // all lines passed
320 debug.tri_sel = tri;
321 break;
324 tri = tri->pNext;
325 } while (tri != start);
327 else
329 // on a texture
330 debug.tex_sel = (((DWORD)((pt.y-SY(512))/SY(64))+debug.tex_scroll)*16) +
331 (DWORD)(pt.x/SX(64));
335 debug_keys ();
337 grBufferClear (0, 0, 0xFFFF);
339 // Copy the screen capture back to the screen:
340 // Lock the backbuffer
341 GrLfbInfo_t info;
342 while (!grLfbLock (GR_LFB_WRITE_ONLY,
343 GR_BUFFER_BACKBUFFER,
344 GR_LFBWRITEMODE_565,
345 GR_ORIGIN_UPPER_LEFT,
346 FXFALSE,
347 &info));
349 DWORD offset_src=0/*(settings.scr_res_y-settings.res_y)*info.strideInBytes*/, offset_dst=0;
351 // Copy the screen
352 for (DWORD y=0; y<settings.res_y; y++)
354 memcpy ((BYTE*)info.lfbPtr + offset_src, debug.screen + offset_dst, settings.res_x << 1);
355 offset_dst += settings.res_x << 1;
356 offset_src += info.strideInBytes;
359 // Unlock the backbuffer
360 grLfbUnlock (GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER);
362 // Do the cacheviewer
363 debug_cacheviewer ();
365 // **
366 // 3/16/02: Moved texture viewer out of loop, remade it. Now it's simpler, and
367 // supports TMU1. [Dave2001]
368 // Original by Gugaman
370 if (debug.page == PAGE_TEX_INFO)
372 grTexSource(debug.tmu,
373 grTexMinAddress(debug.tmu) + rdp.cache[debug.tmu][debug.tex_sel].tmem_addr,
374 GR_MIPMAPLEVELMASK_BOTH,
375 &rdp.cache[debug.tmu][debug.tex_sel].t_info);
377 #ifdef SHOW_FULL_TEXVIEWER
378 float scx = 1.0f;
379 float scy = 1.0f;
380 #else
381 float scx = rdp.cache[debug.tmu][debug.tex_sel].scale_x;
382 float scy = rdp.cache[debug.tmu][debug.tex_sel].scale_y;
383 #endif
384 VERTEX v[4] = {
385 { SX(704.0f), SY(221.0f), 1, 1, 0, 0, 0, 0, 0, 0, 0 },
386 { SX(704.0f+256.0f*scx), SY(221.0f), 1, 1, 255*scx, 0, 255*scx, 0, 0, 0, 0 },
387 { SX(704.0f), SY(221.0f+256.0f*scy), 1, 1, 0, 255*scy, 0, 255*scy, 0, 0, 0 },
388 { 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 } };
389 ConvertCoordsConvert (v, 4);
390 VERTEX *varr[4] = { &v[0], &v[1], &v[2], &v[3] };
391 grDrawVertexArray (GR_TRIANGLE_STRIP, 4, varr);
394 // **
396 grTexFilterMode (GR_TMU0,
397 GR_TEXTUREFILTER_BILINEAR,
398 GR_TEXTUREFILTER_BILINEAR);
400 grColorCombine (GR_COMBINE_FUNCTION_LOCAL,
401 GR_COMBINE_FACTOR_NONE,
402 GR_COMBINE_LOCAL_CONSTANT,
403 GR_COMBINE_OTHER_NONE,
404 FXFALSE);
406 grAlphaCombine (GR_COMBINE_FUNCTION_LOCAL,
407 GR_COMBINE_FACTOR_NONE,
408 GR_COMBINE_LOCAL_CONSTANT,
409 GR_COMBINE_OTHER_NONE,
410 FXFALSE);
412 grConstantColorValue (0x0000FFFF);
414 VERTEX *v[8];
415 if (debug.tri_sel)
417 // Draw the outline around the selected triangle
418 for (i=0; i<debug.tri_sel->nv; i++)
420 j=i+1;
421 if (j>=debug.tri_sel->nv) j=0;
423 grDrawLine (&debug.tri_sel->v[i], &debug.tri_sel->v[j]);
425 v[i] = &debug.tri_sel->v[i];
429 // and the selected texture
430 DWORD t_y = ((debug.tex_sel & 0xFFFFFFF0) >> 4) - debug.tex_scroll;
431 DWORD t_x = debug.tex_sel & 0xF;
432 VERTEX vt[4] = {
433 { SX(t_x*64.0f), SY(512+64.0f*t_y), 1, 1 },
434 { SX(t_x*64.0f+64.0f), SY(512+64.0f*t_y), 1, 1 },
435 { SX(t_x*64.0f), SY(512+64.0f*t_y+64.0f), 1, 1 },
436 { SX(t_x*64.0f+64.0f), SY(512+64.0f*t_y+64.0f), 1, 1 } };
437 if (t_y < 4)
439 grDrawLine (&vt[0], &vt[1]);
440 grDrawLine (&vt[1], &vt[3]);
441 grDrawLine (&vt[3], &vt[2]);
442 grDrawLine (&vt[2], &vt[0]);
445 grConstantColorValue (0xFF000020);
447 if (t_y < 4)
449 grDrawTriangle (&vt[2], &vt[1], &vt[0]);
450 grDrawTriangle (&vt[2], &vt[3], &vt[1]);
453 if (debug.tri_sel)
454 grDrawVertexArray (GR_TRIANGLE_FAN, debug.tri_sel->nv, &v);
456 // Draw the outline of the cacheviewer
457 if (debug.page == PAGE_TEX_INFO)
459 /*grConstantColorValue (0xFF0000FF);
460 float scx = rdp.cache[debug.tmu][debug.tex_sel].scale_x;
461 float scy = rdp.cache[debug.tmu][debug.tex_sel].scale_y;
462 VERTEX v[4] = {
463 { SX(704.0f), SY(271.0f), 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
464 { SX(704.0f+256.0f*scx), SY(271.0f), 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
465 { SX(704.0f), SY(271.0f-256.0f*scy), 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
466 { SX(704.0f+256.0f*scx), SY(271.0f-256.0f*scy), 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
467 VERTEX *varr[5] = { &v[0], &v[1], &v[3], &v[2], &v[0] };
468 grDrawVertexArray (GR_LINE_STRIP, 5, varr);*/
470 float scx = rdp.cache[debug.tmu][debug.tex_sel].scale_x;
471 float scy = rdp.cache[debug.tmu][debug.tex_sel].scale_y;
473 // And the grid
474 if (grid)
476 grConstantColorValue (COL_GRID);
478 float scale_y = (256.0f * scy) / (float)rdp.cache[debug.tmu][debug.tex_sel].height;
479 for (int y=0; y<=(int)rdp.cache[debug.tmu][debug.tex_sel].height; y++)
481 float y_val = SY(221.0f+y*scale_y);
482 VERTEX vh[2] = {
483 { SX(704.0f), y_val, 1, 1 },
484 { SX(704.0f+255.0f*scx), y_val, 1, 1 } };
485 grDrawLine (&vh[0], &vh[1]);
488 float scale_x = (256.0f * scx) / (float)rdp.cache[debug.tmu][debug.tex_sel].width;
489 for (int x=0; x<=(int)rdp.cache[debug.tmu][debug.tex_sel].width; x++)
491 float x_val = SX(704.0f+x*scale_x);
492 VERTEX vv[2] = {
493 { x_val, SX(221.0f), 1, 1 },
494 { x_val, SX(221.0f+256.0f*scy), 1, 1 } };
495 grDrawLine (&vv[0], &vv[1]);
500 grTexCombine (GR_TMU0,
501 GR_COMBINE_FUNCTION_LOCAL,
502 GR_COMBINE_FACTOR_NONE,
503 GR_COMBINE_FUNCTION_LOCAL,
504 GR_COMBINE_FACTOR_NONE,
505 FXFALSE,
506 FXFALSE);
508 grColorCombine (GR_COMBINE_FUNCTION_LOCAL,
509 GR_COMBINE_FACTOR_NONE,
510 GR_COMBINE_LOCAL_CONSTANT,
511 GR_COMBINE_OTHER_NONE,
512 FXFALSE);
514 grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
515 GR_COMBINE_FACTOR_ONE,
516 GR_COMBINE_LOCAL_NONE,
517 GR_COMBINE_OTHER_TEXTURE,
518 FXFALSE);
520 grConstantColorValue (0xFFFFFF00);
522 // Output the information about the selected triangle
523 grTexSource(GR_TMU0, // Text
524 grTexMinAddress(debug.tmu)+ offset_font,
525 GR_MIPMAPLEVELMASK_BOTH,
526 &fontTex);
528 static char *cycle_mode_s[4] = { "1 cycle (0)", "2 cycle (1)", "copy (2)", "fill (3)" };
530 #define OUTPUT(fmt,other) output(642,(float)i,1,fmt,other); i-=16;
531 #define OUTPUT1(fmt,other,other1) output(642,(float)i,1,fmt,other,other1); i-=16;
532 #define OUTPUT_(fmt,cc) COL_SEL(cc); x=642; output(x,(float)i,1,fmt,0); x+=8*(strlen(fmt)+1)
533 #define _OUTPUT(fmt,cc) COL_SEL(cc); output(x,(float)i,1,fmt,0); x+=8*(strlen(fmt)+1)
534 i = 740;
535 float x;
536 if (debug.page == PAGE_GENERAL && debug.tri_sel)
538 COL_CATEGORY();
539 OUTPUT ("GENERAL (page 1):",0);
540 COL_TEXT();
541 OUTPUT ("tri #%d", debug.tri_sel->tri_n);
542 OUTPUT ("type: %s", tri_type[debug.tri_sel->type]);
543 OUTPUT ("geom: 0x%08lx", debug.tri_sel->geom_mode);
544 OUTPUT ("othermode_h: 0x%08lx", debug.tri_sel->othermode_h);
545 OUTPUT ("othermode_l: 0x%08lx", debug.tri_sel->othermode_l);
546 OUTPUT ("flags: 0x%08lx", debug.tri_sel->flags);
547 OUTPUT ("",0);
548 COL_CATEGORY();
549 OUTPUT ("COMBINE:",0);
550 COL_TEXT();
551 OUTPUT ("cycle_mode: %s", cycle_mode_s[debug.tri_sel->cycle_mode]);
552 OUTPUT ("cycle1: 0x%08lx", debug.tri_sel->cycle1);
553 OUTPUT ("cycle2: 0x%08lx", debug.tri_sel->cycle2);
554 if (debug.tri_sel->uncombined & 1)
555 COL_UCC();
556 else
557 COL_CC();
558 OUTPUT ("a0: %s", Mode0[(debug.tri_sel->cycle1)&0x0000000F]);
559 OUTPUT ("b0: %s", Mode1[(debug.tri_sel->cycle1>>4)&0x0000000F]);
560 OUTPUT ("c0: %s", Mode2[(debug.tri_sel->cycle1>>8)&0x0000001F]);
561 OUTPUT ("d0: %s", Mode3[(debug.tri_sel->cycle1>>13)&0x00000007]);
562 if (debug.tri_sel->uncombined & 2)
563 COL_UAC();
564 else
565 COL_AC();
566 OUTPUT ("Aa0: %s", Alpha0[(debug.tri_sel->cycle1>>16)&0x00000007]);
567 OUTPUT ("Ab0: %s", Alpha1[(debug.tri_sel->cycle1>>19)&0x00000007]);
568 OUTPUT ("Ac0: %s", Alpha2[(debug.tri_sel->cycle1>>22)&0x00000007]);
569 OUTPUT ("Ad0: %s", Alpha3[(debug.tri_sel->cycle1>>25)&0x00000007]);
570 if (debug.tri_sel->uncombined & 1)
571 COL_UCC();
572 else
573 COL_CC();
574 OUTPUT ("a1: %s", Mode0[(debug.tri_sel->cycle2)&0x0000000F]);
575 OUTPUT ("b1: %s", Mode1[(debug.tri_sel->cycle2>>4)&0x0000000F]);
576 OUTPUT ("c1: %s", Mode2[(debug.tri_sel->cycle2>>8)&0x0000001F]);
577 OUTPUT ("d1: %s", Mode3[(debug.tri_sel->cycle2>>13)&0x00000007]);
578 if (debug.tri_sel->uncombined & 2)
579 COL_UAC();
580 else
581 COL_AC();
582 OUTPUT ("Aa1: %s", Alpha0[(debug.tri_sel->cycle2>>16)&0x00000007]);
583 OUTPUT ("Ab1: %s", Alpha1[(debug.tri_sel->cycle2>>19)&0x00000007]);
584 OUTPUT ("Ac1: %s", Alpha2[(debug.tri_sel->cycle2>>22)&0x00000007]);
585 OUTPUT ("Ad1: %s", Alpha3[(debug.tri_sel->cycle2>>25)&0x00000007]);
587 if ((debug.page == PAGE_TEX1 || debug.page == PAGE_TEX2) && debug.tri_sel)
589 COL_CATEGORY ();
590 OUTPUT1 ("TEXTURE %d (page %d):", debug.page-PAGE_TEX1, 2+debug.page-PAGE_TEX1);
591 COL_TEXT();
592 int tmu = debug.page - PAGE_TEX1;
593 OUTPUT1 ("cur cache: %d,%d", debug.tri_sel->t[tmu].cur_cache[tmu]&0x0F, debug.tri_sel->t[tmu].cur_cache[tmu]>>4);
594 OUTPUT ("tex_size: %d", debug.tri_sel->t[tmu].size);
595 OUTPUT ("tex_format: %d", debug.tri_sel->t[tmu].format);
596 OUTPUT ("width: %d", debug.tri_sel->t[tmu].width);
597 OUTPUT ("height: %d", debug.tri_sel->t[tmu].height);
598 OUTPUT ("palette: %d", debug.tri_sel->t[tmu].palette);
599 OUTPUT ("clamp_s: %d", debug.tri_sel->t[tmu].clamp_s);
600 OUTPUT ("clamp_t: %d", debug.tri_sel->t[tmu].clamp_t);
601 OUTPUT ("mirror_s: %d", debug.tri_sel->t[tmu].mirror_s);
602 OUTPUT ("mirror_t: %d", debug.tri_sel->t[tmu].mirror_t);
603 OUTPUT ("mask_s: %d", debug.tri_sel->t[tmu].mask_s);
604 OUTPUT ("mask_t: %d", debug.tri_sel->t[tmu].mask_t);
605 OUTPUT ("shift_s: %d", debug.tri_sel->t[tmu].shift_s);
606 OUTPUT ("shift_t: %d", debug.tri_sel->t[tmu].shift_t);
607 OUTPUT ("ul_s: %d", debug.tri_sel->t[tmu].ul_s);
608 OUTPUT ("ul_t: %d", debug.tri_sel->t[tmu].ul_t);
609 OUTPUT ("lr_s: %d", debug.tri_sel->t[tmu].lr_s);
610 OUTPUT ("lr_t: %d", debug.tri_sel->t[tmu].lr_t);
611 OUTPUT ("t_ul_s: %d", debug.tri_sel->t[tmu].t_ul_s);
612 OUTPUT ("t_ul_t: %d", debug.tri_sel->t[tmu].t_ul_t);
613 OUTPUT ("t_lr_s: %d", debug.tri_sel->t[tmu].t_lr_s);
614 OUTPUT ("t_lr_t: %d", debug.tri_sel->t[tmu].t_lr_t);
615 OUTPUT ("scale_s: %f", debug.tri_sel->t[tmu].scale_s);
616 OUTPUT ("scale_t: %f", debug.tri_sel->t[tmu].scale_t);
617 OUTPUT ("s_mode: %s", str_cm[((debug.tri_sel->t[tmu].clamp_s << 1) | debug.tri_sel->t[tmu].mirror_s)&3]);
618 OUTPUT ("t_mode: %s", str_cm[((debug.tri_sel->t[tmu].clamp_t << 1) | debug.tri_sel->t[tmu].mirror_t)&3]);
620 if (debug.page == PAGE_COLORS && debug.tri_sel)
622 COL_CATEGORY();
623 OUTPUT ("COLORS (page 4)", 0);
624 COL_TEXT();
625 OUTPUT ("fill: %08lx", debug.tri_sel->fill_color);
626 OUTPUT ("prim: %08lx", debug.tri_sel->prim_color);
627 OUTPUT ("blend: %08lx", debug.tri_sel->blend_color);
628 OUTPUT ("env: %08lx", debug.tri_sel->env_color);
629 OUTPUT ("fog: %08lx", debug.tri_sel->fog_color);
630 OUTPUT ("prim_lodmin: %d", debug.tri_sel->prim_lodmin);
631 OUTPUT ("prim_lodfrac: %d", debug.tri_sel->prim_lodfrac);
633 if (debug.page == PAGE_FBL && debug.tri_sel)
635 COL_CATEGORY();
636 OUTPUT ("BLENDER", 0);
637 COL_TEXT();
638 OUTPUT ("fbl_a0: %s", FBLa[(debug.tri_sel->othermode_l>>30)&0x3]);
639 OUTPUT ("fbl_b0: %s", FBLb[(debug.tri_sel->othermode_l>>26)&0x3]);
640 OUTPUT ("fbl_c0: %s", FBLc[(debug.tri_sel->othermode_l>>22)&0x3]);
641 OUTPUT ("fbl_d0: %s", FBLd[(debug.tri_sel->othermode_l>>18)&0x3]);
642 OUTPUT ("fbl_a1: %s", FBLa[(debug.tri_sel->othermode_l>>28)&0x3]);
643 OUTPUT ("fbl_b1: %s", FBLb[(debug.tri_sel->othermode_l>>24)&0x3]);
644 OUTPUT ("fbl_c1: %s", FBLc[(debug.tri_sel->othermode_l>>20)&0x3]);
645 OUTPUT ("fbl_d1: %s", FBLd[(debug.tri_sel->othermode_l>>16)&0x3]);
646 OUTPUT ("", 0);
647 OUTPUT ("fbl: %08lx", debug.tri_sel->othermode_l&0xFFFF0000);
648 OUTPUT ("fbl #1: %08lx", debug.tri_sel->othermode_l&0xCCCC0000);
649 OUTPUT ("fbl #2: %08lx", debug.tri_sel->othermode_l&0x33330000);
651 if (debug.page == PAGE_OTHERMODE_L && debug.tri_sel)
653 DWORD othermode_l = debug.tri_sel->othermode_l;
654 COL_CATEGORY ();
655 OUTPUT ("OTHERMODE_L: %08lx", othermode_l);
656 OUTPUT_ ("AC_NONE", (othermode_l & 3) == 0);
657 _OUTPUT ("AC_THRESHOLD", (othermode_l & 3) == 1);
658 _OUTPUT ("AC_DITHER", (othermode_l & 3) == 3);
659 i -= 16;
660 OUTPUT_ ("ZS_PIXEL", !(othermode_l & 4));
661 _OUTPUT ("ZS_PRIM", (othermode_l & 4));
662 i -= 32;
663 COL_CATEGORY ();
664 OUTPUT ("RENDERMODE: %08lx", othermode_l);
665 OUTPUT_ ("AA_EN", othermode_l & 0x08);
666 i -= 16;
667 OUTPUT_ ("Z_CMP", othermode_l & 0x10);
668 i -= 16;
669 OUTPUT_ ("Z_UPD", othermode_l & 0x20);
670 i -= 16;
671 OUTPUT_ ("IM_RD", othermode_l & 0x40);
672 i -= 16;
673 OUTPUT_ ("CLR_ON_CVG", othermode_l & 0x80);
674 i -= 16;
675 OUTPUT_ ("CVG_DST_CLAMP", (othermode_l & 0x300) == 0x000);
676 _OUTPUT ("CVG_DST_WRAP", (othermode_l & 0x300) == 0x100);
677 _OUTPUT (".._FULL", (othermode_l & 0x300) == 0x200);
678 _OUTPUT (".._SAVE", (othermode_l & 0x300) == 0x300);
679 i -= 16;
680 OUTPUT_ ("ZM_OPA", (othermode_l & 0xC00) == 0x000);
681 _OUTPUT ("ZM_INTER", (othermode_l & 0xC00) == 0x400);
682 _OUTPUT ("ZM_XLU", (othermode_l & 0xC00) == 0x800);
683 _OUTPUT ("ZM_DEC", (othermode_l & 0xC00) == 0xC00);
684 i -= 16;
685 OUTPUT_ ("CVG_X_ALPHA", othermode_l & 0x1000);
686 i -= 16;
687 OUTPUT_ ("ALPHA_CVG_SEL", othermode_l & 0x2000);
688 i -= 16;
689 OUTPUT_ ("FORCE_BL", othermode_l & 0x4000);
691 if (debug.page == PAGE_OTHERMODE_H && debug.tri_sel)
693 DWORD othermode_h = debug.tri_sel->othermode_h;
694 COL_CATEGORY ();
695 OUTPUT ("OTHERMODE_H: %08lx", othermode_h);
696 OUTPUT_ ("CK_NONE", (othermode_h & 0x100) == 0);
697 _OUTPUT ("CK_KEY", (othermode_h & 0x100) == 1);
698 i -= 16;
699 OUTPUT_ ("TC_CONV", (othermode_h & 0xE00) == 0x200);
700 _OUTPUT ("TC_FILTCONV", (othermode_h & 0xE00) == 0xA00);
701 _OUTPUT ("TC_FILT", (othermode_h & 0xE00) == 0xC00);
702 i -= 16;
703 OUTPUT_ ("TF_POINT", (othermode_h & 0x3000) == 0x0000);
704 _OUTPUT ("TF_AVERAGE", (othermode_h & 0x3000) == 0x3000);
705 _OUTPUT ("TF_BILERP", (othermode_h & 0x3000) == 0x2000);
706 i -= 16;
707 OUTPUT_ ("TT_NONE", (othermode_h & 0xC000) == 0x0000);
708 _OUTPUT ("TT_RGBA16", (othermode_h & 0xC000) == 0x8000);
709 _OUTPUT ("TT_IA16", (othermode_h & 0xC000) == 0xC000);
710 i -= 16;
711 OUTPUT_ ("TL_TILE", (othermode_h & 0x10000) == 0x00000);
712 _OUTPUT ("TL_LOD", (othermode_h & 0x10000) == 0x10000);
713 i -= 16;
714 OUTPUT_ ("TD_CLAMP", (othermode_h & 0x60000) == 0x00000);
715 _OUTPUT ("TD_SHARPEN", (othermode_h & 0x60000) == 0x20000);
716 _OUTPUT ("TD_DETAIL", (othermode_h & 0x60000) == 0x40000);
717 i -= 16;
718 OUTPUT_ ("TP_NONE", (othermode_h & 0x80000) == 0x00000);
719 _OUTPUT ("TP_PERSP", (othermode_h & 0x80000) == 0x80000);
720 i -= 16;
721 OUTPUT_ ("1CYCLE", (othermode_h & 0x300000) == 0x000000);
722 _OUTPUT ("2CYCLE", (othermode_h & 0x300000) == 0x100000);
723 _OUTPUT ("COPY", (othermode_h & 0x300000) == 0x200000);
724 _OUTPUT ("FILL", (othermode_h & 0x300000) == 0x300000);
725 i -= 16;
726 OUTPUT_ ("PM_1PRIM", (othermode_h & 0x400000) == 0x000000);
727 _OUTPUT ("PM_NPRIM", (othermode_h & 0x400000) == 0x400000);
729 if (debug.page == PAGE_TEXELS && debug.tri_sel)
731 // change these to output whatever you need, ou for triangles, or u0 for texrects
732 COL_TEXT();
733 OUTPUT ("n: %d", debug.tri_sel->nv);
734 OUTPUT ("",0);
735 for (j=0; j<debug.tri_sel->nv; j++)
737 OUTPUT1 ("v[%d].s0: %f", j, debug.tri_sel->v[j].ou);
738 OUTPUT1 ("v[%d].t0: %f", j, debug.tri_sel->v[j].ov);
740 OUTPUT ("",0);
741 for (j=0; j<debug.tri_sel->nv; j++)
743 OUTPUT1 ("v[%d].s1: %f", j, debug.tri_sel->v[j].u0);
744 OUTPUT1 ("v[%d].t1: %f", j, debug.tri_sel->v[j].v0);
747 if (debug.page == PAGE_COORDS && debug.tri_sel)
749 COL_TEXT();
750 OUTPUT ("n: %d", debug.tri_sel->nv);
751 for (j=0; j<debug.tri_sel->nv; j++)
753 OUTPUT1 ("v[%d].x: %f", j, debug.tri_sel->v[j].x);
754 OUTPUT1 ("v[%d].y: %f", j, debug.tri_sel->v[j].y);
755 OUTPUT1 ("v[%d].z: %f", j, debug.tri_sel->v[j].z);
756 OUTPUT1 ("v[%d].w: %f", j, debug.tri_sel->v[j].w);
757 OUTPUT1 ("v[%d].f: %f", j, 1.0f/debug.tri_sel->v[j].f);
758 OUTPUT1 ("v[%d].r: %d", j, debug.tri_sel->v[j].r);
759 OUTPUT1 ("v[%d].g: %d", j, debug.tri_sel->v[j].g);
760 OUTPUT1 ("v[%d].b: %d", j, debug.tri_sel->v[j].b);
761 OUTPUT1 ("v[%d].a: %d", j, debug.tri_sel->v[j].a);
764 if (debug.page == PAGE_TEX_INFO && debug.tex_sel < (DWORD)rdp.n_cached[debug.tmu])
766 COL_CATEGORY();
767 OUTPUT ("CACHE (page 0)", 0);
768 COL_TEXT();
769 //OUTPUT ("t_mem: %08lx", rdp.cache[0][debug.tex_sel].t_mem);
770 //OUTPUT ("crc: %08lx", rdp.cache[0][debug.tex_sel].crc);
771 OUTPUT ("addr: %08lx", rdp.cache[debug.tmu][debug.tex_sel].addr);
772 OUTPUT ("scale_x: %f", rdp.cache[debug.tmu][debug.tex_sel].scale_x);
773 OUTPUT ("scale_y: %f", rdp.cache[debug.tmu][debug.tex_sel].scale_y);
774 OUTPUT ("tmem_addr: %08lx", rdp.cache[debug.tmu][debug.tex_sel].tmem_addr);
775 OUTPUT ("palette: %08lx", rdp.cache[debug.tmu][debug.tex_sel].palette);
776 OUTPUT ("set_by: %08lx", rdp.cache[debug.tmu][debug.tex_sel].set_by);
777 OUTPUT ("texrecting: %d", rdp.cache[debug.tmu][debug.tex_sel].texrecting);
779 OUTPUT ("mod: %08lx", rdp.cache[debug.tmu][debug.tex_sel].mod);
780 OUTPUT ("mod_col: %08lx", rdp.cache[debug.tmu][debug.tex_sel].mod_color);
781 OUTPUT ("mod_col1: %08lx", rdp.cache[debug.tmu][debug.tex_sel].mod_color1);
782 i=740;
783 output(800,(float)i,1,"width: %d", rdp.cache[debug.tmu][debug.tex_sel].width);
784 i-=16;
785 output(800,(float)i,1,"height: %d", rdp.cache[debug.tmu][debug.tex_sel].height);
786 i-=16;
787 output(800,(float)i,1,"format: %d", rdp.cache[debug.tmu][debug.tex_sel].format);
788 i-=16;
789 output(800,(float)i,1,"size: %d", rdp.cache[debug.tmu][debug.tex_sel].size);
790 i-=16;
791 output(800,(float)i,1,"crc: %08lx", rdp.cache[debug.tmu][debug.tex_sel].crc);
792 i-=16;
793 output(800,(float)i,1,"line: %d", rdp.cache[debug.tmu][debug.tex_sel].line);
794 i-=16;
795 output(800,(float)i,1,"mod_factor: %08lx", rdp.cache[debug.tmu][debug.tex_sel].mod_factor);
796 i-=32;
798 output(800,(float)i,1,"lod: %s", str_lod[rdp.cache[debug.tmu][debug.tex_sel].lod]);
799 i-=16;
800 output(800,(float)i,1,"aspect: %s", str_aspect[rdp.cache[debug.tmu][debug.tex_sel].aspect + 3]);
802 // debug_texture(debug.tmu, rdp.cache[debug.tmu][debug.tex_sel].addr, debug.tex_sel);
805 // Draw the vertex numbers
806 if (debug.tri_sel)
808 for (i=0; i<debug.tri_sel->nv; i++)
810 grConstantColorValue (0x000000FF);
811 output (debug.tri_sel->v[i].x+1, settings.scr_res_y-debug.tri_sel->v[i].y+1, 1,
812 "%d", i);
813 grConstantColorValue (0xFFFFFFFF);
814 output (debug.tri_sel->v[i].x, settings.scr_res_y-debug.tri_sel->v[i].y, 1,
815 "%d", i);
819 // Draw the cursor
820 debug_mouse ();
822 grBufferSwap (1);
825 END:
826 // Release all data
827 delete [] debug.screen;
828 TRI_INFO *tri;
829 for (tri=debug.tri_list; tri != debug.tri_last;)
831 TRI_INFO *tmp = tri;
832 tri = tri->pNext;
833 delete [] tmp->v;
834 delete tmp;
836 delete [] tri->v;
837 delete tri;
839 // Reset all values
840 debug.capture = 0;
841 debug.selected = SELECTED_TRI;
842 debug.screen = NULL;
843 debug.tri_list = NULL;
844 debug.tri_last = NULL;
845 debug.tri_sel = NULL;
846 debug.tex_sel = 0;
850 // debug_mouse - draws the debugger mouse
853 void debug_mouse ()
855 grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
856 GR_COMBINE_FACTOR_ONE,
857 GR_COMBINE_LOCAL_NONE,
858 GR_COMBINE_OTHER_TEXTURE,
859 FXFALSE);
861 grAlphaCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,
862 GR_COMBINE_FACTOR_ONE,
863 GR_COMBINE_LOCAL_NONE,
864 GR_COMBINE_OTHER_TEXTURE,
865 FXFALSE);
867 // Draw the cursor
868 POINT pt;
869 GetCursorPos (&pt);
870 float cx = (float)pt.x;
871 float cy = (float)pt.y;
873 VERTEX v[4] = {
874 { cx, cy, 1, 1, 0, 0, 0, 0, 0, 0, 0 },
875 { cx+32, cy, 1, 1, 255, 0, 0, 0, 0, 0, 0 },
876 { cx, cy+32, 1, 1, 0, 255, 0, 0, 0, 0, 0 },
877 { cx+32, cy+32, 1, 1, 255, 255, 0, 0, 0, 0, 0 } };
879 ConvertCoordsKeep (v, 4);
881 grTexSource(GR_TMU0,
882 grTexMinAddress(GR_TMU0) + offset_cursor,
883 GR_MIPMAPLEVELMASK_BOTH,
884 &cursorTex);
886 if (num_tmu >= 3)
887 grTexCombine (GR_TMU2,
888 GR_COMBINE_FUNCTION_NONE,
889 GR_COMBINE_FACTOR_NONE,
890 GR_COMBINE_FUNCTION_NONE,
891 GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
892 if (num_tmu >= 2)
893 grTexCombine (GR_TMU1,
894 GR_COMBINE_FUNCTION_NONE,
895 GR_COMBINE_FACTOR_NONE,
896 GR_COMBINE_FUNCTION_NONE,
897 GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
898 grTexCombine (GR_TMU0,
899 GR_COMBINE_FUNCTION_LOCAL,
900 GR_COMBINE_FACTOR_NONE,
901 GR_COMBINE_FUNCTION_LOCAL,
902 GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE);
904 grDrawTriangle (&v[0], &v[1], &v[2]);
905 grDrawTriangle (&v[1], &v[3], &v[2]);
909 // debug_keys - receives debugger key input
912 void debug_keys ()
914 if ((GetAsyncKeyState (VK_RIGHT) & 0x0001) && debug.tri_sel)
916 TRI_INFO *start = debug.tri_sel;
918 while (debug.tri_sel->pNext != start)
919 debug.tri_sel = debug.tri_sel->pNext;
922 if ((GetAsyncKeyState (VK_LEFT) & 0x0001) && debug.tri_sel)
923 debug.tri_sel = debug.tri_sel->pNext;
925 // Check for page changes
926 if (GetAsyncKeyState ('1') & 0x0001)
927 debug.page = PAGE_GENERAL;
928 if (GetAsyncKeyState ('2') & 0x0001)
929 debug.page = PAGE_TEX1;
930 if (GetAsyncKeyState ('3') & 0x0001)
931 debug.page = PAGE_TEX2;
932 if (GetAsyncKeyState ('4') & 0x0001)
933 debug.page = PAGE_COLORS;
934 if (GetAsyncKeyState ('5') & 0x0001)
935 debug.page = PAGE_FBL;
936 if (GetAsyncKeyState ('6') & 0x0001)
937 debug.page = PAGE_OTHERMODE_L;
938 if (GetAsyncKeyState ('7') & 0x0001)
939 debug.page = PAGE_OTHERMODE_H;
940 if (GetAsyncKeyState ('8') & 0x0001)
941 debug.page = PAGE_TEXELS;
942 if (GetAsyncKeyState ('9') & 0x0001)
943 debug.page = PAGE_COORDS;
944 if (GetAsyncKeyState ('0') & 0x0001)
945 debug.page = PAGE_TEX_INFO;
946 if (GetAsyncKeyState ('Q') & 0x0001)
947 debug.tmu = 0;
948 if (GetAsyncKeyState ('W') & 0x0001)
949 debug.tmu = 1;
951 if (GetAsyncKeyState ('G') & 0x0001)
952 grid = !grid;
954 // Go to texture
955 if (GetAsyncKeyState (VK_SPACE) & 0x0001)
957 int tile = -1;
958 if (debug.page == PAGE_TEX2)
959 tile = 1;
960 else
961 tile = 0;
962 if (tile != -1)
964 debug.tmu = debug.tri_sel->t[tile].tmu;
965 debug.tex_sel = debug.tri_sel->t[tile].cur_cache[debug.tmu];
966 debug.tex_scroll = (debug.tri_sel->t[tile].cur_cache[debug.tmu] >> 4) - 1;
970 // Go to triangle
971 if (GetAsyncKeyState (VK_LCONTROL) & 0x0001)
973 int count = rdp.debug_n - rdp.cache[debug.tmu][debug.tex_sel].uses - 1;
974 if (rdp.cache[debug.tmu][debug.tex_sel].last_used == frame_count)
976 TRI_INFO *t = debug.tri_list;
977 while (count && t) {
978 t = t->pNext;
979 count --;
981 debug.tri_sel = t;
983 else
984 debug.tri_sel = NULL;
987 if (GetAsyncKeyState ('A') & 0x0001)
988 debug.draw_mode = 0; // texture & texture alpha
989 if (GetAsyncKeyState ('S') & 0x0001)
990 debug.draw_mode = 1; // texture
991 if (GetAsyncKeyState ('D') & 0x0001)
992 debug.draw_mode = 2; // texture alpha
994 // Check for texture scrolling
995 if (GetAsyncKeyState (VK_DOWN) & 0x0001)
996 debug.tex_scroll ++;
997 if (GetAsyncKeyState (VK_UP) & 0x0001)
998 debug.tex_scroll --;
1000 #endif // _WIN32
1002 // output - output debugger text
1005 void output (float x, float y, BOOL scale, const char *fmt, ...)
1007 va_list ap;
1008 va_start(ap,fmt);
1009 vsprintf(out_buf, fmt, ap);
1010 va_end(ap);
1012 BYTE c,r;
1013 for (DWORD i=0; i<strlen(out_buf); i++)
1015 c = ((out_buf[i]-32) & 0x1F) * 8;//<< 3;
1016 r = (((out_buf[i]-32) & 0xE0) >> 5) * 16;//<< 4;
1017 VERTEX v[4] = { { SX(x), SY(768-y), 1, 1, (float)c, r+16.0f, 0, 0, {0, 0, 0, 0} },
1018 { SX(x+8), SY(768-y), 1, 1, c+8.0f, r+16.0f, 0, 0, {0, 0, 0, 0} },
1019 { SX(x), SY(768-y-16), 1, 1, (float)c, (float)r, 0, 0, {0, 0, 0, 0} },
1020 { SX(x+8), SY(768-y-16), 1, 1, c+8.0f, (float)r, 0, 0, {0, 0, 0, 0} } };
1021 if (!scale)
1023 v[0].x = x;
1024 v[0].y = y;
1025 v[1].x = x+8;
1026 v[1].y = y;
1027 v[2].x = x;
1028 v[2].y = y-16;
1029 v[3].x = x+8;
1030 v[3].y = y-16;
1033 ConvertCoordsKeep (v, 4);
1035 grDrawTriangle (&v[0], &v[1], &v[2]);
1036 grDrawTriangle (&v[1], &v[3], &v[2]);
1038 x+=8;