Rice GLES2 (from mupen64plus-ae) plugin. Compile but doesn't works well on the OpenPa...
[mupen64plus-pandora.git] / source / gles2rice / src / Debugger.cpp
1 /*
2 Copyright (C) 2002 Rice1964
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17
18 */
19
20 #define M64P_PLUGIN_PROTOTYPES 1
21 #include "m64p_plugin.h"
22 #include "typedefs.h"
23
24 #ifndef DEBUGGER
25 void __cdecl DebuggerAppendMsg(const char * Message, ...) {}
26
27 #else
28
29 void DumpMatrix2(const Matrix &mtx, const char* prompt);
30
31 bool debuggerWinOpened = false;
32 bool debuggerDrawRenderTexture = false;
33 int debuggerDrawRenderTextureNo = 0;
34
35 bool logCombiners = false;
36 bool logWarning = true;
37 bool logTriangles = false;
38 bool logMatrix = false;
39 bool logVertex = false;
40 bool logTextures = false;
41 bool logTextureBuffer = false;
42 bool logToScreen = true;
43 bool logToFile = false;
44 bool logUcodes = false;
45 bool logMicrocode = false;
46 bool logFog = false;
47 bool logDetails = false;
48
49 FILE *logFp = NULL;
50
51 bool debuggerEnableTexture=true;
52 bool debuggerEnableZBuffer=true;
53 bool debuggerEnableCullFace=true;
54 bool debuggerEnableTestTris=true;
55 bool debuggerEnableAlphaTest=true;
56 bool debuggerContinueWithUnknown=false;
57
58 bool debuggerPause = false;
59 bool pauseAtNext = true;
60 int  eventToPause = NEXT_FRAME;
61 int  debuggerPauseCount = 340;
62 int  countToPause = 1;
63
64 bool debuggerDropCombiners=false;
65 bool debuggerDropGeneralCombiners=false;
66 bool debuggerDropDecodedMux=false;
67 bool debuggerDropCombinerInfos=false;
68
69 char msgBuf[0x20000+2];
70 bool msgBufUpdated = false;
71 extern FiddledVtx * g_pVtxBase;
72
73 uint32 CachedTexIndex = 0;
74
75 const char* otherNexts[] = {
76     "Frame",
77     "Flush Tri",
78     "TextRect",
79     "Triangle",
80     "Set CImg",
81     "ObjTxt Cmd",
82     "Obj BG",
83     "Sprite2D",
84     "FillRect",
85     "DList",
86     "Ucode",
87     "Texture Buffer",
88     "Matrix Cmd",
89     "Vertex Cmd",
90     "New Texture",
91     "Set Texture",
92     "Mux",
93     "Set Light",
94     "Set Mode Cmd",
95     "Set Prim Color",
96     "Texture Cmd",
97     "Unknown Ops",
98     "Scale Image",
99     "LoadTlut",
100     "Ucode Switching",
101 };
102 int numberOfNextOthers = sizeof(otherNexts)/sizeof(char*);
103
104 const char* thingsToDump[] = {
105     "Cur Texture RGBA",
106     "Cur+1 Texture RGBA",
107     "Colors",
108     "Memory At",
109     "Mux",
110     "Simple Mux",
111     "Other Modes",
112     "Texture #",
113     "Tile #",
114     "VI Regs",
115     "Cur Txt to file",
116     "Cur+1 Txt to file",
117     "Cur Texture RGB",
118     "Cur Texture Alpha",
119     "Cur+1 Texture RGB",
120     "Cur+1 Texture Alpha",
121     "Light Info",
122     "Tlut",
123     "Obj Tlut",
124     "Vertexes",
125     "Cached Texture",
126     "Next Texture",
127     "Prev Texture",
128     "Dlist At",
129     "Matrix At",
130     "Combined Matrix",
131     "World Top Matrix",
132     "Projection Matrix",
133     "World Matrix #",
134     "Frame Buffer in RDRAM",
135     "BackBuffer",
136     "TexBuffer #",
137 };
138 int numberOfThingsToDump = sizeof(thingsToDump)/sizeof(char*);
139
140 enum {
141     DUMP_CUR_TEXTURE_RGBA,
142     DUMP_CUR_1_TEXTURE_RGBA,
143     DUMP_COLORS,
144     DUMP_CONTENT_AT,
145     DUMP_CUR_MUX,
146     DUMP_SIMPLE_MUX,
147     DUMP_OTHER_MODE,
148     DUMP_TEXTURE_AT,
149     DUMP_TILE_AT,
150     DUMP_VI_REGS,
151     DUMP_CUR_TEXTURE_TO_FILE,
152     DUMP_CUR_1_TEXTURE_TO_FILE,
153     DUMP_CUR_TEXTURE_RGB,
154     DUMP_CUR_TEXTURE_ALPHA,
155     DUMP_CUR_1_TEXTURE_RGB,
156     DUMP_CUR_1_TEXTURE_ALPHA,
157     DUMP_LIGHT,
158     DUMP_TLUT,
159     DUMP_OBJ_TLUT,
160     DUMP_VERTEXES,
161     DUMP_CACHED_TEX,
162     DUMP_NEXT_TEX,
163     DUMP_PREV_TEX,
164     DUMP_DLIST_AT,
165     DUMP_MATRIX_AT,
166     DUMP_COMBINED_MATRIX,
167     DUMP_WORLD_TOP_MATRIX,
168     DUMP_PROJECTION_MATRIX,
169     DUMP_WORLD_MATRIX_AT,
170     DUMP_FRAME_BUFFER,
171     DUMP_BACKBUFFER,
172     DUMP_TEXBUFFER_AT,
173 };
174
175 //---------------------------------------------------------------------
176 void DumpVIRegisters(void)
177 {
178     DebuggerAppendMsg("----VI Registers----\nSTATUS:\t%08X\nORIGIN:\t%08X\nWIDTH:\t%08X\n\
179 V_SYNC:\t%08X\nH_SYNC:\t%08X\nX_SCALE:\t%08X\nY_SCALE:\t%08X\n\
180 H_START:\t%08X\nV_START:\t%08X\nVI Width=%f(x %f), VI Height=%f(x %f)\n\n",
181         *g_GraphicsInfo.VI_STATUS_REG, *g_GraphicsInfo.VI_ORIGIN_REG, *g_GraphicsInfo.VI_WIDTH_REG, *g_GraphicsInfo.VI_V_SYNC_REG,
182         *g_GraphicsInfo.VI_H_SYNC_REG, *g_GraphicsInfo.VI_X_SCALE_REG, *g_GraphicsInfo.VI_Y_SCALE_REG,
183         *g_GraphicsInfo.VI_H_START_REG, *g_GraphicsInfo.VI_V_START_REG, windowSetting.fViWidth,windowSetting.fMultX,
184         windowSetting.fViHeight,windowSetting.fMultY);
185     DebuggerAppendMsg("Scissor: x0=%d y0=%d x1=%d y1=%d mode=%d",
186         gRDP.scissor.left, gRDP.scissor.top,
187         gRDP.scissor.right, gRDP.scissor.bottom,
188         gRDP.scissor.mode);
189     DebuggerAppendMsg("Effective scissor: x0=%d y0=%d x1=%d y1=%d",
190         gRSP.real_clip_scissor_left, gRSP.real_clip_scissor_top,
191         gRSP.real_clip_scissor_right, gRSP.real_clip_scissor_bottom);
192     DebuggerAppendMsg("Clipping: (%d) left=%f top=%f right=%f bottom=%f",
193         gRSP.clip_ratio_posx, gRSP.real_clip_ratio_negx , gRSP.real_clip_ratio_negy,
194         gRSP.real_clip_ratio_posx, gRSP.real_clip_ratio_posy);
195     DebuggerAppendMsg("Viewport: left=%d top=%d right=%d bottom=%d",
196         gRSP.nVPLeftN, gRSP.nVPTopN , gRSP.nVPRightN,
197         gRSP.nVPBottomN);
198     DebuggerAppendMsg("Current CImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", 
199         g_CI.dwAddr, pszImgFormat[g_CI.dwFormat], pszImgSize[g_CI.dwSize], g_CI.dwWidth);
200     DebuggerAppendMsg("Current ZImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", 
201         g_ZI.dwAddr, pszImgFormat[g_ZI.dwFormat], pszImgSize[g_ZI.dwSize], g_ZI.dwWidth);
202 }
203
204 void DumpVertexArray(void)
205 {
206     DebuggerAppendMsg("----Vertexes----\n");
207     try
208     {
209         for( int i=0; i<32; i++ )
210         {
211             FiddledVtx &v = g_pVtxBase[i];
212             DebuggerAppendMsg("[%d] x=%d,y=%d,z=%d -- r=%d,g=%d,b=%d,a=%d\n", i, v.x, v.y, v.z, 
213                 v.rgba.r, v.rgba.g, v.rgba.b, v.rgba.a);
214             DebuggerAppendMsg("\tx=%f,y=%f,z=%f,rhw=%f\n", g_vecProjected[i].x, g_vecProjected[i].y, g_vecProjected[i].z, g_vecProjected[i].w);
215         }
216     }
217     catch(...)
218     {
219         DebuggerAppendMsg("Invalid memory pointer of vertex array\n");
220     }
221 }
222
223 void DumpHex(uint32 rdramAddr, int count);
224 uint32 StrToHex(char *HexStr);
225
226 void DumpTileInfo(uint32 dwTile)
227 {
228     const char *pszOnOff[2] = {"Off", "On"};
229
230     DebuggerAppendMsg("Tile: %d\nFmt: %s/%s Line:%d (Pitch %d) TMem:0x%04x Palette:%d\n",
231         dwTile, pszImgFormat[gRDP.tiles[dwTile].dwFormat], pszImgSize[gRDP.tiles[dwTile].dwSize],
232         gRDP.tiles[dwTile].dwLine, gRDP.tiles[dwTile].dwPitch, gRDP.tiles[dwTile].dwTMem, gRDP.tiles[dwTile].dwPalette);
233     DebuggerAppendMsg("S: Clamp: %s Mirror:%s Mask:0x%x Shift:0x%x\n",
234         pszOnOff[gRDP.tiles[dwTile].bClampS],pszOnOff[gRDP.tiles[dwTile].bMirrorS],
235         gRDP.tiles[dwTile].dwMaskS, gRDP.tiles[dwTile].dwShiftS);
236     DebuggerAppendMsg("T: Clamp: %s Mirror:%s Mask:0x%x Shift:0x%x\n",
237         pszOnOff[gRDP.tiles[dwTile].bClampT],pszOnOff[gRDP.tiles[dwTile].bMirrorT],
238         gRDP.tiles[dwTile].dwMaskT, gRDP.tiles[dwTile].dwShiftT);
239     DebuggerAppendMsg("(%d,%d) -> (%d,%d), hilite [%d, %d]\n",
240         gRDP.tiles[dwTile].sl, gRDP.tiles[dwTile].tl, gRDP.tiles[dwTile].sh, gRDP.tiles[dwTile].th,
241         gRDP.tiles[dwTile].hilite_sl,gRDP.tiles[dwTile].hilite_tl);
242 }
243
244 void DumpTexture(int tex, TextureChannel channel = TXT_RGB )
245 {
246     CRender::GetRender()->DrawTexture(tex, channel);
247 }
248
249 void DumpRenderTexture(int tex=-1)
250 {
251     if( CDeviceBuilder::GetBuilder()->GetGeneralDeviceType() == DIRECTX_DEVICE )
252     {
253         g_pFrameBufferManager->DisplayRenderTexture(tex);
254     }
255     else
256     {
257         debuggerDrawRenderTextureNo = tex;
258         debuggerDrawRenderTexture = true;
259     }
260 }
261
262 void DumpTextureToFile(int tex, TextureChannel channel = TXT_RGB)
263 {
264     CRender::GetRender()->SaveTextureToFile(tex, channel,false);
265 }
266
267 void DumpTlut(uint16* palAddr)
268 {
269     for( uint32 i=0; i<0x100; i+=8 )
270     {
271         DebuggerAppendMsg("0x%4X 0x%4X 0x%4X 0x%4X 0x%4X 0x%4X 0x%4X 0x%4X ", 
272             g_wRDPTlut[i], g_wRDPTlut[i+1], g_wRDPTlut[i+2], g_wRDPTlut[i+2], 
273             g_wRDPTlut[i+4], g_wRDPTlut[i+5], g_wRDPTlut[i+6], g_wRDPTlut[i+7]);
274     }
275 }
276
277 extern char ucodeNames_GBI1[256];
278 extern char ucodeNames_GBI2[256];
279
280 void DumpDlistAt(uint32 dwPC)
281 {
282     uint32 word0, word1, opcode;
283     char *name;
284     switch( gRSP.ucode )
285     {
286     case 2:
287     case 10:
288     //case 8:
289         name=ucodeNames_GBI2;
290         break;
291     default:
292         name=ucodeNames_GBI1;
293     }
294
295     DebuggerAppendMsg("\n\n");
296     //if( dwPC>100 ) dwPC -= 40;
297     for( uint32 i=0; i<20; i++)
298     {
299         word0 = g_pRDRAMu32[(dwPC>>2)+0];
300         word1 = g_pRDRAMu32[(dwPC>>2)+1];
301         opcode = word0>>24;
302         DebuggerAppendMsg("%08X: %08X, %08X - %s", dwPC, word0, word1, name[opcode] );
303         dwPC+=8;
304     }
305     DebuggerAppendMsg("\n\n");
306 }
307
308 void DumpMatrixAt(uint32 dwPC)
309 {
310     Matrix mat;
311     const float fRecip = 1.0f / 65536.0f;
312
313     for (uint32 dwI = 0; dwI < 4; dwI++)
314     {
315         for (uint32 dwJ = 0; dwJ < 4; dwJ++)
316         {
317             int nDataHi = *(short  *)(g_pRDRAMu8 + ((dwPC+(dwI<<3)+(dwJ<<1)     )^0x2));
318             int nDataLo = *(uint16 *)(g_pRDRAMu8 + ((dwPC+(dwI<<3)+(dwJ<<1) + 32)^0x2));
319             mat.m[dwI][dwJ] = (float)((nDataHi << 16) | nDataLo) * fRecip;
320         }
321     }
322
323     TRACE0("Dump Matrix in Memory");
324     DebuggerAppendMsg(
325         " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n"
326         " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n"
327         " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n"
328         " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n",
329         mat.m[0][0], mat.m[0][1], mat.m[0][2], mat.m[0][3],
330         mat.m[1][0], mat.m[1][1], mat.m[1][2], mat.m[1][3],
331         mat.m[2][0], mat.m[2][1], mat.m[2][2], mat.m[2][3],
332         mat.m[3][0], mat.m[3][1], mat.m[3][2], mat.m[3][3]);
333 }
334
335 // High
336 static const char *alphadithertypes[4]  = {"Pattern", "NotPattern", "Noise", "Disable"};
337 static const char *rgbdithertype[4]     = {"MagicSQ", "Bayer", "Noise", "Disable"};
338 static const char *convtype[8]          = {"Conv", "?", "?", "?",   "?", "FiltConv", "Filt", "?"};
339 static const char *filtertype[4]        = {"Point", "?", "Bilinear", "Average"};
340 static const char *cycletype[4]         = {"1Cycle", "2Cycle", "Copy", "Fill"};
341 static const char *alphacomptype[4]     = {"None", "Threshold", "?", "Dither"};
342 static const char * szCvgDstMode[4]     = { "Clamp", "Wrap", "Full", "Save" };
343 static const char * szZMode[4]          = { "Opa", "Inter", "XLU", "Decal" };
344 static const char * szZSrcSel[2]        = { "Pixel", "Primitive" };
345 static const char * sc_szBlClr[4]       = { "In", "Mem", "Bl", "Fog" };
346 static const char * sc_szBlA1[4]        = { "AIn", "AFog", "AShade", "0" };
347 static const char * sc_szBlA2[4]        = { "1-A", "AMem", "1", "0" };
348
349 void DumpOtherMode()
350 {
351     uint16 blender = gRDP.otherMode.blender;
352     RDP_BlenderSetting &bl = *(RDP_BlenderSetting*)(&(blender));
353     DebuggerAppendMsg( "Other Modes");
354     DebuggerAppendMsg( "\talpha_compare:\t%s", alphacomptype[ gRDP.otherMode.alpha_compare ]);
355     DebuggerAppendMsg( "\tdepth_source:\t%s", szZSrcSel[ gRDP.otherMode.depth_source ]);
356     DebuggerAppendMsg( "\taa_en:\t\t%d", gRDP.otherMode.aa_en );
357     DebuggerAppendMsg( "\tz_cmp:\t\t%d", gRDP.otherMode.z_cmp );
358     DebuggerAppendMsg( "\tz_upd:\t\t%d", gRDP.otherMode.z_upd );
359     DebuggerAppendMsg( "\tim_rd:\t\t%d", gRDP.otherMode.im_rd );
360     DebuggerAppendMsg( "\tclr_on_cvg:\t%d", gRDP.otherMode.clr_on_cvg );
361     DebuggerAppendMsg( "\tcvg_dst:\t\t%s", szCvgDstMode[ gRDP.otherMode.cvg_dst ] );
362     DebuggerAppendMsg( "\tzmode:\t\t%s", szZMode[ gRDP.otherMode.zmode ] );
363     DebuggerAppendMsg( "\tcvg_x_alpha:\t%d", gRDP.otherMode.cvg_x_alpha );
364     DebuggerAppendMsg( "\talpha_cvg_sel:\t%d", gRDP.otherMode.alpha_cvg_sel );
365     DebuggerAppendMsg( "\tforce_bl:\t\t%d", gRDP.otherMode.force_bl );
366     DebuggerAppendMsg( "\ttex_edge:\t\t%d", gRDP.otherMode.tex_edge );
367     DebuggerAppendMsg( "\tblender:\t\t%04x - Cycle1:\t%s * %s + %s * %s\n\t\t\tCycle2:\t%s * %s + %s * %s", gRDP.otherMode.blender,
368         sc_szBlClr[bl.c1_m1a], sc_szBlA1[bl.c1_m1b], sc_szBlClr[bl.c1_m2a], sc_szBlA2[bl.c1_m2b],
369         sc_szBlClr[bl.c2_m1a], sc_szBlA1[bl.c2_m1b], sc_szBlClr[bl.c2_m2a], sc_szBlA2[bl.c2_m2b]);
370     DebuggerAppendMsg( "\tblend_mask:\t%d", gRDP.otherMode.blend_mask );
371     DebuggerAppendMsg( "\talpha_dither:\t%s", alphadithertypes[ gRDP.otherMode.alpha_dither ] );
372     DebuggerAppendMsg( "\trgb_dither:\t\t%s", rgbdithertype[ gRDP.otherMode.rgb_dither ] );
373     DebuggerAppendMsg( "\tcomb_key:\t%s", gRDP.otherMode.key_en ? "Key" : "None" );
374     DebuggerAppendMsg( "\ttext_conv:\t\t%s", convtype[ gRDP.otherMode.text_conv ] );
375     DebuggerAppendMsg( "\ttext_filt:\t\t%s", filtertype[ gRDP.otherMode.text_filt ] );
376     DebuggerAppendMsg( "\ttext_tlut:\t\t%s", textluttype[ gRDP.otherMode.text_tlut ] );
377     DebuggerAppendMsg( "\ttext_lod:\t\t%s", gRDP.otherMode.text_lod ? "Yes": "No" );
378     DebuggerAppendMsg( "\ttext_detail:\t\t%s", gRDP.otherMode.text_detail ? "Yes": "No" );
379     DebuggerAppendMsg( "\ttext_sharpen:\t\t%s", gRDP.otherMode.text_sharpen ? "Yes": "No" );
380     DebuggerAppendMsg( "\ttext_persp:\t%s", gRDP.otherMode.text_persp ? "On" : "Off" );
381     DebuggerAppendMsg( "\tcycle_type:\t%s", cycletype[ gRDP.otherMode.cycle_type ] );
382     DebuggerAppendMsg( "\tpipeline:\t\t%s", gRDP.otherMode.atomic_prim ? "1Primitive" : "NPrimitive" );
383
384     DebuggerAppendMsg("\n\nSP render flags:");
385     DebuggerAppendMsg("\tCull mode: %s%s", gRSP.bCullFront?"Cull Front":"", gRSP.bCullBack?" Cull Back":"");
386     DebuggerAppendMsg("\tShade mode: %d", gRSP.shadeMode);
387     DebuggerAppendMsg("\tFog: %s", gRSP.bFogEnabled?"enabled":"disabled");
388     DebuggerAppendMsg("\tZbuffer in SP: %s", gRSP.bZBufferEnabled?"enabled":"disabled");
389     DebuggerAppendMsg("\tLighting: %s", gRSP.bLightingEnable?"enabled":"disabled");
390     DebuggerAppendMsg("\\Number of lights: %d", gRSPnumLights);
391     DebuggerAppendMsg("\tTexture Gen: %s", gRSP.bTextureGen?"enabled":"disabled");
392     DebuggerAppendMsg("\tTexture Gen Linear: %s", (gRDP.geometryMode & G_TEXTURE_GEN_LINEAR)?"enabled":"disabled");
393 }
394
395 void DumpCachedTexture(uint32 index)
396 {
397     TxtrCacheEntry *p = gTextureManager.GetCachedTexture(index);
398     if( p != NULL )
399     {
400         char filename[80];
401         sprintf(filename,"\\Texture%d_rgb", index);
402         CRender::GetRender()->SaveTextureToFile(*(p->pTexture), filename, TXT_RGB);
403         DebuggerAppendMsg("Display cached texture #%d of %d\n", index, gTextureManager.GetNumOfCachedTexture());
404         DebuggerAppendMsg("W:%d, H:%d, RealW:%d, RealH:%d, D3DW:%d, D3DH: %d", p->ti.WidthToCreate, p->ti.HeightToCreate,
405             p->ti.WidthToLoad, p->ti.HeightToLoad, p->pTexture->m_dwCreatedTextureWidth, p->pTexture->m_dwCreatedTextureHeight);
406         DebuggerAppendMsg("ScaledS:%s, ScaledT:%s", p->pTexture->m_bScaledS?"T":"F", p->pTexture->m_bScaledT?"T":"F");
407     }
408     else
409     {
410         DebuggerAppendMsg("No cached texture at index = %d\n", index);
411     }
412 }
413
414 extern uint32 gObjTlutAddr;
415 void DumpInfo(int thingToDump)
416 {
417     switch(thingToDump)
418     {
419     case DUMP_COLORS:
420         DebuggerAppendMsg("----Colors----\nPrim Color:\t%08X\nEnv Color:\t%08X\n"
421             "Fill Color:\t%08X\nFog Color:\t%08X\n"
422             "Prim Depth:\t%f\nPrim LOD Frac:\t%08X\n",
423         GetPrimitiveColor(), GetEnvColor(), gRDP.fillColor,
424         CRender::GetRender()->GetFogColor(), GetPrimitiveDepth(), GetLODFrac());
425         break;
426     case DUMP_CUR_MUX:
427         CRender::GetRender()->m_pColorCombiner->DisplayMuxString();
428         break;
429     case DUMP_LIGHT:
430         DebuggerAppendMsg("----Light Colors----\nNumber of Lights: %d\n",GetNumLights());
431         for( uint32 i=0; i<GetNumLights()+2; i++)
432         {
433             DebuggerAppendMsg("Light %d:\t%08X, (%d,%d,%d)\n", i, gRSPn64lights[i].dwRGBA,gRSPn64lights[i].x,gRSPn64lights[i].y,gRSPn64lights[i].z );
434         }
435         break;
436     case DUMP_TEXTURE_AT:
437         {
438         }
439         break;
440     case DUMP_CUR_TEXTURE_RGBA:
441         DumpTexture(gRSP.curTile, TXT_RGBA);
442         break;
443     case DUMP_CUR_1_TEXTURE_RGBA:
444         DumpTexture((1+gRSP.curTile)%7, TXT_RGBA);
445         break;
446     case DUMP_CUR_TEXTURE_RGB:
447         DumpTexture(gRSP.curTile, TXT_RGB);
448         break;
449     case DUMP_CUR_1_TEXTURE_RGB:
450         DumpTexture((1+gRSP.curTile)%7, TXT_RGB);
451         break;
452     case DUMP_CUR_TEXTURE_TO_FILE:
453         DumpTextureToFile(0,TXT_RGB);
454         DumpTextureToFile(0,TXT_ALPHA);
455         DumpTextureToFile(0,TXT_RGBA);
456         break;
457     case DUMP_CUR_1_TEXTURE_TO_FILE:
458         DumpTextureToFile(1,TXT_RGB);
459         DumpTextureToFile(1,TXT_ALPHA);
460         DumpTextureToFile(1,TXT_RGBA);
461         break;
462     case DUMP_CUR_TEXTURE_ALPHA:
463         DumpTexture(0, TXT_ALPHA);
464         break;
465     case DUMP_CUR_1_TEXTURE_ALPHA:
466         DumpTexture(1, TXT_ALPHA);
467         break;
468     case DUMP_TLUT:
469         DumpTlut(g_wRDPTlut);
470         break;
471     case DUMP_OBJ_TLUT:
472         DumpTlut((uint16*)(g_pRDRAMu8+gObjTlutAddr));
473         break;
474     case DUMP_TILE_AT:
475         {
476         }
477         break;
478     case DUMP_VERTEXES:
479         DumpVertexArray();
480         break;
481     case DUMP_VI_REGS:
482         DumpVIRegisters();
483         break;
484     case DUMP_SIMPLE_MUX:
485         CRender::GetRender()->m_pColorCombiner->DisplaySimpleMuxString();
486         break;
487     case DUMP_OTHER_MODE:
488         DumpOtherMode();
489         break;
490     case DUMP_FRAME_BUFFER:
491         CRender::GetRender()->DrawFrameBuffer(true);
492         break;
493     case DUMP_CONTENT_AT:
494         {
495         }
496         break;
497     case DUMP_DLIST_AT:
498         {
499         }
500         break;
501     case DUMP_MATRIX_AT:
502         {
503         }
504         break;
505     case DUMP_NEXT_TEX:
506         CachedTexIndex++;
507         if( CachedTexIndex >= gTextureManager.GetNumOfCachedTexture() )
508         {
509             CachedTexIndex = 0;
510         }
511         DumpCachedTexture(CachedTexIndex);
512         break;
513     case DUMP_PREV_TEX:     
514         CachedTexIndex--;
515         if( CachedTexIndex < 0 || CachedTexIndex >= gTextureManager.GetNumOfCachedTexture() )
516             CachedTexIndex = 0;
517         DumpCachedTexture(CachedTexIndex);
518         break;
519     case DUMP_CACHED_TEX:
520         DumpCachedTexture(CachedTexIndex);
521         break;
522     case DUMP_TEXBUFFER_AT:
523         {
524         }
525         break;
526     case DUMP_COMBINED_MATRIX:
527         DumpMatrix2(gRSPworldProject,"Combined Matrix");
528         break;
529     case DUMP_WORLD_TOP_MATRIX:
530         DumpMatrix2(gRSP.modelviewMtxs[gRSP.modelViewMtxTop],"World Top Matrix");
531         break;
532     case DUMP_WORLD_MATRIX_AT:
533         {
534         }
535         break;
536     case DUMP_PROJECTION_MATRIX:
537         DumpMatrix2(gRSP.projectionMtxs[gRSP.projectionMtxTop],"Projection Top Matrix");
538         break;
539     }
540 }
541
542
543 void SetLogToFile(bool log)
544 {
545     if( log )
546     {
547         if( logFp == NULL )
548         {
549             logFp = fopen("\\RiceVideo.log", "at");
550         }
551     }
552     else
553     {
554         if( logFp != NULL )
555         {
556             fclose(logFp);
557             logFp = NULL;
558         }
559     }
560 }
561
562
563 void __cdecl DebuggerAppendMsg(const char * Message, ...)
564 {
565     if( !logToScreen && !logToFile )
566         return;
567
568     char Msg[5000];
569     va_list ap;
570
571     va_start( ap, Message );
572     vsprintf( Msg, Message, ap );
573     va_end( ap );
574     
575     if( Msg[strlen(Msg)-1]!='\n' ) strcat(Msg,"\n");
576
577     if( logToScreen )
578     {
579         DebugMessage(M64MSG_INFO, "Rice Debug: %s", Msg);
580     }
581
582     if( logToFile )
583     {
584         fprintf(logFp, "%s\n", Msg);
585     }
586 }
587
588
589 void DebuggerPause()
590 {
591     while( debuggerPause )
592     {
593         if( debuggerDrawRenderTexture )
594         {
595             g_pFrameBufferManager->DisplayRenderTexture(debuggerDrawRenderTextureNo);
596             debuggerDrawRenderTexture = false;
597         }
598         usleep(100 * 1000);
599         debuggerPause = false;
600     }
601 }
602
603 void __cdecl LOG_UCODE(const char* szFormat, ...)
604 {
605     if( logUcodes)
606     {
607         char Msg[400];
608         va_list va;
609         va_start(va, szFormat);
610         vsprintf( Msg, szFormat, va );
611         va_end(va);
612         DebuggerAppendMsg("%s\n", Msg);
613     }
614 }
615
616 void DumpHex(uint32 rdramAddr, int count)
617 {
618     rdramAddr &= 0xFFFFFFF0;
619     uint32 *ptr = (uint32 *)((rdramAddr&(g_dwRamSize-1))+g_pRDRAMu8);
620
621     for( int i=0; i<(count+3)/4; i++)
622     {
623         DebuggerAppendMsg("%08X: %08X, %08X, %08X, %08X\n", 
624             rdramAddr+i*16, ptr[i*4], ptr[i*4+1], ptr[i*4+2], ptr[i*4+3]);
625     }
626     DebuggerAppendMsg("\n");
627 }
628
629 uint32 StrToHex(char *HexStr)
630 {
631     uint32 temp = 0;
632
633     for(uint32 k = 0; k < strlen(HexStr); k++)
634     {
635         if(HexStr[k] <= '9' && HexStr[k] >= '0')
636         {
637             temp = temp << 4;
638             temp += HexStr[k] - '0';
639         }
640         else if(HexStr[k] <= 'F' && HexStr[k] >= 'A')
641         {
642             temp = temp << 4;
643             temp += HexStr[k] - 'A' + 10;
644         }
645         else if(HexStr[k] <= 'f' && HexStr[k] >= 'a')
646         {
647             temp = temp << 4;
648             temp += HexStr[k] - 'a' + 10;
649         }
650         else
651         {
652             return(temp);
653         }
654     }
655
656     return(temp);
657 }
658
659 void DEBUGGER_PAUSE_COUNT_N(uint32 val)
660 {
661     if (eventToPause == (int)val)
662     {   
663         if(debuggerPauseCount>0) 
664             debuggerPauseCount--;
665         if(debuggerPauseCount==0)
666         {
667             CGraphicsContext::Get()->UpdateFrame();
668             debuggerPause = true;
669         }   
670     }
671 }
672
673 void DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(uint32 val)
674 {
675     if(eventToPause == (int)val)
676     {
677         if(debuggerPauseCount>0) 
678             debuggerPauseCount--;
679         if(debuggerPauseCount==0)
680         {
681             debuggerPauseCount = countToPause;
682             debuggerPause = true;
683         }   
684     }
685 }
686
687 void DumpMatrix2(const Matrix &mat, const char* prompt)
688 {
689     DebuggerAppendMsg(prompt);
690     DebuggerAppendMsg(
691         " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n"
692         " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n"
693         " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n"
694         " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\n",
695         mat.m[0][0], mat.m[0][1], mat.m[0][2], mat.m[0][3],
696         mat.m[1][0], mat.m[1][1], mat.m[1][2], mat.m[1][3],
697         mat.m[2][0], mat.m[2][1], mat.m[2][2], mat.m[2][3],
698         mat.m[3][0], mat.m[3][1], mat.m[3][2], mat.m[3][3]);
699 }
700
701 void DumpMatrix(const Matrix &mat, const char* prompt)
702 {
703     if( pauseAtNext && logMatrix )
704     {
705         DumpMatrix2(mat, prompt);
706     }
707 }
708
709 #endif
710