~ppsspp/ppsspp/ppsspp_1.3.0

« back to all changes in this revision

Viewing changes to GPU/GeDisasm.cpp

  • Committer: Sérgio Benjamim
  • Date: 2017-01-02 00:12:05 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20170102001205-cxbta9za203nmjwm
1.3.0 source (from ppsspp_1.3.0-r160.p5.l1762.a165.t83~56~ubuntu16.04.1.tar.xz).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2012- PPSSPP Project.
 
2
 
 
3
// This program is free software: you can redistribute it and/or modify
 
4
// it under the terms of the GNU General Public License as published by
 
5
// the Free Software Foundation, version 2.0 or later versions.
 
6
 
 
7
// This program is distributed in the hope that it will be useful,
 
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
// GNU General Public License 2.0 for more details.
 
11
 
 
12
// A copy of the GPL 2.0 should have been included with the program.
 
13
// If not, see http://www.gnu.org/licenses/
 
14
 
 
15
// Official git repository and contact information can be found at
 
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
 
17
 
 
18
#include "Core/MemMap.h"
 
19
 
 
20
#include "ge_constants.h"
 
21
#include "GPU/GPU.h"
 
22
#include "GPU/GPUState.h"
 
23
 
 
24
void GeDescribeVertexType(u32 op, char *buffer, int len) {
 
25
        bool through = (op & GE_VTYPE_THROUGH_MASK) == GE_VTYPE_THROUGH;
 
26
        int tc = (op & GE_VTYPE_TC_MASK) >> GE_VTYPE_TC_SHIFT;
 
27
        int col = (op & GE_VTYPE_COL_MASK) >> GE_VTYPE_COL_SHIFT;
 
28
        int nrm = (op & GE_VTYPE_NRM_MASK) >> GE_VTYPE_NRM_SHIFT;
 
29
        int pos = (op & GE_VTYPE_POS_MASK) >> GE_VTYPE_POS_SHIFT;
 
30
        int weight = (op & GE_VTYPE_WEIGHT_MASK) >> GE_VTYPE_WEIGHT_SHIFT;
 
31
        int weightCount = ((op & GE_VTYPE_WEIGHTCOUNT_MASK) >> GE_VTYPE_WEIGHTCOUNT_SHIFT) + 1;
 
32
        int morphCount = (op & GE_VTYPE_MORPHCOUNT_MASK) >> GE_VTYPE_MORPHCOUNT_SHIFT;
 
33
        int idx = (op & GE_VTYPE_IDX_MASK) >> GE_VTYPE_IDX_SHIFT;
 
34
 
 
35
        static const char *colorNames[] = {
 
36
                NULL,
 
37
                "unsupported1",
 
38
                "unsupported2",
 
39
                "unsupported3",
 
40
                "BGR 565",
 
41
                "ABGR 1555",
 
42
                "ABGR 4444",
 
43
                "ABGR 8888",
 
44
        };
 
45
        static const char *typeNames[] = {
 
46
                NULL,
 
47
                "u8",
 
48
                "u16",
 
49
                "float",
 
50
        };
 
51
        static const char *typeNamesI[] = {
 
52
                NULL,
 
53
                "u8",
 
54
                "u16",
 
55
                "u32",
 
56
        };
 
57
        static const char *typeNamesS[] = {
 
58
                NULL,
 
59
                "s8",
 
60
                "s16",
 
61
                "float",
 
62
        };
 
63
 
 
64
        char *w = buffer, *end = buffer + len;
 
65
        if (through)
 
66
                w += snprintf(w, end - w, "through, ");
 
67
        if (typeNames[tc] && w < end)
 
68
                w += snprintf(w, end - w, "%s texcoords, ", typeNames[tc]);
 
69
        if (colorNames[col] && w < end)
 
70
                w += snprintf(w, end - w, "%s colors, ", colorNames[col]);
 
71
        if (typeNames[nrm] && w < end)
 
72
                w += snprintf(w, end - w, "%s normals, ", typeNamesS[nrm]);
 
73
        if (typeNames[pos] && w < end)
 
74
                w += snprintf(w, end - w, "%s positions, ", typeNamesS[pos]);
 
75
        if (typeNames[weight] && w < end)
 
76
                w += snprintf(w, end - w, "%s weights (%d), ", typeNames[weight], weightCount);
 
77
        else if (weightCount > 1 && w < end)
 
78
                w += snprintf(w, end - w, "unknown weights (%d), ", weightCount);
 
79
        if (morphCount > 0 && w < end)
 
80
                w += snprintf(w, end - w, "%d morphs, ", morphCount);
 
81
        if (typeNamesI[idx] && w < end)
 
82
                w += snprintf(w, end - w, "%s indexes, ", typeNamesI[idx]);
 
83
 
 
84
        if (w < buffer + 2)
 
85
                snprintf(buffer, len, "none");
 
86
        // Otherwise, get rid of the pesky trailing comma.
 
87
        else if (w < end)
 
88
                w[-2] = '\0';
 
89
}
 
