/[pcsx2_0.9.7]/trunk/tools/GSDumpGUI/Library/GSDXWrapper.cs
ViewVC logotype

Contents of /trunk/tools/GSDumpGUI/Library/GSDXWrapper.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 290 - (show annotations) (download)
Sat Dec 25 02:51:30 2010 UTC (9 years, 1 month ago) by william
File size: 22518 byte(s)
Auto Commited Import of: pcsx2-0.9.7-DEBUG (upstream: v0.9.7.4139 local: v0.9.7.283-latest) in ./trunk
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Runtime.InteropServices;
5 using System.IO;
6 using TCPLibrary.MessageBased.Core;
7 using System.Threading;
8
9 namespace GSDumpGUI
10 {
11 public delegate void GSgifTransfer(IntPtr data, int size);
12 public delegate void GSgifTransfer1(IntPtr data, int size);
13 public delegate void GSgifTransfer2(IntPtr data, int size);
14 public delegate void GSgifTransfer3(IntPtr data, int size);
15 public delegate void GSVSync(byte field);
16 public delegate void GSreset();
17 public delegate void GSreadFIFO2(IntPtr data, int size);
18 public delegate void GSsetGameCRC(int crc, int options);
19 public delegate int GSfreeze(int mode, IntPtr data);
20 public delegate void GSopen(IntPtr hwnd, String Title, int renderer);
21 public delegate void GSclose();
22 public delegate void GSshutdown();
23 public delegate void GSConfigure();
24 public delegate void GSsetBaseMem(IntPtr data);
25 public delegate IntPtr PSEgetLibName();
26 public delegate void GSinit();
27
28 public class GSDXWrapper
29 {
30 static public bool DumpTooOld = false;
31
32 private GSConfigure gsConfigure;
33 private PSEgetLibName PsegetLibName;
34 private GSgifTransfer GSgifTransfer;
35 private GSgifTransfer1 GSgifTransfer1;
36 private GSgifTransfer2 GSgifTransfer2;
37 private GSgifTransfer3 GSgifTransfer3;
38 private GSVSync GSVSync;
39 private GSreadFIFO2 GSreadFIFO2;
40 private GSsetGameCRC GSsetGameCRC;
41 private GSfreeze GSfreeze;
42 private GSopen GSopen;
43 private GSclose GSclose;
44 private GSshutdown GSshutdown;
45 private GSsetBaseMem GSsetBaseMem;
46 private GSinit GSinit;
47 private GSreset GSreset;
48
49 private Boolean Loaded;
50
51 private String DLL;
52 private IntPtr DLLAddr;
53
54 private Boolean Running;
55
56 public Queue<TCPMessage> QueueMessage;
57 public Boolean DebugMode;
58 public GSData CurrentGIFPacket;
59 public bool ThereIsWork;
60 public AutoResetEvent ExternalEvent;
61 public int RunTo;
62
63 static public Boolean IsValidGSDX(String DLL)
64 {
65 NativeMethods.SetErrorMode(0x8007);
66 Boolean Ris = true;
67
68 Directory.SetCurrentDirectory(Path.GetDirectoryName(DLL));
69 IntPtr hmod = NativeMethods.LoadLibrary(DLL);
70 if (hmod.ToInt64() > 0)
71 {
72 IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PS2EgetLibName");
73 IntPtr funcaddrConfig = NativeMethods.GetProcAddress(hmod, "GSconfigure");
74
75 IntPtr funcaddrGIF = NativeMethods.GetProcAddress(hmod, "GSgifTransfer");
76 IntPtr funcaddrVSync = NativeMethods.GetProcAddress(hmod, "GSvsync");
77 IntPtr funcaddrSetBaseMem = NativeMethods.GetProcAddress(hmod, "GSsetBaseMem");
78 IntPtr funcaddrOpen = NativeMethods.GetProcAddress(hmod, "GSopen");
79 IntPtr funcaddrSetCRC = NativeMethods.GetProcAddress(hmod, "GSsetGameCRC");
80 IntPtr funcaddrClose = NativeMethods.GetProcAddress(hmod, "GSclose");
81 IntPtr funcaddrShutdown = NativeMethods.GetProcAddress(hmod, "GSshutdown");
82 IntPtr funcaddrFreeze = NativeMethods.GetProcAddress(hmod, "GSfreeze");
83 IntPtr funcaddrGSreadFIFO2 = NativeMethods.GetProcAddress(hmod, "GSreadFIFO2");
84 IntPtr funcaddrinit = NativeMethods.GetProcAddress(hmod, "GSinit");
85
86 NativeMethods.FreeLibrary(hmod);
87 if (!((funcaddrConfig.ToInt64() > 0) && (funcaddrLibName.ToInt64() > 0) && (funcaddrGIF.ToInt64() > 0)))
88 {
89 Int32 id = NativeMethods.GetLastError();
90 System.IO.File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "log.txt", DLL + " failed to load. Error " + id + Environment.NewLine);
91 Ris = false;
92 }
93 }
94 else
95 {
96 Int32 id = NativeMethods.GetLastError();
97 System.IO.File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "log.txt", DLL + " failed to load. Error " + id + Environment.NewLine);
98 Ris = false;
99 }
100
101 NativeMethods.SetErrorMode(0x0000);
102 return Ris;
103 }
104
105 public void Load(String DLL)
106 {
107 this.DLL = DLL;
108 NativeMethods.SetErrorMode(0x8007);
109
110 if (!IsValidGSDX(DLL))
111 throw new Exception("Invalid GSDX DLL");
112
113 if (Loaded)
114 Unload();
115
116 Loaded = true;
117 Directory.SetCurrentDirectory(Path.GetDirectoryName(DLL));
118 IntPtr hmod = NativeMethods.LoadLibrary(DLL);
119 if (hmod.ToInt64() > 0)
120 {
121 IntPtr funcaddrLibName = NativeMethods.GetProcAddress(hmod, "PS2EgetLibName");
122 IntPtr funcaddrConfig = NativeMethods.GetProcAddress(hmod, "GSconfigure");
123
124 IntPtr funcaddrGIF = NativeMethods.GetProcAddress(hmod, "GSgifTransfer");
125 IntPtr funcaddrGIF1 = NativeMethods.GetProcAddress(hmod, "GSgifTransfer1");
126 IntPtr funcaddrGIF2 = NativeMethods.GetProcAddress(hmod, "GSgifTransfer2");
127 IntPtr funcaddrGIF3 = NativeMethods.GetProcAddress(hmod, "GSgifTransfer3");
128 IntPtr funcaddrVSync = NativeMethods.GetProcAddress(hmod, "GSvsync");
129 IntPtr funcaddrSetBaseMem = NativeMethods.GetProcAddress(hmod, "GSsetBaseMem");
130 IntPtr funcaddrGSReset = NativeMethods.GetProcAddress(hmod, "GSreset");
131 IntPtr funcaddrOpen = NativeMethods.GetProcAddress(hmod, "GSopen");
132 IntPtr funcaddrSetCRC = NativeMethods.GetProcAddress(hmod, "GSsetGameCRC");
133 IntPtr funcaddrClose = NativeMethods.GetProcAddress(hmod, "GSclose");
134 IntPtr funcaddrShutdown = NativeMethods.GetProcAddress(hmod, "GSshutdown");
135 IntPtr funcaddrFreeze = NativeMethods.GetProcAddress(hmod, "GSfreeze");
136 IntPtr funcaddrGSreadFIFO2 = NativeMethods.GetProcAddress(hmod, "GSreadFIFO2");
137 IntPtr funcaddrinit = NativeMethods.GetProcAddress(hmod, "GSinit");
138
139 gsConfigure = (GSConfigure)Marshal.GetDelegateForFunctionPointer(funcaddrConfig, typeof(GSConfigure));
140 PsegetLibName = (PSEgetLibName)Marshal.GetDelegateForFunctionPointer(funcaddrLibName, typeof(PSEgetLibName));
141
142 this.GSgifTransfer = (GSgifTransfer)Marshal.GetDelegateForFunctionPointer(funcaddrGIF, typeof(GSgifTransfer));
143 this.GSgifTransfer1 = (GSgifTransfer1)Marshal.GetDelegateForFunctionPointer(funcaddrGIF1, typeof(GSgifTransfer1));
144 this.GSgifTransfer2 = (GSgifTransfer2)Marshal.GetDelegateForFunctionPointer(funcaddrGIF2, typeof(GSgifTransfer2));
145 this.GSgifTransfer3 = (GSgifTransfer3)Marshal.GetDelegateForFunctionPointer(funcaddrGIF3, typeof(GSgifTransfer3));
146 this.GSVSync = (GSVSync)Marshal.GetDelegateForFunctionPointer(funcaddrVSync, typeof(GSVSync));
147 this.GSsetBaseMem = (GSsetBaseMem)Marshal.GetDelegateForFunctionPointer(funcaddrSetBaseMem, typeof(GSsetBaseMem));
148 this.GSopen = (GSopen)Marshal.GetDelegateForFunctionPointer(funcaddrOpen, typeof(GSopen));
149 this.GSsetGameCRC = (GSsetGameCRC)Marshal.GetDelegateForFunctionPointer(funcaddrSetCRC, typeof(GSsetGameCRC));
150 this.GSclose = (GSclose)Marshal.GetDelegateForFunctionPointer(funcaddrClose, typeof(GSclose));
151 this.GSshutdown = (GSshutdown)Marshal.GetDelegateForFunctionPointer(funcaddrShutdown, typeof(GSshutdown));
152 this.GSfreeze = (GSfreeze)Marshal.GetDelegateForFunctionPointer(funcaddrFreeze, typeof(GSfreeze));
153 this.GSreset = (GSreset)Marshal.GetDelegateForFunctionPointer(funcaddrGSReset, typeof(GSreset));
154 this.GSreadFIFO2 = (GSreadFIFO2)Marshal.GetDelegateForFunctionPointer(funcaddrGSreadFIFO2, typeof(GSreadFIFO2));
155 this.GSinit = (GSinit)Marshal.GetDelegateForFunctionPointer(funcaddrinit, typeof(GSinit));
156
157 DLLAddr = hmod;
158 }
159 NativeMethods.SetErrorMode(0x0000);
160 }
161
162 public void Unload()
163 {
164 NativeMethods.FreeLibrary(DLLAddr);
165 Loaded = false;
166 }
167
168 public void GSConfig()
169 {
170 if (!Loaded)
171 throw new Exception("GSDX is not loaded");
172 gsConfigure.Invoke();
173 }
174
175 public String PSEGetLibName()
176 {
177 if (!Loaded)
178 throw new Exception("GSDX is not loaded");
179 return Marshal.PtrToStringAnsi(PsegetLibName.Invoke());
180 }
181
182 public unsafe void Run(GSDump dump, int rendererOverride)
183 {
184 QueueMessage = new Queue<TCPMessage>();
185 Running = true;
186 ExternalEvent = new AutoResetEvent(true);
187
188 GSinit();
189 byte[] tempregisters = new byte[8192];
190 Array.Copy(dump.Registers, tempregisters, 8192);
191 fixed (byte* pointer = tempregisters)
192 {
193 GSsetBaseMem(new IntPtr(pointer));
194 Int32 HWND = 0;
195 GSopen(new IntPtr(&HWND), "", rendererOverride);
196 GSsetGameCRC(dump.CRC, 0);
197
198 fixed (byte* freeze = dump.StateData)
199 {
200 byte[] GSFreez = new byte[8];
201 Array.Copy(BitConverter.GetBytes(dump.StateData.Length), 0, GSFreez, 0, 4);
202 Array.Copy(BitConverter.GetBytes(new IntPtr(freeze).ToInt32()), 0, GSFreez, 4, 4);
203
204 fixed (byte* fr = GSFreez)
205 {
206 int ris = GSfreeze(0, new IntPtr(fr));
207 if (ris == -1)
208 {
209 DumpTooOld = true;
210 return;
211 }
212 GSVSync(1);
213
214 while (Running)
215 {
216 if (!NativeMethods.IsWindowVisible(new IntPtr(HWND)))
217 {
218 Running = false;
219 break;
220 }
221
222 GSreset();
223 Marshal.Copy(dump.Registers, 0, new IntPtr(pointer), 8192);
224 GSsetBaseMem(new IntPtr(pointer));
225 GSfreeze(0, new IntPtr(fr));
226
227 for (int i = 0; i < dump.Data.Count; i++)
228 {
229 GSData itm = dump.Data[i];
230 CurrentGIFPacket = itm;
231
232 if (DebugMode)
233 {
234 if (RunTo != -1)
235 {
236 if (i == RunTo)
237 {
238 RunTo = -1;
239 int idxnextReg = dump.Data.FindIndex(i, a => a.id == GSType.Registers);
240 if (idxnextReg != -1)
241 {
242 Step(dump.Data[idxnextReg], pointer);
243 }
244
245 GSData g = new GSData();
246 g.id = GSType.VSync;
247 Step(g, pointer);
248
249 TCPMessage Msg = new TCPMessage();
250 Msg.MessageType = MessageType.RunToCursor;
251 Msg.Parameters.Add(i);
252 Program.Client.Send(Msg);
253
254 ExternalEvent.Set();
255 }
256 else
257 {
258 Step(itm, pointer);
259 }
260 }
261 else
262 {
263 while (!ThereIsWork && Running)
264 {
265 NativeMessage message;
266 while (NativeMethods.PeekMessage(out message, IntPtr.Zero, 0, 0, 1))
267 {
268 if (!NativeMethods.IsWindowVisible(new IntPtr(HWND)))
269 {
270 Running = false;
271 }
272 NativeMethods.TranslateMessage(ref message);
273 NativeMethods.DispatchMessage(ref message);
274 }
275 }
276
277 ThereIsWork = false;
278 if (QueueMessage.Count > 0)
279 {
280 TCPMessage Mess = QueueMessage.Dequeue();
281 switch (Mess.MessageType)
282 {
283 case MessageType.Step:
284 RunTo = i;
285 break;
286 case MessageType.RunToCursor:
287 RunTo = (int)Mess.Parameters[0];
288 break;
289 case MessageType.RunToNextVSync:
290 RunTo = dump.Data.FindIndex(i, a => a.id == GSType.VSync);
291 break;
292 default:
293 break;
294 }
295 break;
296 }
297 }
298 }
299 else
300 {
301 Step(itm, pointer);
302 }
303 }
304 }
305
306 GSclose();
307 GSshutdown();
308 }
309 }
310 }
311 }
312
313 private unsafe void Step(GSData itm, byte* registers)
314 {
315 /*"C:\Users\Alessio\Desktop\Plugins\Dll\GSdx-SSE4.dll" "C:\Users\Alessio\Desktop\Plugins\Dumps\gsdx_20101222215004.gs" "GSReplay" 0*/
316 switch (itm.id)
317 {
318 case GSType.Transfer:
319 switch (((GSTransfer)itm).Path)
320 {
321 case GSTransferPath.Path1Old:
322 byte[] data = new byte[16384];
323 int addr = 16384 - itm.data.Length;
324 Array.Copy(itm.data, 0, data, addr, itm.data.Length);
325 fixed (byte* gifdata = data)
326 {
327 GSgifTransfer1(new IntPtr(gifdata), addr);
328 }
329 break;
330 case GSTransferPath.Path2:
331 fixed (byte* gifdata = itm.data)
332 {
333 GSgifTransfer2(new IntPtr(gifdata), (itm.data.Length) / 16);
334 }
335 break;
336 case GSTransferPath.Path3:
337 fixed (byte* gifdata = itm.data)
338 {
339 GSgifTransfer3(new IntPtr(gifdata), (itm.data.Length) / 16);
340 }
341 break;
342 case GSTransferPath.Path1New:
343 fixed (byte* gifdata = itm.data)
344 {
345 GSgifTransfer(new IntPtr(gifdata), (itm.data.Length) / 16);
346 }
347 break;
348 }
349 break;
350 case GSType.VSync:
351 GSVSync((*((int*)(registers + 4096)) & 0x2000) > 0 ? (byte)1 : (byte)0);
352 break;
353 case GSType.ReadFIFO2:
354 fixed (byte* FIFO = itm.data)
355 {
356 byte[] arrnew = new byte[*((int*)FIFO)];
357 fixed (byte* arrn = arrnew)
358 {
359 GSreadFIFO2(new IntPtr(arrn), *((int*)FIFO));
360 }
361 }
362 break;
363 case GSType.Registers:
364 Marshal.Copy(itm.data, 0, new IntPtr(registers), 8192);
365 break;
366 default:
367 break;
368 }
369 }
370
371 public void Stop()
372 {
373 Running = false;
374 }
375
376 internal List<Object> GetGifPackets(GSDump dump)
377 {
378 List<Object> Data = new List<Object>();
379 for (int i = 0; i < dump.Data.Count; i++)
380 {
381 String act = i.ToString() + "|";
382 act += dump.Data[i].id.ToString() + "|";
383 if (dump.Data[i].GetType().IsSubclassOf(typeof(GSData)))
384 {
385 act += ((GSTransfer)dump.Data[i]).Path.ToString() + "|";
386 act += ((GSTransfer)dump.Data[i]).data.Length;
387 }
388 else
389 {
390 act += ((GSData)dump.Data[i]).data.Length;
391 }
392 Data.Add(act);
393 }
394 return Data;
395 }
396
397 internal String GetGifPacketInfo(GSDump dump, int i)
398 {
399 string val = dump.Data[i].data.Length.ToString() + "|";
400
401 switch (dump.Data[i].id)
402 {
403 case GSType.Transfer:
404 GIFTag tag = ExtractGifTag(dump.Data[i].data);
405 val += "Transfer Path " + ((GSTransfer)dump.Data[i]).Path.ToString() + "|";
406 val += "NLoop = " + tag.nloop + "|";
407 //val += "Pad1 = " + tag._pad1 + "|";
408 //val += "Pad2 = " + tag._pad2 + "|";
409 val += "eop = " + tag.eop + "|";
410 val += "flg = " + ((GIFFLG)tag.flg).ToString() + "|";
411 val += "pre = " + tag.pre + "|";
412 val += "prim~Prim Class = " + ((GS_PRIM)tag.prim.Prim).ToString() + "~IIP = " + tag.prim.IIP + "~TME = "+ tag.prim.TME + "~FGE = "+ tag.prim.FGE + "~ABE = "+
413 tag.prim.ABE + "~AA1 = "+ tag.prim.AA1 + "~FST = "+ tag.prim.FST + "~CTXT = " + tag.prim.CTXT + "~FIX = " + tag.prim.FIX + "|";
414 val += "nreg = " + (tag.nreg == 0 ? 16 : tag.nreg) + "|";
415 val += "regs~ ";
416 foreach (var itm in tag.regs)
417 val += itm.Descriptor.ToString() + "~";
418 break;
419 case GSType.VSync:
420 val += "Field = " + dump.Data[i].data[0].ToString();
421 break;
422 case GSType.ReadFIFO2:
423 val += "ReadFIFO2 : Size = " + BitConverter.ToInt32(dump.Data[i].data, 0).ToString() + " byte";
424 break;
425 case GSType.Registers:
426 val += "Registers";
427 break;
428 default:
429 break;
430 }
431
432 return val;
433 }
434
435 internal GIFTag ExtractGifTag(byte[] data)
436 {
437 Int16 nloopEOP = 0;
438 Int16 pad1 = 0;
439 Int32 pad2PrePrimFlgNReg = 0;
440 Int64 regs = 0;
441
442 nloopEOP = BitConverter.ToInt16(data, 0);
443 pad1 = BitConverter.ToInt16(data, 2);
444 pad2PrePrimFlgNReg = BitConverter.ToInt32(data, 4);
445 regs = BitConverter.ToInt64(data, 8);
446
447 GIFTag t = new GIFTag();
448 t.nloop = (nloopEOP & 0x7FFF);
449 t.eop = (nloopEOP & 0x8000) >> 15;
450 t._pad1 = pad1;
451 t._pad2 = (pad2PrePrimFlgNReg & 0x00003FFF);
452 t.pre = (pad2PrePrimFlgNReg & 0x00004000) >> 14;
453
454 int prim = (pad2PrePrimFlgNReg & 0x03FF8000) >> 15;
455 GIFPrim pri = new GIFPrim();
456 pri.Prim = (prim & 0x007);
457 pri.IIP = (prim & 0x008) >> 3;
458 pri.TME = (prim & 0x010) >> 4;
459 pri.FGE = (prim & 0x020) >> 5;
460 pri.ABE = (prim & 0x040) >> 6;
461 pri.AA1 = (prim & 0x080) >> 7;
462 pri.FST = (prim & 0x100) >> 8;
463 pri.CTXT = (prim & 0x200) >> 9;
464 pri.FIX = (prim & 0x400) >> 10;
465 t.prim = pri;
466
467 t.flg = (pad2PrePrimFlgNReg & 0xC000000) >> 26;
468 t.nreg = (int)(pad2PrePrimFlgNReg & 0xF0000000) >> 28;
469
470 t.regs = new List<GIFReg>();
471 for (int i = 0; i < t.nreg; i++)
472 {
473 GIFReg reg = new GIFReg();
474 reg.Descriptor = (GIFRegDescriptor)((regs & (Convert.ToInt32(Math.Pow(16, i + 1)) - 1)) >> i*4);
475 t.regs.Add(reg);
476 }
477 return t;
478 }
479 }
480 }

  ViewVC Help
Powered by ViewVC 1.1.22