90
 
 
91
void GeDisassembleOp(u32 pc, u32 op, u32 prev, char *buffer, int bufsize) {
 
92
        u32 cmd = op >> 24;
 
93
        u32 data = op & 0xFFFFFF;
 
94
 
 
95
        // Handle control and drawing commands here directly. The others we delegate.
 
96
        switch (cmd)
 
97
        {
 
98
        case GE_CMD_NOP:
 
99
                if (data != 0)
 
100
                        snprintf(buffer, bufsize, "NOP: data= %06x", data);
 
101
                else
 
102
                        snprintf(buffer, bufsize, "NOP");
 
103
                break;
 
104
 
 
105
        case GE_CMD_BASE:
 
106
                snprintf(buffer, bufsize, "BASE: %06x", data);
 
107
                break;
 
108
 
 
109
        case GE_CMD_VADDR:
 
110
                snprintf(buffer, bufsize, "VADDR: %06x => %08x", data, gstate_c.getRelativeAddress(data));
 
111
                break;
 
112
 
 
113
        case GE_CMD_IADDR:
 
114
                snprintf(buffer, bufsize, "IADDR: %06x => %08x", data, gstate_c.getRelativeAddress(data));
 
115
                break;
 
116
 
 
117
        case GE_CMD_PRIM:
 
118
                {
 
119
                        u32 count = data & 0xFFFF;
 
120
                        u32 type = (data >> 16) & 7;
 
121
                        static const char* types[8] = {
 
122
                                "POINTS",
 
123
                                "LINES",
 
124
                                "LINE_STRIP",
 
125
                                "TRIANGLES",
 
126
                                "TRIANGLE_STRIP",
 
127
                                "TRIANGLE_FAN",
 
128
                                "RECTANGLES",
 
129
                                "CONTINUE_PREVIOUS",
 
130
                        };
 
131
                        if (gstate.vertType & GE_VTYPE_IDX_MASK)
 
132
                                snprintf(buffer, bufsize, "DRAW PRIM %s: count= %i vaddr= %08x, iaddr= %08x", type < 7 ? types[type] : "INVALID", count, gstate_c.vertexAddr, gstate_c.indexAddr);
 
133
                        else
 
134
                                snprintf(buffer, bufsize, "DRAW PRIM %s: count= %i vaddr= %08x", type < 7 ? types[type] : "INVALID", count, gstate_c.vertexAddr);
 
135
                }
 
136
                break;
 
137
 
 
138
        // The arrow and other rotary items in Puzbob are bezier patches, strangely enough.
 
139
        case GE_CMD_BEZIER:
 
140
                {
 
141
                        int bz_ucount = data & 0xFF;
 
142
                        int bz_vcount = (data >> 8) & 0xFF;
 
143
                        if (data & 0xFF0000)
 
144
                                snprintf(buffer, bufsize, "DRAW BEZIER: %i x %i (extra %x)", bz_ucount, bz_vcount, data >> 16);
 
145
                        else
 
146
                                snprintf(buffer, bufsize, "DRAW BEZIER: %i x %i", bz_ucount, bz_vcount);
 
147
                }
 
148
                break;
 
149
 
 
150
        case GE_CMD_SPLINE:
 
151
                {
 
152
                        int sp_ucount = data & 0xFF;
 
153
                        int sp_vcount = (data >> 8) & 0xFF;
 
154
                        int sp_utype = (data >> 16) & 0x3;
 
155
                        int sp_vtype = (data >> 18) & 0x3;
 
156
                        if (data & 0xF00000)
 
157
                                snprintf(buffer, bufsize, "DRAW SPLINE: %i x %i, %i x %i (extra %x)", sp_ucount, sp_vcount, sp_utype, sp_vtype, data >> 20);
 
158
                        else
 
159
                                snprintf(buffer, bufsize, "DRAW SPLINE: %i x %i, %i x %i", sp_ucount, sp_vcount, sp_utype, sp_vtype);
 
160
                }
 
161
                break;
 
162
 
 
163
        case GE_CMD_JUMP:
 
164
                {
 
165
                        u32 target = (((gstate.base & 0x00FF0000) << 8) | (op & 0xFFFFFC)) & 0x0FFFFFFF;
 
166
                        snprintf(buffer, bufsize, "JUMP: %08x to %08x", pc, target);
 
167
                }
 
168
                break;
 
169
 
 
170
        case GE_CMD_CALL:
 
171
                {
 
172
                        u32 retval = pc + 4;
 
173
                        u32 target = gstate_c.getRelativeAddress(op & 0xFFFFFF);
 
174
                        snprintf(buffer, bufsize, "CALL: %08x to %08x, ret=%08x", pc, target, retval);
 
175
                }
 
176
                break;
 
177
 
 
178
        case GE_CMD_RET:
 
179
                if (data)
 
180
                        snprintf(buffer, bufsize, "RET: data= %06x", data);
 
181
                else
 
182
                        snprintf(buffer, bufsize, "RET");
 
183
                break;
 
184
 
 
185
        case GE_CMD_SIGNAL:
 
186
                snprintf(buffer, bufsize, "SIGNAL %06x", data);
 
187
                break;
 
188
 
 
189
        case GE_CMD_FINISH:
 
190
                snprintf(buffer, bufsize, "FINISH %06x", data);
 
191
                break;
 
192
 
 
193
        case GE_CMD_END:
 
194
                switch (prev >> 24)
 
195
                {
 
196
                case GE_CMD_SIGNAL:
 
197
                        {
 
198
                                snprintf(buffer, bufsize, "END - ");
 
199
                                // TODO: see http://code.google.com/p/jpcsp/source/detail?r=2935#
 
200
                                int behaviour = (prev >> 16) & 0xFF;
 
201
                                int signal = prev & 0xFFFF;
 
202
                                int enddata = data & 0xFFFFFF;
 
203
                                // We should probably defer to sceGe here, no sense in implementing this stuff in every GPU
 
204
                                switch (behaviour) {
 
205
                                case 1:
 
206
                                        snprintf(buffer, bufsize, "Signal with wait. signal/end: %04x %04x", signal, enddata);
 
207
                                        break;
 
208
                                case 2:
 
209
                                        snprintf(buffer, bufsize, "Signal without wait. signal/end: %04x %04x", signal, enddata);
 
210
                                        break;
 
211
                                case 3:
 
212
                                        snprintf(buffer, bufsize, "Signal with pause. signal/end: %04x %04x", signal, enddata);
 
213
                                        break;
 
214
                                case 8:
 
215
                                        snprintf(buffer, bufsize, "Signal with sync. signal/end: %04x %04x", signal, enddata);
 
216
                                        break;
 
217
                                case 0x10:
 
218
                                        snprintf(buffer, bufsize, "Signal with jump. signal/end: %04x %04x", signal, enddata);
 
219
                                        break;
 
220
                                case 0x11:
 
221
                                        snprintf(buffer, bufsize, "Signal with call. signal/end: %04x %04x", signal, enddata);
 
222
                                        break;
 
223
                                case 0x12:
 
224
                                        snprintf(buffer, bufsize, "Signal with return. signal/end: %04x %04x", signal, enddata);
 
225
                                        break;
 
226
                                default:
 
227
                                        snprintf(buffer, bufsize, "UNKNOWN Signal UNIMPLEMENTED %i! signal/end: %04x %04x", behaviour, signal, enddata);
 
228
                                        break;
 
229
                                }
 
230
                        }
 
231
                        break;
 
232
                case GE_CMD_FINISH:
 
233
                        if (data)
 
234
                                snprintf(buffer, bufsize, "END: data= %06x", data);
 
235
                        else
 
236
                                snprintf(buffer, bufsize, "END");
 
237
                        break;
 
238
                default:
 
239
                        snprintf(buffer, bufsize, "END: %06x, not finished (%08x)", data, prev);
 
240
                        break;
 
241
                }
 
242
                break;
 
243
 
 
244
        case GE_CMD_BJUMP:
 
245
                {
 
246
                        u32 target = (((gstate.base & 0x00FF0000) << 8) | (op & 0xFFFFFC)) & 0x0FFFFFFF;
 
247
                        snprintf(buffer, bufsize, "BBOX_JUMP: target= %08x", target);
 
248
                }
 
249
                break;
 
250
 
 
251
        case GE_CMD_BOUNDINGBOX:
 
252
                snprintf(buffer, bufsize, "BBOX_TEST: %06x", data);
 
253
                break;
 
254
 
 
255
        case GE_CMD_ORIGIN:
 
256
                snprintf(buffer, bufsize, "ORIGIN: %06x", data);
 
257
                break;
 
258
 
 
259
        case GE_CMD_VERTEXTYPE:
 
260
                {
 
261
                        int len = snprintf(buffer, bufsize, "SetVertexType: ");
 
262
                        GeDescribeVertexType(op, buffer + len, bufsize - len);
 
263
                }
 
264
                break;
 
265
 
 
266
        case GE_CMD_OFFSETADDR:
 
267
                snprintf(buffer, bufsize, "OffsetAddr: %06x", data);
 
268
                break;
 
269
 
 
270
        case GE_CMD_REGION1:
 
271
                {
 
272
                        int x1 = data & 0x3ff;
 
273
                        int y1 = data >> 10;
 
274
                        if (data & 0xF00000)
 
275
                                snprintf(buffer, bufsize, "Region TL: %d %d (extra %x)", x1, y1, data >> 20);
 
276
                        else
 
277
                                snprintf(buffer, bufsize, "Region TL: %d %d", x1, y1);
 
278
                }
 
279
                break;
 
280
 
 
281
        case GE_CMD_REGION2:
 
282
                {
 
283
                        int x2 = data & 0x3ff;
 
284
                        int y2 = data >> 10;
 
285
                        if (data & 0xF00000)
 
286
                                snprintf(buffer, bufsize, "Region BR: %d %d (extra %x)", x2, y2, data >> 20);
 
287
                        else
 
288
                                snprintf(buffer, bufsize, "Region BR: %d %d", x2, y2);
 
289
                }
 
290
                break;
 
291
 
 
292
        case GE_CMD_CLIPENABLE:
 
293
                snprintf(buffer, bufsize, "Clip enable: %i", data);
 
294
                break;
 
295
 
 
296
        case GE_CMD_CULLFACEENABLE:
 
297
                snprintf(buffer, bufsize, "CullFace enable: %i", data);
 
298
                break;
 
299
 
 
300
        case GE_CMD_TEXTUREMAPENABLE:
 
301
                snprintf(buffer, bufsize, "Texture map enable: %i", data);
 
302
                break;
 
303
 
 
304
        case GE_CMD_LIGHTINGENABLE:
 
305
                snprintf(buffer, bufsize, "Lighting enable: %i", data);
 
306
                break;
 
307
 
 
308
        case GE_CMD_FOGENABLE:
 
309
                snprintf(buffer, bufsize, "Fog enable: %i", data);
 
310
                break;
 
311
 
 
312
        case GE_CMD_DITHERENABLE:
 
313
                snprintf(buffer, bufsize, "Dither enable: %i", data);
 
314
                break;
 
315
 
 
316
        case GE_CMD_OFFSETX:
 
317
                snprintf(buffer, bufsize, "Offset X: %i", data);
 
318
                break;
 
319
 
 
320
        case GE_CMD_OFFSETY:
 
321
                snprintf(buffer, bufsize, "Offset Y: %i", data);
 
322
                break;
 
323
 
 
324
        case GE_CMD_TEXSCALEU:
 
325
                snprintf(buffer, bufsize, "Texture U scale: %f", getFloat24(data));
 
326
                break;
 
327
 
 
328
        case GE_CMD_TEXSCALEV:
 
329
                snprintf(buffer, bufsize, "Texture V scale: %f", getFloat24(data));
 
330
                break;
 
331
 
 
332
        case GE_CMD_TEXOFFSETU:
 
333
                snprintf(buffer, bufsize, "Texture U offset: %f", getFloat24(data));
 
334
                break;
 
335
 
 
336
        case GE_CMD_TEXOFFSETV:
 
337
                snprintf(buffer, bufsize, "Texture V offset: %f", getFloat24(data));
 
338
                break;
 
339
 
 
340
        case GE_CMD_SCISSOR1:
 
341
                {
 
342
                        int x1 = data & 0x3ff;
 
343
                        int y1 = data >> 10;
 
344
                        if (data & 0xF00000)
 
345
                                snprintf(buffer, bufsize, "Scissor TL: %i, %i (extra %x)", x1, y1, data >> 20);
 
346
                        else
 
347
                                snprintf(buffer, bufsize, "Scissor TL: %i, %i", x1, y1);
 
348
                }
 
349
                break;
 
350
        case GE_CMD_SCISSOR2:
 
351
                {
 
352
                        int x2 = data & 0x3ff;
 
353
                        int y2 = data >> 10;
 
354
                        if (data & 0xF00000)
 
355
                                snprintf(buffer, bufsize, "Scissor BR: %i, %i (extra %x)", x2, y2, data >> 20);
 
356
                        else
 
357
                                snprintf(buffer, bufsize, "Scissor BR: %i, %i", x2, y2);
 
358
                }
 
359
                break;
 
360
 
 
361
        case GE_CMD_MINZ:
 
362
                {
 
363
                        float zMin = getFloat24(data) / 65535.f;
 
364
                        snprintf(buffer, bufsize, "MinZ: %f", zMin);
 
365
                }
 
366
                break;
 
367
 
 
368
        case GE_CMD_MAXZ:
 
369
                {
 
370
                        float zMax = getFloat24(data) / 65535.f;
 
371
                        snprintf(buffer, bufsize, "MaxZ: %f", zMax);
 
372
                }
 
373
                break;
 
374
 
 
375
        case GE_CMD_FRAMEBUFPTR:
 
376
                {
 
377
                        snprintf(buffer, bufsize, "FramebufPtr: %08x", data);
 
378
                }
 
379
                break;
 
380
 
 
381
        case GE_CMD_FRAMEBUFWIDTH:
 
382
                {
 
383
                        snprintf(buffer, bufsize, "FramebufWidth: %x, address high %02x", data & 0xFFFF, data >> 16);
 
384
                }
 
385
                break;
 
386
 
 
387
        case GE_CMD_FRAMEBUFPIXFORMAT:
 
388
                snprintf(buffer, bufsize, "FramebufPixelFormat: %i", data);
 
389
                break;
 
390
 
 
391
        case GE_CMD_TEXADDR0:
 
392
        case GE_CMD_TEXADDR1:
 
393
        case GE_CMD_TEXADDR2:
 
394
        case GE_CMD_TEXADDR3:
 
395
        case GE_CMD_TEXADDR4:
 
396
        case GE_CMD_TEXADDR5:
 
397
        case GE_CMD_TEXADDR6:
 
398
        case GE_CMD_TEXADDR7:
 
399
                snprintf(buffer, bufsize, "Texture address %i: %06x", cmd-GE_CMD_TEXADDR0, data);
 
400
                break;
 
401
 
 
402
        case GE_CMD_TEXBUFWIDTH0:
 
403
        case GE_CMD_TEXBUFWIDTH1:
 
404
        case GE_CMD_TEXBUFWIDTH2:
 
405
        case GE_CMD_TEXBUFWIDTH3:
 
406
        case GE_CMD_TEXBUFWIDTH4:
 
407
        case GE_CMD_TEXBUFWIDTH5:
 
408
        case GE_CMD_TEXBUFWIDTH6:
 
409
        case GE_CMD_TEXBUFWIDTH7:
 
410
                snprintf(buffer, bufsize, "Texture BUFWIDTH %i: %06x", cmd-GE_CMD_TEXBUFWIDTH0, data);
 
411
                break;
 
412
 
 
413
        case GE_CMD_CLUTADDR:
 
414
                snprintf(buffer, bufsize, "CLUT base addr: %06x", data);
 
415
                break;
 
416
 
 
417
        case GE_CMD_CLUTADDRUPPER:
 
418
                snprintf(buffer, bufsize, "CLUT addr upper %08x", data);
 
419
                break;
 
420
 
 
421
        case GE_CMD_LOADCLUT:
 
422
                // This could be used to "dirty" textures with clut.
 
423
                if (data)
 
424
                        snprintf(buffer, bufsize, "Clut load: %06x", data);
 
425
                else
 
426
                        snprintf(buffer, bufsize, "Clut load");
 
427
                break;
 
428
 
 
429
        case GE_CMD_TEXMAPMODE:
 
430
                snprintf(buffer, bufsize, "Tex map mode: %06x", data);
 
431
                break;
 
432
 
 
433
        case GE_CMD_TEXSHADELS:
 
434
                snprintf(buffer, bufsize, "Tex shade light sources: %06x", data);
 
435
                break;
 
436
 
 
437
        case GE_CMD_CLUTFORMAT:
 
438
                {
 
439
                        const char *clutformats[] = {
 
440
                                "BGR 5650",
 
441
                                "ABGR 1555",
 
442
                                "ABGR 4444",
 
443
                                "ABGR 8888",
 
444
                        };
 
445
                        snprintf(buffer, bufsize, "Clut format: %06x (%s)", data, clutformats[data & 3]);
 
446
                }
 
447
                break;
 
448
 
 
449
        case GE_CMD_TRANSFERSRC:
 
450
                {
 
451
                        if (data & 0xF)
 
452
                                snprintf(buffer, bufsize, "Block transfer src: %06x (extra: %x)", data & ~0xF, data & 0xF);
 
453
                        else
 
454
                                snprintf(buffer, bufsize, "Block transfer src: %06x", data);
 
455
                        // Nothing to do, the next one prints
 
456
                }
 
457
                break;
 
458
 
 
459
        case GE_CMD_TRANSFERSRCW:
 
460
                {
 
461
                        u32 xferSrc = (gstate.transfersrc & 0x00FFFFFF) | ((data & 0xFF0000) << 8);
 
462
                        u32 xferSrcW = data & 0x3FF;
 
463
                        if (data & ~0xFF03FF)
 
464
                                snprintf(buffer, bufsize, "Block transfer src: %08x     W: %i (extra %x)", xferSrc, xferSrcW, data);
 
465
                        else
 
466
                                snprintf(buffer, bufsize, "Block transfer src: %08x     W: %i", xferSrc, xferSrcW);
 
467
                        break;
 
468
                }
 
469
 
 
470
        case GE_CMD_TRANSFERDST:
 
471
                {
 
472
                        // Nothing to do, the next one prints
 
473
                        if (data & 0xF)
 
474
                                snprintf(buffer, bufsize, "Block transfer dst: %06x (extra: %x)", data & ~0xF, data & 0xF);
 
475
                        else
 
476
                                snprintf(buffer, bufsize, "Block transfer dst: %06x", data);
 
477
                }
 
478
                break;
 
479
 
 
480
        case GE_CMD_TRANSFERDSTW:
 
481
                {
 
482
                        u32 xferDst = (gstate.transferdst & 0x00FFFFFF) | ((data & 0xFF0000) << 8);
 
483
                        u32 xferDstW = data & 0x3FF;
 
484
                        if (data & ~0xFF03FF)
 
485
                                snprintf(buffer, bufsize, "Block transfer dest: %08x    W: %i (extra %x)", xferDst, xferDstW, data);
 
486
                        else
 
487
                                snprintf(buffer, bufsize, "Block transfer dest: %08x    W: %i", xferDst, xferDstW);
 
488
                        break;
 
489
                }
 
490
 
 
491
        case GE_CMD_TRANSFERSRCPOS:
 
492
                {
 
493
                        u32 x = (data & 1023);
 
494
                        u32 y = ((data>>10) & 1023);
 
495
                        if (data & 0xF00000)
 
496
                                snprintf(buffer, bufsize, "Block transfer src rect TL: %i, %i (extra %x)", x, y, data >> 20);
 
497
                        else
 
498
                                snprintf(buffer, bufsize, "Block transfer src rect TL: %i, %i", x, y);
 
499
                        break;
 
500
                }
 
501
 
 
502
        case GE_CMD_TRANSFERDSTPOS:
 
503
                {
 
504
                        u32 x = (data & 1023);
 
505
                        u32 y = ((data>>10) & 1023);
 
506
                        if (data & 0xF00000)
 
507
                                snprintf(buffer, bufsize, "Block transfer dest rect TL: %i, %i (extra %x)", x, y, data >> 20);
 
508
                        else
 
509
                                snprintf(buffer, bufsize, "Block transfer dest rect TL: %i, %i", x, y);
 
510
                        break;
 
511
                }
 
512
 
 
513
        case GE_CMD_TRANSFERSIZE:
 
514
                {
 
515
                        u32 w = (data & 1023)+1;
 
516
                        u32 h = ((data>>10) & 1023)+1;
 
517
                        if (data & 0xF00000)
 
518
                                snprintf(buffer, bufsize, "Block transfer rect size: %i x %i (extra %x)", w, h, data >> 20);
 
519
                        else
 
520
                                snprintf(buffer, bufsize, "Block transfer rect size: %i x %i", w, h);
 
521
                        break;
 
522
                }
 
523
 
 
524
        case GE_CMD_TRANSFERSTART:  // Orphis calls this TRXKICK
 
525
                if (data & ~1)
 
526
                        snprintf(buffer, bufsize, "Block transfer start: %d (extra %x)", data & 1, data & ~1);
 
527
                else
 
528
                        snprintf(buffer, bufsize, "Block transfer start: %d", data);
 
529
                break;
 
530
 
 
531
        case GE_CMD_TEXSIZE0:
 
532
        case GE_CMD_TEXSIZE1:
 
533
        case GE_CMD_TEXSIZE2:
 
534
        case GE_CMD_TEXSIZE3:
 
535
        case GE_CMD_TEXSIZE4:
 
536
        case GE_CMD_TEXSIZE5:
 
537
        case GE_CMD_TEXSIZE6:
 
538
        case GE_CMD_TEXSIZE7:
 
539
                {
 
540
                        int w = 1 << (data & 0xf);
 
541
                        int h = 1 << ((data>>8) & 0xf);
 
542
                        snprintf(buffer, bufsize, "Texture size %i: %06x, width : %d, height : %d", cmd - GE_CMD_TEXSIZE0, data, w, h);
 
543
                }
 
544
                break;
 
545
 
 
546
        case GE_CMD_ZBUFPTR:
 
547
                {
 
548
                        snprintf(buffer, bufsize, "Zbuf ptr: %06x", data);
 
549
                }
 
550
                break;
 
551
 
 
552
        case GE_CMD_ZBUFWIDTH:
 
553
                snprintf(buffer, bufsize, "Zbuf width: %06x", data);
 
554
                break;
 
555
 
 
556
        case GE_CMD_AMBIENTCOLOR:
 
557
                snprintf(buffer, bufsize, "Ambient color: %06x", data);
 
558
                break;
 
559
 
 
560
        case GE_CMD_AMBIENTALPHA:
 
561
                snprintf(buffer, bufsize, "Ambient alpha: %06x", data);
 
562
                break;
 
563
 
 
564
        case GE_CMD_MATERIALAMBIENT:
 
565
                snprintf(buffer, bufsize, "Material ambient color: %06x", data);
 
566
                break;
 
567
 
 
568
        case GE_CMD_MATERIALDIFFUSE:
 
569
                snprintf(buffer, bufsize, "Material diffuse color: %06x", data);
 
570
                break;
 
571
 
 
572
        case GE_CMD_MATERIALEMISSIVE:
 
573
                snprintf(buffer, bufsize, "Material emissive color: %06x", data);
 
574
                break;
 
575
 
 
576
        case GE_CMD_MATERIALSPECULAR:
 
577
                snprintf(buffer, bufsize, "Material specular color: %06x", data);
 
578
                break;
 
579
 
 
580
        case GE_CMD_MATERIALALPHA:
 
581
                snprintf(buffer, bufsize, "Material alpha color: %06x", data);
 
582
                break;
 
583
 
 
584
        case GE_CMD_MATERIALSPECULARCOEF:
 
585
                snprintf(buffer, bufsize, "Material specular coef: %f", getFloat24(data));
 
586
                break;
 
587
 
 
588
        case GE_CMD_SHADEMODE:
 
589
                if (data & ~1)
 
590
                        snprintf(buffer, bufsize, "Shade: %06x (%s, extra %x)", data, data ? "gouraud" : "flat", data);
 
591
                else
 
592
                        snprintf(buffer, bufsize, "Shade: %06x (%s)", data, data ? "gouraud" : "flat");
 
593
                break;
 
594
 
 
595
        case GE_CMD_LIGHTMODE:
 
596
                if (data & ~1)
 
597
                        snprintf(buffer, bufsize, "Lightmode: %06x (%s, extra %x)", data, data ? "separate spec" : "single color", data);
 
598
                else
 
599
                        snprintf(buffer, bufsize, "Lightmode: %06x (%s)", data, data ? "separate spec" : "single color");
 
600
                break;
 
601
 
 
602
        case GE_CMD_LIGHTTYPE0:
 
603
        case GE_CMD_LIGHTTYPE1:
 
604
        case GE_CMD_LIGHTTYPE2:
 
605
        case GE_CMD_LIGHTTYPE3:
 
606
                snprintf(buffer, bufsize, "Light %i type: %06x", cmd-GE_CMD_LIGHTTYPE0, data);
 
607
                break;
 
608
 
 
609
        case GE_CMD_LX0:case GE_CMD_LY0:case GE_CMD_LZ0:
 
610
        case GE_CMD_LX1:case GE_CMD_LY1:case GE_CMD_LZ1:
 
611
        case GE_CMD_LX2:case GE_CMD_LY2:case GE_CMD_LZ2:
 
612
        case GE_CMD_LX3:case GE_CMD_LY3:case GE_CMD_LZ3:
 
613
                {
 
614
                        int n = cmd - GE_CMD_LX0;
 
615
                        int l = n / 3;
 
616
                        int c = n % 3;
 
617
                        float val = getFloat24(data);
 
618
                        snprintf(buffer, bufsize, "Light %i %c pos: %f", l, c+'X', val);
 
619
                }
 
620
                break;
 
621
 
 
622
        case GE_CMD_LDX0:case GE_CMD_LDY0:case GE_CMD_LDZ0:
 
623
        case GE_CMD_LDX1:case GE_CMD_LDY1:case GE_CMD_LDZ1:
 
624
        case GE_CMD_LDX2:case GE_CMD_LDY2:case GE_CMD_LDZ2:
 
625
        case GE_CMD_LDX3:case GE_CMD_LDY3:case GE_CMD_LDZ3:
 
626
                {
 
627
                        int n = cmd - GE_CMD_LDX0;
 
628
                        int l = n / 3;
 
629
                        int c = n % 3;
 
630
                        float val = getFloat24(data);
 
631
                        snprintf(buffer, bufsize, "Light %i %c dir: %f", l, c+'X', val);
 
632
                }
 
633
                break;
 
634
 
 
635
        case GE_CMD_LKA0:case GE_CMD_LKB0:case GE_CMD_LKC0:
 
636
        case GE_CMD_LKA1:case GE_CMD_LKB1:case GE_CMD_LKC1:
 
637
        case GE_CMD_LKA2:case GE_CMD_LKB2:case GE_CMD_LKC2:
 
638
        case GE_CMD_LKA3:case GE_CMD_LKB3:case GE_CMD_LKC3:
 
639
                {
 
640
                        int n = cmd - GE_CMD_LKA0;
 
641
                        int l = n / 3;
 
642
                        int c = n % 3;
 
643
                        float val = getFloat24(data);
 
644
                        snprintf(buffer, bufsize, "Light %i %c att: %f", l, c+'X', val);
 
645
                }
 
646
                break;
 
647
 
 
648
        case GE_CMD_LAC0:case GE_CMD_LAC1:case GE_CMD_LAC2:case GE_CMD_LAC3:
 
649
        case GE_CMD_LDC0:case GE_CMD_LDC1:case GE_CMD_LDC2:case GE_CMD_LDC3:
 
650
        case GE_CMD_LSC0:case GE_CMD_LSC1:case GE_CMD_LSC2:case GE_CMD_LSC3:
 
651
                {
 
652
                        float r = (float)(data & 0xff)/255.0f;
 
653
                        float g = (float)((data>>8) & 0xff)/255.0f;
 
654
                        float b = (float)(data>>16)/255.0f;
 
655
 
 
656
                        int l = (cmd - GE_CMD_LAC0) / 3;
 
657
                        int t = (cmd - GE_CMD_LAC0) % 3;
 
658
                        snprintf(buffer, bufsize, "Light %i color %i: %f %f %f", l, t, r, g, b);
 
659
                }
 
660
                break;
 
661
 
 
662
        case GE_CMD_VIEWPORTXSCALE:
 
663
        case GE_CMD_VIEWPORTYSCALE:
 
664
        case GE_CMD_VIEWPORTXCENTER:
 
665
        case GE_CMD_VIEWPORTYCENTER:
 
666
                snprintf(buffer, bufsize, "Viewport param %i: %f", cmd-GE_CMD_VIEWPORTXSCALE, getFloat24(data));
 
667
                break;
 
668
        case GE_CMD_VIEWPORTZSCALE:
 
669
                {
 
670
                        float zScale = getFloat24(data) / 65535.f;
 
671
                        snprintf(buffer, bufsize, "Viewport Z scale: %f", zScale);
 
672
                }
 
673
                break;
 
674
        case GE_CMD_VIEWPORTZCENTER:
 
675
                {
 
676
                        float zOff = getFloat24(data) / 65535.f;
 
677
                        snprintf(buffer, bufsize, "Viewport Z pos: %f", zOff);
 
678
                }
 
679
                break;
 
680
 
 
681
        case GE_CMD_LIGHTENABLE0:
 
682
        case GE_CMD_LIGHTENABLE1:
 
683
        case GE_CMD_LIGHTENABLE2:
 
684
        case GE_CMD_LIGHTENABLE3:
 
685
                snprintf(buffer, bufsize, "Light %i enable: %d", cmd-GE_CMD_LIGHTENABLE0, data);
 
686
                break;
 
687
 
 
688
        case GE_CMD_CULL:
 
689
                snprintf(buffer, bufsize, "Cull: %06x", data);
 
690
                break;
 
691
 
 
692
        case GE_CMD_PATCHDIVISION:
 
693
                {
 
694
                        int patch_div_s = data & 0xFF;
 
695
                        int patch_div_t = (data >> 8) & 0xFF;
 
696
                        if (data & 0xFF0000)
 
697
                                snprintf(buffer, bufsize, "Patch subdivision: %i x %i (extra %x)", patch_div_s, patch_div_t, data & 0xFF0000);
 
698
                        else
 
699
                                snprintf(buffer, bufsize, "Patch subdivision: %i x %i", patch_div_s, patch_div_t);
 
700
                }
 
701
                break;
 
702
 
 
703
        case GE_CMD_PATCHPRIMITIVE:
 
704
                snprintf(buffer, bufsize, "Patch Primitive: %d", data);
 
705
                break;
 
706
 
 
707
        case GE_CMD_PATCHFACING:
 
708
                snprintf(buffer, bufsize, "Patch Facing: %d", data);
 
709
                break;
 
710
 
 
711
        case GE_CMD_REVERSENORMAL:
 
712
                snprintf(buffer, bufsize, "Reverse normal: %d", data);
 
713
                break;
 
714
 
 
715
        case GE_CMD_MATERIALUPDATE:
 
716
                snprintf(buffer, bufsize, "Material update: %d", data);
 
717
                break;
 
718
 
 
719
 
 
720
        //////////////////////////////////////////////////////////////////
 
721
        //      CLEARING
 
722
        //////////////////////////////////////////////////////////////////
 
723
        case GE_CMD_CLEARMODE:
 
724
                {
 
725
                        const char *clearModes[] = {
 
726
                                "on",
 
727
                                "on, color",
 
728
                                "on, alpha/stencil",
 
729
                                "on, color, alpha/stencil",
 
730
                                "on, depth",
 
731
                                "on, color, depth",
 
732
                                "on, alpha/stencil, depth",
 
733
                                "on, color, alpha/stencil, depth",
 
734
                        };
 
735
 
 
736
                        const char *mode;
 
737
                        if (data & 1)
 
738
                                mode = clearModes[(data >> 8) & 7];
 
739
                        else
 
740
                                mode = "off";
 
741
                        snprintf(buffer, bufsize, "Clear mode: %06x (%s)", data, mode);
 
742
                }
 
743
                break;
 
744
 
 
745
 
 
746
        //////////////////////////////////////////////////////////////////
 
747
        //      ALPHA BLENDING
 
748
        //////////////////////////////////////////////////////////////////
 
749
        case GE_CMD_ALPHABLENDENABLE:
 
750
                snprintf(buffer, bufsize, "Alpha blend enable: %d", data);
 
751
                break;
 
752
 
 
753
        case GE_CMD_BLENDMODE:
 
754
                {
 
755
                        const char *blendModes[] = {
 
756
                                "add",
 
757
                                "subtract",
 
758
                                "reverse subtract",
 
759
                                "min",
 
760
                                "max",
 
761
                                "abs subtract",
 
762
                                "unsupported1",
 
763
                                "unsupported2",
 
764
                        };
 
765
                        const char *blendFactorsA[16] = {
 
766
                                "dst",                       
 
767
                                "1.0 - dst",
 
768
                                "src.a",
 
769
                                "1.0 - src.a",
 
770
                                "dst.a",
 
771
                                "1.0 - dst.a",
 
772
                                "2.0 * src.a",
 
773
                                "1.0 - 2.0 * src.a",
 
774
                                "2.0 * dst.a",
 
775
                                "1.0 - 2.0 * dst.a",
 
776
                                "fixed",
 
777
                                "fixed2",
 
778
                                "fixed3",
 
779
                                "fixed4",
 
780
                                "fixed5",
 
781
                        };
 
782
                        const char *blendFactorsB[16] = {
 
783
                                "src",
 
784
                                "1.0 - src",
 
785
                                "src.a",
 
786
                                "1.0 - src.a",
 
787
                                "dst.a",
 
788
                                "1.0 - dst.a",
 
789
                                "2.0 * src.a",
 
790
                                "1.0 - 2.0 * src.a",
 
791
                                "2.0 * dst.a",
 
792
                                "1.0 - 2.0 * dst.a",
 
793
                                "fixed",
 
794
                                "fixed2",
 
795
                                "fixed3",
 
796
                                "fixed4",
 
797
                                "fixed5",
 
798
                        };
 
799
 
 
800
                        const char *blendFactorA = blendFactorsA[(data >> 0) & 0xF];
 
801
                        const char *blendFactorB = blendFactorsB[(data >> 4) & 0xF];
 
802
                        const char *blendMode = blendModes[(data >> 8) & 0x7];
 
803
 
 
804
                        if (data & ~0xFF0007FF)
 
805
                                snprintf(buffer, bufsize, "Blend mode: %s %s, %s (extra: %06x)", blendMode, blendFactorA, blendFactorB, data & ~0xFF0007FF);
 
806
                        else
 
807
                                snprintf(buffer, bufsize, "Blend mode: %s %s, %s", blendMode, blendFactorA, blendFactorB);
 
808
                }
 
809
                break;
 
810
 
 
811
        case GE_CMD_BLENDFIXEDA:
 
812
                snprintf(buffer, bufsize, "Blend fix A: %06x", data);
 
813
                break;
 
814
 
 
815
        case GE_CMD_BLENDFIXEDB:
 
816
                snprintf(buffer, bufsize, "Blend fix B: %06x", data);
 
817
                break;
 
818
 
 
819
        case GE_CMD_ALPHATESTENABLE:
 
820
                snprintf(buffer, bufsize, "Alpha test enable: %d", data);
 
821
                break;
 
822
 
 
823
        case GE_CMD_ALPHATEST:
 
824
                {
 
825
                        const char *alphaTestFuncs[] = { " NEVER ", " ALWAYS ", " == ", " != ", " < ", " <= ", " > ", " >= " };
 
826
                        snprintf(buffer, bufsize, "Alpha test settings: %06x ((c & %02x)%s%02x)", data, (data >> 16) & 0xFF, alphaTestFuncs[data & 7], (data >> 8) & 0xFF);
 
827
                }
 
828
                break;
 
829
 
 
830
        case GE_CMD_ANTIALIASENABLE:
 
831
                snprintf(buffer, bufsize, "Antialias enable: %d", data);
 
832
                break;
 
833
 
 
834
        case GE_CMD_PATCHCULLENABLE:
 
835
                snprintf(buffer, bufsize, "Patch cull enable: %d", data);
 
836
                break;
 
837
 
 
838
        case GE_CMD_COLORTESTENABLE:
 
839
                snprintf(buffer, bufsize, "Color test enable: %d", data);
 
840
                break;
 
841
 
 
842
        case GE_CMD_LOGICOPENABLE:
 
843
                snprintf(buffer, bufsize, "Logic op enable: %d", data);
 
844
                break;
 
845
 
 
846
        case GE_CMD_TEXFUNC:
 
847
                {
 
848
                        const char *texfuncs[] = {
 
849
                                "modulate",
 
850
                                "decal",
 
851
                                "blend",
 
852
                                "replace",
 
853
                                "add",
 
854
                                "unsupported1",
 
855
                                "unsupported2",
 
856
                                "unsupported3",
 
857
                        };
 
858
                        if (data & ~0x10107)
 
859
                                snprintf(buffer, bufsize, "TexFunc %i %s %s%s (extra %x)", data & 7, data & 0x100 ? "RGBA" : "RGB", texfuncs[data & 7], data & 0x10000 ? " color double" : "", data);
 
860
                        else
 
861
                                snprintf(buffer, bufsize, "TexFunc %i %s %s%s", data & 7, data & 0x100 ? "RGBA" : "RGB", texfuncs[data & 7], data & 0x10000 ? " color double" : "");
 
862
                }
 
863
                break;
 
864
 
 
865
        case GE_CMD_TEXFILTER:
 
866
                {
 
867
                        int min = data & 7;
 
868
                        int mag = (data >> 8) & 1;
 
869
                        if (data & ~0x107)
 
870
                                snprintf(buffer, bufsize, "TexFilter min: %i mag: %i (extra %x)", min, mag, data);
 
871
                        else
 
872
                                snprintf(buffer, bufsize, "TexFilter min: %i mag: %i", min, mag);
 
873
                }
 
874
                break;
 
875
 
 
876
        case GE_CMD_TEXENVCOLOR:
 
877
                snprintf(buffer, bufsize, "TexEnvColor %06x", data);
 
878
                break;
 
879
 
 
880
        case GE_CMD_TEXMODE:
 
881
                snprintf(buffer, bufsize, "TexMode %06x (%s, %d levels, %s)", data, data & 1 ? "swizzle" : "no swizzle", (data >> 16) & 7, (data >> 8) & 1 ? "separate cluts" : "shared clut");
 
882
                break;
 
883
 
 
884
        case GE_CMD_TEXFORMAT:
 
885
                {
 
886
                        const char *texformats[] = {
 
887
                                "5650",
 
888
                                "5551",
 
889
                                "4444",
 
890
                                "8888",
 
891
                                "CLUT4",
 
892
                                "CLUT8",
 
893
                                "CLUT16",
 
894
                                "CLUT32",
 
895
                                "DXT1",
 
896
                                "DXT3",
 
897
                                "DXT5",
 
898
                                "unsupported1",
 
899
                                "unsupported2",
 
900
                                "unsupported3",
 
901
                                "unsupported4",
 
902
                                "unsupported5",
 
903
                        };
 
904
                        snprintf(buffer, bufsize, "TexFormat %06x (%s)", data, texformats[data & 0xF]);
 
905
                }
 
906
                break;
 
907
 
 
908
        case GE_CMD_TEXFLUSH:
 
909
                if (data)
 
910
                        snprintf(buffer, bufsize, "TexFlush: %x", data);
 
911
                else
 
912
                        snprintf(buffer, bufsize, "TexFlush");
 
913
                break;
 
914
 
 
915
        case GE_CMD_TEXSYNC:
 
916
                if (data)
 
917
                        snprintf(buffer, bufsize, "TexSync: %x", data);
 
918
                else
 
919
                        snprintf(buffer, bufsize, "TexSync");
 
920
                break;
 
921
 
 
922
        case GE_CMD_TEXWRAP:
 
923
                if (data & ~0x0101)
 
924
                        snprintf(buffer, bufsize, "TexWrap %s s, %s t (extra %x)", data & 1 ? "clamp" : "wrap", data & 0x100 ? "clamp" : "wrap", data);
 
925
                else
 
926
                        snprintf(buffer, bufsize, "TexWrap %s s, %s t", data & 1 ? "clamp" : "wrap", data & 0x100 ? "clamp" : "wrap");
 
927
                break;
 
928
 
 
929
        case GE_CMD_TEXLEVEL:
 
930
                if (data & ~0xFF0003)
 
931
                        snprintf(buffer, bufsize, "TexLevel mode: %i Offset: %i (extra %x)", data&3, data >> 16, data);
 
932
                else
 
933
                        snprintf(buffer, bufsize, "TexLevel mode: %i Offset: %i", data&3, data >> 16);
 
934
                break;
 
935
 
 
936
        case GE_CMD_FOG1:
 
937
                snprintf(buffer, bufsize, "Fog1 %f", getFloat24(data));
 
938
                break;
 
939
 
 
940
        case GE_CMD_FOG2:
 
941
                snprintf(buffer, bufsize, "Fog2 %f", getFloat24(data));
 
942
                break;
 
943
 
 
944
        case GE_CMD_FOGCOLOR:
 
945
                snprintf(buffer, bufsize, "FogColor %06x", data);
 
946
                break;
 
947
 
 
948
        case GE_CMD_TEXLODSLOPE:
 
949
                snprintf(buffer, bufsize, "TexLodSlope %06x", data);
 
950
                break;
 
951
 
 
952
        //////////////////////////////////////////////////////////////////
 
953
        //      Z/STENCIL TESTING
 
954
        //////////////////////////////////////////////////////////////////
 
955
 
 
956
        case GE_CMD_ZTESTENABLE:
 
957
                if (data & ~1)
 
958
                        snprintf(buffer, bufsize, "Z test enable: %d (extra %x)", data & 1, data);
 
959
                else
 
960
                        snprintf(buffer, bufsize, "Z test enable: %d", data & 1);
 
961
                break;
 
962
 
 
963
        case GE_CMD_STENCILOP:
 
964
                {
 
965
                        const char *stencilOps[] = { "KEEP", "ZERO", "REPLACE", "INVERT", "INCREMENT", "DECREMENT", "unsupported1", "unsupported2" };
 
966
                        snprintf(buffer, bufsize, "Stencil op: fail=%s, pass/depthfail=%s, pass=%s", stencilOps[data & 7], stencilOps[(data >> 8) & 7], stencilOps[(data >> 16) & 7]);
 
967
                }
 
968
                break;
 
969
 
 
970
        case GE_CMD_STENCILTEST:
 
971
                {
 
972
                        const char *zTestFuncs[] = { "NEVER", "ALWAYS", " == ", " != ", " < ", " <= ", " > ", " >= " };
 
973
                        snprintf(buffer, bufsize, "Stencil test: %06x (%02x %s (c & %02x))", data, (data >> 8) & 0xFF, zTestFuncs[data & 7], (data >> 16) & 0xFF);
 
974
                }
 
975
                break;
 
976
 
 
977
        case GE_CMD_STENCILTESTENABLE:
 
978
                snprintf(buffer, bufsize, "Stencil test enable: %d", data);
 
979
                break;
 
980
 
 
981
        case GE_CMD_ZTEST:
 
982
                {
 
983
                        const char *zTestFuncs[] = { "NEVER", "ALWAYS", " == ", " != ", " < ", " <= ", " > ", " >= " };
 
984
                        snprintf(buffer, bufsize, "Z test mode: %i (%s)", data, zTestFuncs[data & 7]);
 
985
                }
 
986
                break;
 
987
 
 
988
        case GE_CMD_MORPHWEIGHT0:
 
989
        case GE_CMD_MORPHWEIGHT1:
 
990
        case GE_CMD_MORPHWEIGHT2:
 
991
        case GE_CMD_MORPHWEIGHT3:
 
992
        case GE_CMD_MORPHWEIGHT4:
 
993
        case GE_CMD_MORPHWEIGHT5:
 
994
        case GE_CMD_MORPHWEIGHT6:
 
995
        case GE_CMD_MORPHWEIGHT7:
 
996
                {
 
997
                        int index = cmd - GE_CMD_MORPHWEIGHT0;
 
998
                        float weight = getFloat24(data);
 
999
                        snprintf(buffer, bufsize, "MorphWeight %i = %f", index, weight);
 
1000
                }
 
1001
                break;
 
1002
 
 
1003
        case GE_CMD_DITH0:
 
1004
        case GE_CMD_DITH1:
 
1005
        case GE_CMD_DITH2:
 
1006
        case GE_CMD_DITH3:
 
1007
                snprintf(buffer, bufsize, "DitherMatrix %i = %06x",cmd-GE_CMD_DITH0,data);
 
1008
                break;
 
1009
 
 
1010
        case GE_CMD_LOGICOP:
 
1011
                {
 
1012
                        const char *logicOps[] = {
 
1013
                                "clear",
 
1014
                                "and",
 
1015
                                "reverse and",
 
1016
                                "copy",
 
1017
                                "inverted and",
 
1018
                                "noop",
 
1019
                                "xor",
 
1020
                                "or",
 
1021
                                "negated or",
 
1022
                                "equivalence",
 
1023
                                "inverted",
 
1024
                                "reverse or",
 
1025
                                "inverted copy",
 
1026
                                "inverted or",
 
1027
                                "negated and",
 
1028
                                "set",
 
1029
                        };
 
1030
                        snprintf(buffer, bufsize, "LogicOp: %06x (%s)", data, logicOps[data & 0xF]);
 
1031
                }
 
1032
                break;
 
1033
 
 
1034
        case GE_CMD_ZWRITEDISABLE:
 
1035
                snprintf(buffer, bufsize, "ZMask: %06x", data);
 
1036
                break;
 
1037
 
 
1038
        case GE_CMD_COLORTEST:
 
1039
                {
 
1040
                        const char *colorTests[] = {"NEVER", "ALWAYS", " == ", " != "};
 
1041
                        snprintf(buffer, bufsize, "ColorTest: %06x (ref%s(c & cmask))", data, colorTests[data & 3]);
 
1042
                }
 
1043
                break;
 
1044
 
 
1045
        case GE_CMD_COLORREF:
 
1046
                snprintf(buffer, bufsize, "ColorRef: %06x", data);
 
1047
                break;
 
1048
 
 
1049
        case GE_CMD_COLORTESTMASK:
 
1050
                snprintf(buffer, bufsize, "ColorTestMask: %06x", data);
 
1051
                break;
 
1052
 
 
1053
        case GE_CMD_MASKRGB:
 
1054
                snprintf(buffer, bufsize, "MaskRGB: %06x", data);
 
1055
                break;
 
1056
 
 
1057
        case GE_CMD_MASKALPHA:
 
1058
                snprintf(buffer, bufsize, "MaskAlpha: %06x", data);
 
1059
                break;
 
1060
 
 
1061
        case GE_CMD_WORLDMATRIXNUMBER:
 
1062
                if (data & ~0xF)
 
1063
                        snprintf(buffer, bufsize, "World # %i (extra %x)", data & 0xF, data);
 
1064
                else
 
1065
                        snprintf(buffer, bufsize, "World # %i", data & 0xF);
 
1066
                break;
 
1067
 
 
1068
        case GE_CMD_WORLDMATRIXDATA:
 
1069
                snprintf(buffer, bufsize, "World data # %f", getFloat24(data));
 
1070
                break;
 
1071
 
 
1072
        case GE_CMD_VIEWMATRIXNUMBER:
 
1073
                if (data & ~0xF)
 
1074
                        snprintf(buffer, bufsize, "VIEW # %i (extra %x)", data & 0xF, data);
 
1075
                else
 
1076
                        snprintf(buffer, bufsize, "VIEW # %i", data & 0xF);
 
1077
                break;
 
1078
 
 
1079
        case GE_CMD_VIEWMATRIXDATA:
 
1080
                snprintf(buffer, bufsize, "VIEW data # %f", getFloat24(data));
 
1081
                break;
 
1082
 
 
1083
        case GE_CMD_PROJMATRIXNUMBER:
 
1084
                if (data & ~0xF)
 
1085
                        snprintf(buffer, bufsize, "PROJECTION # %i (extra %x)", data & 0xF, data);
 
1086
                else
 
1087
                        snprintf(buffer, bufsize, "PROJECTION # %i", data & 0xF);
 
1088
                break;
 
1089
 
 
1090
        case GE_CMD_PROJMATRIXDATA:
 
1091
                snprintf(buffer, bufsize, "PROJECTION matrix data # %f", getFloat24(data));
 
1092
                break;
 
1093
 
 
1094
        case GE_CMD_TGENMATRIXNUMBER:
 
1095
                if (data & ~0xF)
 
1096
                        snprintf(buffer, bufsize, "TGEN # %i (extra %x)", data & 0xF, data);
 
1097
                else
 
1098
                        snprintf(buffer, bufsize, "TGEN # %i", data & 0xF);
 
1099
                break;
 
1100
 
 
1101
        case GE_CMD_TGENMATRIXDATA:
 
1102
                snprintf(buffer, bufsize, "TGEN data # %f", getFloat24(data));
 
1103
                break;
 
1104
 
 
1105
        case GE_CMD_BONEMATRIXNUMBER:
 
1106
                if (data & ~0x7F)
 
1107
                        snprintf(buffer, bufsize, "BONE #%i (extra %x)", data & 0x7F, data);
 
1108
                else
 
1109
                        snprintf(buffer, bufsize, "BONE #%i", data & 0x7F);
 
1110
                break;
 
1111
 
 
1112
        case GE_CMD_BONEMATRIXDATA:
 
1113
                snprintf(buffer, bufsize, "BONE data #%i %f", gstate.boneMatrixNumber & 0x7f, getFloat24(data));
 
1114
                break;
 
1115
 
 
1116
        default:
 
1117
                snprintf(buffer, bufsize, "Unknown: %08x", op);
 
1118
                break;
 
1119
        }
 
1120
}
 
1121