/[pcsx2_0.9.7]/trunk/pcsx2/PluginManager.cpp
ViewVC logotype

Diff of /trunk/pcsx2/PluginManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 273 by william, Fri Nov 12 01:10:22 2010 UTC revision 280 by william, Thu Dec 23 12:02:12 2010 UTC
# Line 1  Line 1 
1  /*  PCSX2 - PS2 Emulator for PCs  /*  PCSX2 - PS2 Emulator for PCs
2   *  Copyright (C) 2002-2010  PCSX2 Dev Team   *  Copyright (C) 2002-2010  PCSX2 Dev Team
3   *   *
4   *  PCSX2 is free software: you can redistribute it and/or modify it under the terms   *  PCSX2 is free software: you can redistribute it and/or modify it under the terms
5   *  of the GNU Lesser General Public License as published by the Free Software Found-   *  of the GNU Lesser General Public License as published by the Free Software Found-
6   *  ation, either version 3 of the License, or (at your option) any later version.   *  ation, either version 3 of the License, or (at your option) any later version.
7   *   *
8   *  PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;   *  PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9   *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR   *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10   *  PURPOSE.  See the GNU General Public License for more details.   *  PURPOSE.  See the GNU General Public License for more details.
11   *   *
12   *  You should have received a copy of the GNU General Public License along with PCSX2.   *  You should have received a copy of the GNU General Public License along with PCSX2.
13   *  If not, see <http://www.gnu.org/licenses/>.   *  If not, see <http://www.gnu.org/licenses/>.
14   */   */
15    
16  #include "PrecompiledHeader.h"  #include "PrecompiledHeader.h"
17  #include "IopCommon.h"  #include "IopCommon.h"
18    
19  #include <wx/dir.h>  #include <wx/dir.h>
20  #include <wx/file.h>  #include <wx/file.h>
21    
22  #include "GS.h"  #include "GS.h"
23  #include "CDVD/CDVDisoReader.h"  #include "CDVD/CDVDisoReader.h"
24    
25  #include "Utilities/ScopedPtr.h"  #include "Utilities/ScopedPtr.h"
26    
27  #if _MSC_VER  #if _MSC_VER
28  #       include "svnrev.h"  #       include "svnrev.h"
29  #endif  #endif
30    
31  SysPluginBindings SysPlugins;  SysPluginBindings SysPlugins;
32    
33  bool SysPluginBindings::McdIsPresent( uint port, uint slot )  bool SysPluginBindings::McdIsPresent( uint port, uint slot )
34  {  {
35          return !!Mcd->McdIsPresent( (PS2E_THISPTR) Mcd, port, slot );          return !!Mcd->McdIsPresent( (PS2E_THISPTR) Mcd, port, slot );
36  }  }
37    
38  void SysPluginBindings::McdGetSizeInfo( uint port, uint slot, PS2E_McdSizeInfo& outways )  void SysPluginBindings::McdGetSizeInfo( uint port, uint slot, PS2E_McdSizeInfo& outways )
39  {  {
40          if( Mcd->McdGetSizeInfo )          if( Mcd->McdGetSizeInfo )
41                  Mcd->McdGetSizeInfo( (PS2E_THISPTR) Mcd, port, slot, &outways );                  Mcd->McdGetSizeInfo( (PS2E_THISPTR) Mcd, port, slot, &outways );
42  }  }
43    
44  void SysPluginBindings::McdRead( uint port, uint slot, u8 *dest, u32 adr, int size )  void SysPluginBindings::McdRead( uint port, uint slot, u8 *dest, u32 adr, int size )
45  {  {
46          Mcd->McdRead( (PS2E_THISPTR) Mcd, port, slot, dest, adr, size );          Mcd->McdRead( (PS2E_THISPTR) Mcd, port, slot, dest, adr, size );
47  }  }
48    
49  void SysPluginBindings::McdSave( uint port, uint slot, const u8 *src, u32 adr, int size )  void SysPluginBindings::McdSave( uint port, uint slot, const u8 *src, u32 adr, int size )
50  {  {
51          Mcd->McdSave( (PS2E_THISPTR) Mcd, port, slot, src, adr, size );          Mcd->McdSave( (PS2E_THISPTR) Mcd, port, slot, src, adr, size );
52  }  }
53    
54  void SysPluginBindings::McdEraseBlock( uint port, uint slot, u32 adr )  void SysPluginBindings::McdEraseBlock( uint port, uint slot, u32 adr )
55  {  {
56          Mcd->McdEraseBlock( (PS2E_THISPTR) Mcd, port, slot, adr );          Mcd->McdEraseBlock( (PS2E_THISPTR) Mcd, port, slot, adr );
57  }  }
58    
59  u64 SysPluginBindings::McdGetCRC( uint port, uint slot )  u64 SysPluginBindings::McdGetCRC( uint port, uint slot )
60  {  {
61          return Mcd->McdGetCRC( (PS2E_THISPTR) Mcd, port, slot );          return Mcd->McdGetCRC( (PS2E_THISPTR) Mcd, port, slot );
62  }  }
63    
64    
65  // ----------------------------------------------------------------------------  // ----------------------------------------------------------------------------
66  // Yay, order of this array shouldn't be important. :)  // Yay, order of this array shouldn't be important. :)
67  //  //
68  const PluginInfo tbl_PluginInfo[] =  const PluginInfo tbl_PluginInfo[] =
69  {  {
70          { "GS",         PluginId_GS,    PS2E_LT_GS,             PS2E_GS_VERSION         },          { "GS",         PluginId_GS,    PS2E_LT_GS,             PS2E_GS_VERSION         },
71          { "PAD",        PluginId_PAD,   PS2E_LT_PAD,    PS2E_PAD_VERSION        },          { "PAD",        PluginId_PAD,   PS2E_LT_PAD,    PS2E_PAD_VERSION        },
72          { "SPU2",       PluginId_SPU2,  PS2E_LT_SPU2,   PS2E_SPU2_VERSION       },          { "SPU2",       PluginId_SPU2,  PS2E_LT_SPU2,   PS2E_SPU2_VERSION       },
73          { "CDVD",       PluginId_CDVD,  PS2E_LT_CDVD,   PS2E_CDVD_VERSION       },          { "CDVD",       PluginId_CDVD,  PS2E_LT_CDVD,   PS2E_CDVD_VERSION       },
74          { "USB",        PluginId_USB,   PS2E_LT_USB,    PS2E_USB_VERSION        },          { "USB",        PluginId_USB,   PS2E_LT_USB,    PS2E_USB_VERSION        },
75          { "FW",         PluginId_FW,    PS2E_LT_FW,             PS2E_FW_VERSION         },          { "FW",         PluginId_FW,    PS2E_LT_FW,             PS2E_FW_VERSION         },
76          { "DEV9",       PluginId_DEV9,  PS2E_LT_DEV9,   PS2E_DEV9_VERSION       },          { "DEV9",       PluginId_DEV9,  PS2E_LT_DEV9,   PS2E_DEV9_VERSION       },
77    
78          { NULL },          { NULL },
79    
80          // See PluginEnums_t for details on the MemoryCard plugin hack.          // See PluginEnums_t for details on the MemoryCard plugin hack.
81          { "Mcd",        PluginId_Mcd,   0,      0       },          { "Mcd",        PluginId_Mcd,   0,      0       },
82  };  };
83    
84  typedef void CALLBACK VoidMethod();  typedef void CALLBACK VoidMethod();
85  typedef void CALLBACK vMeth();          // shorthand for VoidMethod  typedef void CALLBACK vMeth();          // shorthand for VoidMethod
86    
87  // ----------------------------------------------------------------------------  // ----------------------------------------------------------------------------
88  struct LegacyApi_CommonMethod  struct LegacyApi_CommonMethod
89  {  {
90          const char*             MethodName;          const char*             MethodName;
91    
92          // fallback is used if the method is null.  If the method is null and fallback is null          // fallback is used if the method is null.  If the method is null and fallback is null
93          // also, the plugin is considered incomplete or invalid, and an error is generated.          // also, the plugin is considered incomplete or invalid, and an error is generated.
94          VoidMethod*     Fallback;          VoidMethod*     Fallback;
95    
96          // returns the method name as a wxString, converted from UTF8.          // returns the method name as a wxString, converted from UTF8.
97          wxString GetMethodName( PluginsEnum_t pid ) const          wxString GetMethodName( PluginsEnum_t pid ) const
98          {          {
99                  return tbl_PluginInfo[pid].GetShortname() + fromUTF8( MethodName );                  return tbl_PluginInfo[pid].GetShortname() + fromUTF8( MethodName );
100          }          }
101  };  };
102    
103  // ----------------------------------------------------------------------------  // ----------------------------------------------------------------------------
104  struct LegacyApi_ReqMethod  struct LegacyApi_ReqMethod
105  {  {
106          const char*             MethodName;          const char*             MethodName;
107          VoidMethod**    Dest;           // Target function where the binding is saved.          VoidMethod**    Dest;           // Target function where the binding is saved.
108    
109          // fallback is used if the method is null.  If the method is null and fallback is null          // fallback is used if the method is null.  If the method is null and fallback is null
110          // also, the plugin is considered incomplete or invalid, and an error is generated.          // also, the plugin is considered incomplete or invalid, and an error is generated.
111          VoidMethod*     Fallback;          VoidMethod*     Fallback;
112    
113          // returns the method name as a wxString, converted from UTF8.          // returns the method name as a wxString, converted from UTF8.
114          wxString GetMethodName( ) const          wxString GetMethodName( ) const
115          {          {
116                  return fromUTF8( MethodName );                  return fromUTF8( MethodName );
117          }          }
118  };  };
119    
120  // ----------------------------------------------------------------------------  // ----------------------------------------------------------------------------
121  struct LegacyApi_OptMethod  struct LegacyApi_OptMethod
122  {  {
123          const char*             MethodName;          const char*             MethodName;
124          VoidMethod**    Dest;           // Target function where the binding is saved.          VoidMethod**    Dest;           // Target function where the binding is saved.
125    
126          // returns the method name as a wxString, converted from UTF8.          // returns the method name as a wxString, converted from UTF8.
127          wxString GetMethodName() const { return fromUTF8( MethodName ); }          wxString GetMethodName() const { return fromUTF8( MethodName ); }
128  };  };
129    
130    
131  static s32  CALLBACK fallback_freeze(int mode, freezeData *data)  static s32  CALLBACK fallback_freeze(int mode, freezeData *data)
132  {  {
133          if( mode == FREEZE_SIZE ) data->size = 0;          if( mode == FREEZE_SIZE ) data->size = 0;
134          return 0;          return 0;
135  }  }
136    
137  static void CALLBACK fallback_keyEvent(keyEvent *ev) {}  static void CALLBACK fallback_keyEvent(keyEvent *ev) {}
138  static void CALLBACK fallback_setSettingsDir(const char* dir) {}  static void CALLBACK fallback_setSettingsDir(const char* dir) {}
139  static void CALLBACK fallback_setLogDir(const char* dir) {}  static void CALLBACK fallback_setLogDir(const char* dir) {}
140  static void CALLBACK fallback_configure() {}  static void CALLBACK fallback_configure() {}
141  static void CALLBACK fallback_about() {}  static void CALLBACK fallback_about() {}
142  static s32  CALLBACK fallback_test() { return 0; }  static s32  CALLBACK fallback_test() { return 0; }
143    
144  _GSvsync           GSvsync;  _GSvsync           GSvsync;
145  _GSopen            GSopen;  _GSopen            GSopen;
146  _GSopen2           GSopen2;  _GSopen2           GSopen2;
147  _GSgifTransfer     GSgifTransfer;  _GSgifTransfer     GSgifTransfer;
148  _GSgifTransfer1    GSgifTransfer1;  _GSgifTransfer1    GSgifTransfer1;
149  _GSgifTransfer2    GSgifTransfer2;  _GSgifTransfer2    GSgifTransfer2;
150  _GSgifTransfer3    GSgifTransfer3;  _GSgifTransfer3    GSgifTransfer3;
151  _GSgifSoftReset    GSgifSoftReset;  _GSgifSoftReset    GSgifSoftReset;
152  _GSreadFIFO        GSreadFIFO;  _GSreadFIFO        GSreadFIFO;
153  _GSreadFIFO2       GSreadFIFO2;  _GSreadFIFO2       GSreadFIFO2;
154  _GSchangeSaveState GSchangeSaveState;  _GSchangeSaveState GSchangeSaveState;
155  _GSgetTitleInfo    GSgetTitleInfo;  _GSgetTitleInfo2   GSgetTitleInfo2;
156  _GSmakeSnapshot    GSmakeSnapshot;  _GSmakeSnapshot    GSmakeSnapshot;
157  _GSmakeSnapshot2   GSmakeSnapshot2;  _GSmakeSnapshot2   GSmakeSnapshot2;
158  _GSirqCallback     GSirqCallback;  _GSirqCallback     GSirqCallback;
159  _GSprintf          GSprintf;  _GSprintf          GSprintf;
160  _GSsetBaseMem           GSsetBaseMem;  _GSsetBaseMem           GSsetBaseMem;
161  _GSsetGameCRC           GSsetGameCRC;  _GSsetGameCRC           GSsetGameCRC;
162  _GSsetFrameSkip         GSsetFrameSkip;  _GSsetFrameSkip         GSsetFrameSkip;
163  _GSsetVsync                     GSsetVsync;  _GSsetVsync                     GSsetVsync;
164  _GSsetExclusive         GSsetExclusive;  _GSsetExclusive         GSsetExclusive;
165  _GSsetupRecording       GSsetupRecording;  _GSsetupRecording       GSsetupRecording;
166  _GSreset                        GSreset;  _GSreset                        GSreset;
167  _GSwriteCSR                     GSwriteCSR;  _GSwriteCSR                     GSwriteCSR;
168    
169  static void CALLBACK GS_makeSnapshot(const char *path) {}  static void CALLBACK GS_makeSnapshot(const char *path) {}
170  static void CALLBACK GS_setGameCRC(u32 crc, int gameopts) {}  static void CALLBACK GS_setGameCRC(u32 crc, int gameopts) {}
171  static void CALLBACK GS_irqCallback(void (*callback)()) {}  static void CALLBACK GS_irqCallback(void (*callback)()) {}
172  static void CALLBACK GS_setFrameSkip(int frameskip) {}  static void CALLBACK GS_setFrameSkip(int frameskip) {}
173  static void CALLBACK GS_setVsync(int enabled) {}  static void CALLBACK GS_setVsync(int enabled) {}
174  static void CALLBACK GS_setExclusive(int isExcl) {}  static void CALLBACK GS_setExclusive(int isExcl) {}
175  static void CALLBACK GS_changeSaveState( int, const char* filename ) {}  static void CALLBACK GS_changeSaveState( int, const char* filename ) {}
176  static void CALLBACK GS_printf(int timeout, char *fmt, ...)  static void CALLBACK GS_printf(int timeout, char *fmt, ...)
177  {  {
178          va_list list;          va_list list;
179          char msg[512];          char msg[512];
180    
181          va_start(list, fmt);          va_start(list, fmt);
182          vsprintf(msg, fmt, list);          vsprintf(msg, fmt, list);
183          va_end(list);          va_end(list);
184    
185          Console.WriteLn(msg);          Console.WriteLn(msg);
186  }  }
187    
188  void CALLBACK GS_getTitleInfo( char dest[128] )  void CALLBACK GS_getTitleInfo2( char* dest, size_t length )
189  {  {
190          dest[0] = 'G';          // Just return a generic "GS" title -- a plugin actually implementing this feature
191          dest[1] = 'S';          // should return a title such as "GSdx" or "ZZogl" instead.  --air
192          dest[2] = 0;  
193  }          dest[0] = 'G';
194            dest[1] = 'S';
195  // This legacy passthrough function is needed because the old GS plugins tended to assume that          dest[2] = 0;
196  // a PATH1 transfer that didn't EOP needed an automatic EOP (which was needed to avoid a crash  }
197  // in the BIOS when it starts an XGKICK prior to having an EOP written to VU1 memory).  The new  
198  // MTGS wraps data around the end of the MTGS buffer, so it often splits PATH1 data into two  // This legacy passthrough function is needed because the old GS plugins tended to assume that
199  // transfers now.  // a PATH1 transfer that didn't EOP needed an automatic EOP (which was needed to avoid a crash
200  static void CALLBACK GS_gifTransferLegacy( const u32* src, u32 data )  // in the BIOS when it starts an XGKICK prior to having an EOP written to VU1 memory).  The new
201  {  // MTGS wraps data around the end of the MTGS buffer, so it often splits PATH1 data into two
202          static __aligned16 u128 path1queue[0x400];  // transfers now.
203          static uint path1size = 0;  static void CALLBACK GS_gifTransferLegacy( const u32* src, u32 data )
204    {
205          const u128* src128 = (u128*)src;          static __aligned16 u128 path1queue[0x400];
206            static uint path1size = 0;
207          if( (src128 + data) >= &RingBuffer.m_Ring[RingBufferSize] )  
208          {          const u128* src128 = (u128*)src;
209                  // the transfer is most likely wrapped/partial.  We need to queue it into a linear buffer  
210                  // and then send it on its way on the next copy.          if( (src128 + data) >= &RingBuffer.m_Ring[RingBufferSize] )
211            {
212                  memcpy_qwc( path1queue, src128, data );                  // the transfer is most likely wrapped/partial.  We need to queue it into a linear buffer
213                  path1size = data;                  // and then send it on its way on the next copy.
214          }  
215          else                  memcpy_qwc( path1queue, src128, data );
216          {                  path1size = data;
217                  if (path1size != 0)          }
218                  {          else
219                          // Previous transfer check.  *Most* likely this one should be added to it, but to know for          {
220                          // sure we need to check to see if src points to the head of RingBuffer.  If its pointing                  if (path1size != 0)
221                          // to like Ringbuffer[1] instead it means the last transfer finished and this transfer is                  {
222                          // a new one.                          // Previous transfer check.  *Most* likely this one should be added to it, but to know for
223                            // sure we need to check to see if src points to the head of RingBuffer.  If its pointing
224                          if (src128 == RingBuffer.m_Ring)                          // to like Ringbuffer[1] instead it means the last transfer finished and this transfer is
225                          {                          // a new one.
226                                  pxAssume( (data+path1size) <= 0x400 );  
227                                  memcpy_qwc( &path1queue[path1size], src128, data );                          if (src128 == RingBuffer.m_Ring)
228                                  path1size += data;                          {
229                          }                                  pxAssume( (data+path1size) <= 0x400 );
230                          GSgifTransfer1( (u32*)path1queue, 0 );                                  memcpy_qwc( &path1queue[path1size], src128, data );
231                          path1size = 0;                                  path1size += data;
232                  }                          }
233                  else                          GSgifTransfer1( (u32*)path1queue, 0 );
234                  {                          path1size = 0;
235                          GSgifTransfer1( (u32*)src128, 0 );                  }
236                  }                  else
237          }                  {
238  }                          GSgifTransfer1( (u32*)src128, 0 );
239                    }
240            }
241  // PAD  }
242  _PADinit           PADinit;  
243  _PADopen           PADopen;  
244  _PADstartPoll      PADstartPoll;  // PAD
245  _PADpoll           PADpoll;  _PADinit           PADinit;
246  _PADquery          PADquery;  _PADopen           PADopen;
247  _PADupdate         PADupdate;  _PADstartPoll      PADstartPoll;
248  _PADkeyEvent       PADkeyEvent;  _PADpoll           PADpoll;
249  _PADsetSlot        PADsetSlot;  _PADquery          PADquery;
250  _PADqueryMtap      PADqueryMtap;  _PADupdate         PADupdate;
251    _PADkeyEvent       PADkeyEvent;
252  static void PAD_update( u32 padslot ) { }  _PADsetSlot        PADsetSlot;
253    _PADqueryMtap      PADqueryMtap;
254  // SPU2  
255  _SPU2open          SPU2open;  static void PAD_update( u32 padslot ) { }
256  _SPU2write         SPU2write;  
257  _SPU2reset         SPU2reset;  // SPU2
258  _SPU2read          SPU2read;  _SPU2open          SPU2open;
259  #ifdef ENABLE_NEW_IOPDMA_SPU2  _SPU2write         SPU2write;
260  _SPU2dmaRead       SPU2dmaRead;  _SPU2reset         SPU2reset;
261  _SPU2dmaWrite      SPU2dmaWrite;  _SPU2read          SPU2read;
262  _SPU2dmaInterrupt  SPU2dmaInterrupt;  #ifdef ENABLE_NEW_IOPDMA_SPU2
263  #else  _SPU2dmaRead       SPU2dmaRead;
264  _SPU2readDMA4Mem   SPU2readDMA4Mem;  _SPU2dmaWrite      SPU2dmaWrite;
265  _SPU2writeDMA4Mem  SPU2writeDMA4Mem;  _SPU2dmaInterrupt  SPU2dmaInterrupt;
266  _SPU2interruptDMA4 SPU2interruptDMA4;  #else
267  _SPU2readDMA7Mem   SPU2readDMA7Mem;  _SPU2readDMA4Mem   SPU2readDMA4Mem;
268  _SPU2writeDMA7Mem  SPU2writeDMA7Mem;  _SPU2writeDMA4Mem  SPU2writeDMA4Mem;
269  _SPU2setDMABaseAddr SPU2setDMABaseAddr;  _SPU2interruptDMA4 SPU2interruptDMA4;
270  _SPU2interruptDMA7 SPU2interruptDMA7;  _SPU2readDMA7Mem   SPU2readDMA7Mem;
271  _SPU2ReadMemAddr   SPU2ReadMemAddr;  _SPU2writeDMA7Mem  SPU2writeDMA7Mem;
272  _SPU2WriteMemAddr   SPU2WriteMemAddr;  _SPU2setDMABaseAddr SPU2setDMABaseAddr;
273  #endif  _SPU2interruptDMA7 SPU2interruptDMA7;
274  _SPU2setupRecording SPU2setupRecording;  _SPU2ReadMemAddr   SPU2ReadMemAddr;
275  _SPU2irqCallback   SPU2irqCallback;  _SPU2WriteMemAddr   SPU2WriteMemAddr;
276    #endif
277  _SPU2setClockPtr   SPU2setClockPtr;  _SPU2setupRecording SPU2setupRecording;
278  _SPU2async         SPU2async;  _SPU2irqCallback   SPU2irqCallback;
279    
280    _SPU2setClockPtr   SPU2setClockPtr;
281  // DEV9  _SPU2async         SPU2async;
282  _DEV9open          DEV9open;  
283  _DEV9read8         DEV9read8;  
284  _DEV9read16        DEV9read16;  // DEV9
285  _DEV9read32        DEV9read32;  _DEV9open          DEV9open;
286  _DEV9write8        DEV9write8;  _DEV9read8         DEV9read8;
287  _DEV9write16       DEV9write16;  _DEV9read16        DEV9read16;
288  _DEV9write32       DEV9write32;  _DEV9read32        DEV9read32;
289  #ifdef ENABLE_NEW_IOPDMA_DEV9  _DEV9write8        DEV9write8;
290  _DEV9dmaRead       DEV9dmaRead;  _DEV9write16       DEV9write16;
291  _DEV9dmaWrite      DEV9dmaWrite;  _DEV9write32       DEV9write32;
292  _DEV9dmaInterrupt  DEV9dmaInterrupt;  #ifdef ENABLE_NEW_IOPDMA_DEV9
293  #else  _DEV9dmaRead       DEV9dmaRead;
294  _DEV9readDMA8Mem   DEV9readDMA8Mem;  _DEV9dmaWrite      DEV9dmaWrite;
295  _DEV9writeDMA8Mem  DEV9writeDMA8Mem;  _DEV9dmaInterrupt  DEV9dmaInterrupt;
296  #endif  #else
297  _DEV9irqCallback   DEV9irqCallback;  _DEV9readDMA8Mem   DEV9readDMA8Mem;
298  _DEV9irqHandler    DEV9irqHandler;  _DEV9writeDMA8Mem  DEV9writeDMA8Mem;
299    #endif
300  // USB  _DEV9irqCallback   DEV9irqCallback;
301  _USBopen           USBopen;  _DEV9irqHandler    DEV9irqHandler;
302  _USBread8          USBread8;  
303  _USBread16         USBread16;  // USB
304  _USBread32         USBread32;  _USBopen           USBopen;
305  _USBwrite8         USBwrite8;  _USBread8          USBread8;
306  _USBwrite16        USBwrite16;  _USBread16         USBread16;
307  _USBwrite32        USBwrite32;  _USBread32         USBread32;
308  _USBasync          USBasync;  _USBwrite8         USBwrite8;
309    _USBwrite16        USBwrite16;
310  _USBirqCallback    USBirqCallback;  _USBwrite32        USBwrite32;
311  _USBirqHandler     USBirqHandler;  _USBasync          USBasync;
312  _USBsetRAM         USBsetRAM;  
313    _USBirqCallback    USBirqCallback;
314  // FW  _USBirqHandler     USBirqHandler;
315  _FWopen            FWopen;  _USBsetRAM         USBsetRAM;
316  _FWread32          FWread32;  
317  _FWwrite32         FWwrite32;  // FW
318  _FWirqCallback     FWirqCallback;  _FWopen            FWopen;
319    _FWread32          FWread32;
320  DEV9handler dev9Handler;  _FWwrite32         FWwrite32;
321  USBhandler usbHandler;  _FWirqCallback     FWirqCallback;
322  uptr pDsp;  
323    DEV9handler dev9Handler;
324  static s32 CALLBACK _hack_PADinit()  USBhandler usbHandler;
325  {  uptr pDsp;
326          return PADinit( 3 );  
327  }  static s32 CALLBACK _hack_PADinit()
328    {
329  // ----------------------------------------------------------------------------          return PADinit( 3 );
330  // Important: Contents of this array must match the order of the contents of the  }
331  // LegacyPluginAPI_Common structure defined in Plugins.h.  
332  //  // ----------------------------------------------------------------------------
333  static const LegacyApi_CommonMethod s_MethMessCommon[] =  // Important: Contents of this array must match the order of the contents of the
334  {  // LegacyPluginAPI_Common structure defined in Plugins.h.
335          {       "init",                         NULL    },  //
336          {       "close",                        NULL    },  static const LegacyApi_CommonMethod s_MethMessCommon[] =
337          {       "shutdown",                     NULL    },  {
338            {       "init",                         NULL    },
339          {       "keyEvent",                     (vMeth*)fallback_keyEvent },          {       "close",                        NULL    },
340          {       "setSettingsDir",       (vMeth*)fallback_setSettingsDir },          {       "shutdown",                     NULL    },
341          {       "setLogDir",        (vMeth*)fallback_setLogDir },  
342            {       "keyEvent",                     (vMeth*)fallback_keyEvent },
343          {       "freeze",                       (vMeth*)fallback_freeze },          {       "setSettingsDir",       (vMeth*)fallback_setSettingsDir },
344          {       "test",                         (vMeth*)fallback_test },          {       "setLogDir",        (vMeth*)fallback_setLogDir },
345          {       "configure",            fallback_configure      },  
346          {       "about",                        fallback_about  },          {       "freeze",                       (vMeth*)fallback_freeze },
347            {       "test",                         (vMeth*)fallback_test },
348          { NULL }          {       "configure",            fallback_configure      },
349            {       "about",                        fallback_about  },
350  };  
351            { NULL }
352  // ----------------------------------------------------------------------------  
353  //  GS Mess!  };
354  // ----------------------------------------------------------------------------  
355  static const LegacyApi_ReqMethod s_MethMessReq_GS[] =  // ----------------------------------------------------------------------------
356  {  //  GS Mess!
357          {       "GSopen",                       (vMeth**)&GSopen,                       NULL    },  // ----------------------------------------------------------------------------
358          {       "GSvsync",                      (vMeth**)&GSvsync,                      NULL    },  static const LegacyApi_ReqMethod s_MethMessReq_GS[] =
359          {       "GSgifTransfer",        (vMeth**)&GSgifTransfer,        (vMeth*)GS_gifTransferLegacy },  {
360          {       "GSgifTransfer2",       (vMeth**)&GSgifTransfer2,       NULL    },          {       "GSopen",                       (vMeth**)&GSopen,                       NULL    },
361          {       "GSgifTransfer3",       (vMeth**)&GSgifTransfer3,       NULL    },          {       "GSvsync",                      (vMeth**)&GSvsync,                      NULL    },
362          {       "GSreadFIFO2",          (vMeth**)&GSreadFIFO2,          NULL    },          {       "GSgifTransfer",        (vMeth**)&GSgifTransfer,        (vMeth*)GS_gifTransferLegacy },
363            {       "GSgifTransfer2",       (vMeth**)&GSgifTransfer2,       NULL    },
364          {       "GSmakeSnapshot",       (vMeth**)&GSmakeSnapshot,       (vMeth*)GS_makeSnapshot },          {       "GSgifTransfer3",       (vMeth**)&GSgifTransfer3,       NULL    },
365          {       "GSirqCallback",        (vMeth**)&GSirqCallback,        (vMeth*)GS_irqCallback },          {       "GSreadFIFO2",          (vMeth**)&GSreadFIFO2,          NULL    },
366          {       "GSprintf",                     (vMeth**)&GSprintf,                     (vMeth*)GS_printf },  
367          {       "GSsetBaseMem",         (vMeth**)&GSsetBaseMem,         NULL    },          {       "GSmakeSnapshot",       (vMeth**)&GSmakeSnapshot,       (vMeth*)GS_makeSnapshot },
368          {       "GSwriteCSR",           (vMeth**)&GSwriteCSR,           NULL    },          {       "GSirqCallback",        (vMeth**)&GSirqCallback,        (vMeth*)GS_irqCallback },
369          {       "GSsetGameCRC",         (vMeth**)&GSsetGameCRC,         (vMeth*)GS_setGameCRC },          {       "GSprintf",                     (vMeth**)&GSprintf,                     (vMeth*)GS_printf },
370            {       "GSsetBaseMem",         (vMeth**)&GSsetBaseMem,         NULL    },
371          {       "GSsetFrameSkip",       (vMeth**)&GSsetFrameSkip,       (vMeth*)GS_setFrameSkip },          {       "GSwriteCSR",           (vMeth**)&GSwriteCSR,           NULL    },
372          {       "GSsetVsync",           (vMeth**)&GSsetVsync,           (vMeth*)GS_setVsync     },          {       "GSsetGameCRC",         (vMeth**)&GSsetGameCRC,         (vMeth*)GS_setGameCRC },
373          {       "GSsetExclusive",       (vMeth**)&GSsetExclusive,       (vMeth*)GS_setExclusive },  
374          {       "GSchangeSaveState",(vMeth**)&GSchangeSaveState,(vMeth*)GS_changeSaveState },          {       "GSsetFrameSkip",       (vMeth**)&GSsetFrameSkip,       (vMeth*)GS_setFrameSkip },
375          {       "GSgetTitleInfo",       (vMeth**)&GSgetTitleInfo,       (vMeth*)GS_getTitleInfo },          {       "GSsetVsync",           (vMeth**)&GSsetVsync,           (vMeth*)GS_setVsync     },
376          { NULL }          {       "GSsetExclusive",       (vMeth**)&GSsetExclusive,       (vMeth*)GS_setExclusive },
377  };          {       "GSchangeSaveState",(vMeth**)&GSchangeSaveState,(vMeth*)GS_changeSaveState },
378            {       "GSgetTitleInfo2",      (vMeth**)&GSgetTitleInfo2,      (vMeth*)GS_getTitleInfo2 },
379  static const LegacyApi_OptMethod s_MethMessOpt_GS[] =          { NULL }
380  {  };
381          {       "GSopen2",                      (vMeth**)&GSopen2                       },  
382          {       "GSreset",                      (vMeth**)&GSreset                       },  static const LegacyApi_OptMethod s_MethMessOpt_GS[] =
383          {       "GSsetupRecording",     (vMeth**)&GSsetupRecording      },  {
384          {       "GSmakeSnapshot2",      (vMeth**)&GSmakeSnapshot2       },          {       "GSopen2",                      (vMeth**)&GSopen2                       },
385          {       "GSgifSoftReset",       (vMeth**)&GSgifSoftReset        },          {       "GSreset",                      (vMeth**)&GSreset                       },
386          {       "GSreadFIFO",           (vMeth**)&GSreadFIFO            },          {       "GSsetupRecording",     (vMeth**)&GSsetupRecording      },
387          {       "GSgifTransfer1",       (vMeth**)&GSgifTransfer1        },          {       "GSmakeSnapshot2",      (vMeth**)&GSmakeSnapshot2       },
388          { NULL }          {       "GSgifSoftReset",       (vMeth**)&GSgifSoftReset        },
389  };          {       "GSreadFIFO",           (vMeth**)&GSreadFIFO            },
390            {       "GSgifTransfer1",       (vMeth**)&GSgifTransfer1        },
391  // ----------------------------------------------------------------------------          { NULL }
392  //  PAD Mess!  };
393  // ----------------------------------------------------------------------------  
394  static s32 CALLBACK PAD_queryMtap( u8 slot ) { return 0; }  // ----------------------------------------------------------------------------
395  static s32 CALLBACK PAD_setSlot(u8 port, u8 slot) { return 0; }  //  PAD Mess!
396    // ----------------------------------------------------------------------------
397  static const LegacyApi_ReqMethod s_MethMessReq_PAD[] =  static s32 CALLBACK PAD_queryMtap( u8 slot ) { return 0; }
398  {  static s32 CALLBACK PAD_setSlot(u8 port, u8 slot) { return 0; }
399          {       "PADopen",                      (vMeth**)&PADopen,              NULL },  
400          {       "PADstartPoll",         (vMeth**)&PADstartPoll, NULL },  static const LegacyApi_ReqMethod s_MethMessReq_PAD[] =
401          {       "PADpoll",                      (vMeth**)&PADpoll,              NULL },  {
402          {       "PADquery",                     (vMeth**)&PADquery,             NULL },          {       "PADopen",                      (vMeth**)&PADopen,              NULL },
403          {       "PADkeyEvent",          (vMeth**)&PADkeyEvent,  NULL },          {       "PADstartPoll",         (vMeth**)&PADstartPoll, NULL },
404            {       "PADpoll",                      (vMeth**)&PADpoll,              NULL },
405          // fixme - Following functions are new as of some revison post-0.9.6, and          {       "PADquery",                     (vMeth**)&PADquery,             NULL },
406          // are for multitap support only.  They should either be optional or offer          {       "PADkeyEvent",          (vMeth**)&PADkeyEvent,  NULL },
407          // NOP fallbacks, to allow older plugins to retain functionality.  
408          {       "PADsetSlot",           (vMeth**)&PADsetSlot,   (vMeth*)PAD_setSlot },          // fixme - Following functions are new as of some revison post-0.9.6, and
409          {       "PADqueryMtap",         (vMeth**)&PADqueryMtap, (vMeth*)PAD_queryMtap },          // are for multitap support only.  They should either be optional or offer
410          { NULL },          // NOP fallbacks, to allow older plugins to retain functionality.
411  };          {       "PADsetSlot",           (vMeth**)&PADsetSlot,   (vMeth*)PAD_setSlot },
412            {       "PADqueryMtap",         (vMeth**)&PADqueryMtap, (vMeth*)PAD_queryMtap },
413  static const LegacyApi_OptMethod s_MethMessOpt_PAD[] =          { NULL },
414  {  };
415          {       "PADupdate",            (vMeth**)&PADupdate },  
416          { NULL },  static const LegacyApi_OptMethod s_MethMessOpt_PAD[] =
417  };  {
418            {       "PADupdate",            (vMeth**)&PADupdate },
419  // ----------------------------------------------------------------------------          { NULL },
420  //  CDVD Mess!  };
421  // ----------------------------------------------------------------------------  
422  void CALLBACK CDVD_newDiskCB(void (*callback)()) {}  // ----------------------------------------------------------------------------
423    //  CDVD Mess!
424  extern int lastReadSize, lastLSN;  // ----------------------------------------------------------------------------
425  static s32 CALLBACK CDVD_getBuffer2(u8* buffer)  void CALLBACK CDVD_newDiskCB(void (*callback)()) {}
426  {  
427          // TEMP: until I fix all the plugins to use this function style  extern int lastReadSize, lastLSN;
428          u8* pb = CDVD->getBuffer();  static s32 CALLBACK CDVD_getBuffer2(u8* buffer)
429          if(pb == NULL) return -2;  {
430            // TEMP: until I fix all the plugins to use this function style
431          memcpy_fast( buffer, pb, lastReadSize );          u8* pb = CDVD->getBuffer();
432          return 0;          if(pb == NULL) return -2;
433  }  
434            memcpy_fast( buffer, pb, lastReadSize );
435  static s32 CALLBACK CDVD_readSector(u8* buffer, u32 lsn, int mode)          return 0;
436  {  }
437          if(CDVD->readTrack(lsn,mode) < 0)  
438                  return -1;  static s32 CALLBACK CDVD_readSector(u8* buffer, u32 lsn, int mode)
439    {
440          // TEMP: until all the plugins use the new CDVDgetBuffer style          if(CDVD->readTrack(lsn,mode) < 0)
441          switch (mode)                  return -1;
442          {  
443          case CDVD_MODE_2352:          // TEMP: until all the plugins use the new CDVDgetBuffer style
444                  lastReadSize = 2352;          switch (mode)
445                  break;          {
446          case CDVD_MODE_2340:          case CDVD_MODE_2352:
447                  lastReadSize = 2340;                  lastReadSize = 2352;
448                  break;                  break;
449          case CDVD_MODE_2328:          case CDVD_MODE_2340:
450                  lastReadSize = 2328;                  lastReadSize = 2340;
451                  break;                  break;
452          case CDVD_MODE_2048:          case CDVD_MODE_2328:
453                  lastReadSize = 2048;                  lastReadSize = 2328;
454                  break;                  break;
455          }          case CDVD_MODE_2048:
456                    lastReadSize = 2048;
457          lastLSN = lsn;                  break;
458          return CDVD->getBuffer2(buffer);          }
459  }  
460            lastLSN = lsn;
461  static s32 CALLBACK CDVD_getDualInfo(s32* dualType, u32* layer1Start)          return CDVD->getBuffer2(buffer);
462  {  }
463          u8 toc[2064];  
464    static s32 CALLBACK CDVD_getDualInfo(s32* dualType, u32* layer1Start)
465          // if error getting toc, settle for single layer disc ;)  {
466          if(CDVD->getTOC(toc))          u8 toc[2064];
467                  return 0;  
468            // if error getting toc, settle for single layer disc ;)
469          if(toc[14] & 0x60)          if(CDVD->getTOC(toc))
470          {                  return 0;
471                  if(toc[14] & 0x10)  
472                  {          if(toc[14] & 0x60)
473                          // otp dvd          {
474                          *dualType = 2;                  if(toc[14] & 0x10)
475                          *layer1Start = (toc[25]<<16) + (toc[26]<<8) + (toc[27]) - 0x30000 + 1;                  {
476                  }                          // otp dvd
477                  else                          *dualType = 2;
478                  {                          *layer1Start = (toc[25]<<16) + (toc[26]<<8) + (toc[27]) - 0x30000 + 1;
479                          // ptp dvd                  }
480                          *dualType = 1;                  else
481                          *layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1;                  {
482                  }                          // ptp dvd
483          }                          *dualType = 1;
484          else                          *layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1;
485          {                  }
486                  // single layer dvd          }
487                  *dualType = 0;          else
488                  *layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1;          {
489          }                  // single layer dvd
490                    *dualType = 0;
491          return 1;                  *layer1Start = (toc[21]<<16) + (toc[22]<<8) + (toc[23]) - 0x30000 + 1;
492  }          }
493    
494  CDVD_API CDVDapi_Plugin =          return 1;
495  {  }
496          // All of these are filled by the plugin manager  
497          NULL  CDVD_API CDVDapi_Plugin =
498  };  {
499            // All of these are filled by the plugin manager
500  CDVD_API* CDVD                  = NULL;          NULL
501    };
502  static const LegacyApi_ReqMethod s_MethMessReq_CDVD[] =  
503  {  CDVD_API* CDVD                  = NULL;
504          {       "CDVDopen",                     (vMeth**)&CDVDapi_Plugin.open,                  NULL },  
505          {       "CDVDclose",            (vMeth**)&CDVDapi_Plugin.close,                 NULL },  static const LegacyApi_ReqMethod s_MethMessReq_CDVD[] =
506          {       "CDVDreadTrack",        (vMeth**)&CDVDapi_Plugin.readTrack,             NULL },  {
507          {       "CDVDgetBuffer",        (vMeth**)&CDVDapi_Plugin.getBuffer,             NULL },          {       "CDVDopen",                     (vMeth**)&CDVDapi_Plugin.open,                  NULL },
508          {       "CDVDreadSubQ",         (vMeth**)&CDVDapi_Plugin.readSubQ,              NULL },          {       "CDVDclose",            (vMeth**)&CDVDapi_Plugin.close,                 NULL },
509          {       "CDVDgetTN",            (vMeth**)&CDVDapi_Plugin.getTN,                 NULL },          {       "CDVDreadTrack",        (vMeth**)&CDVDapi_Plugin.readTrack,             NULL },
510          {       "CDVDgetTD",            (vMeth**)&CDVDapi_Plugin.getTD,                 NULL },          {       "CDVDgetBuffer",        (vMeth**)&CDVDapi_Plugin.getBuffer,             NULL },
511          {       "CDVDgetTOC",           (vMeth**)&CDVDapi_Plugin.getTOC,                NULL },          {       "CDVDreadSubQ",         (vMeth**)&CDVDapi_Plugin.readSubQ,              NULL },
512          {       "CDVDgetDiskType",      (vMeth**)&CDVDapi_Plugin.getDiskType,   NULL },          {       "CDVDgetTN",            (vMeth**)&CDVDapi_Plugin.getTN,                 NULL },
513          {       "CDVDgetTrayStatus",(vMeth**)&CDVDapi_Plugin.getTrayStatus,     NULL },          {       "CDVDgetTD",            (vMeth**)&CDVDapi_Plugin.getTD,                 NULL },
514          {       "CDVDctrlTrayOpen",     (vMeth**)&CDVDapi_Plugin.ctrlTrayOpen,  NULL },          {       "CDVDgetTOC",           (vMeth**)&CDVDapi_Plugin.getTOC,                NULL },
515          {       "CDVDctrlTrayClose",(vMeth**)&CDVDapi_Plugin.ctrlTrayClose,     NULL },          {       "CDVDgetDiskType",      (vMeth**)&CDVDapi_Plugin.getDiskType,   NULL },
516          {       "CDVDnewDiskCB",        (vMeth**)&CDVDapi_Plugin.newDiskCB,             (vMeth*)CDVD_newDiskCB },          {       "CDVDgetTrayStatus",(vMeth**)&CDVDapi_Plugin.getTrayStatus,     NULL },
517            {       "CDVDctrlTrayOpen",     (vMeth**)&CDVDapi_Plugin.ctrlTrayOpen,  NULL },
518          {       "CDVDreadSector",       (vMeth**)&CDVDapi_Plugin.readSector,    (vMeth*)CDVD_readSector },          {       "CDVDctrlTrayClose",(vMeth**)&CDVDapi_Plugin.ctrlTrayClose,     NULL },
519          {       "CDVDgetBuffer2",       (vMeth**)&CDVDapi_Plugin.getBuffer2,    (vMeth*)CDVD_getBuffer2 },          {       "CDVDnewDiskCB",        (vMeth**)&CDVDapi_Plugin.newDiskCB,             (vMeth*)CDVD_newDiskCB },
520          {       "CDVDgetDualInfo",      (vMeth**)&CDVDapi_Plugin.getDualInfo,   (vMeth*)CDVD_getDualInfo },  
521            {       "CDVDreadSector",       (vMeth**)&CDVDapi_Plugin.readSector,    (vMeth*)CDVD_readSector },
522          { NULL }          {       "CDVDgetBuffer2",       (vMeth**)&CDVDapi_Plugin.getBuffer2,    (vMeth*)CDVD_getBuffer2 },
523  };          {       "CDVDgetDualInfo",      (vMeth**)&CDVDapi_Plugin.getDualInfo,   (vMeth*)CDVD_getDualInfo },
524    
525  static const LegacyApi_OptMethod s_MethMessOpt_CDVD[] =          { NULL }
526  {  };
527          { NULL }  
528  };  static const LegacyApi_OptMethod s_MethMessOpt_CDVD[] =
529    {
530  // ----------------------------------------------------------------------------          { NULL }
531  //  SPU2 Mess!  };
532  // ----------------------------------------------------------------------------  
533    // ----------------------------------------------------------------------------
534  // manualized reset that writes core reset registers of the SPU2 plugin:  //  SPU2 Mess!
535  static void CALLBACK SPU2_Reset()  // ----------------------------------------------------------------------------
536  {  
537          SPU2write( 0x1f90019A, 1<<15 );         // core 0  // manualized reset that writes core reset registers of the SPU2 plugin:
538          SPU2write( 0x1f90059A, 1<<15 );         // core 1  static void CALLBACK SPU2_Reset()
539  }  {
540            SPU2write( 0x1f90019A, 1<<15 );         // core 0
541  static const LegacyApi_ReqMethod s_MethMessReq_SPU2[] =          SPU2write( 0x1f90059A, 1<<15 );         // core 1
542  {  }
543          {       "SPU2open",                             (vMeth**)&SPU2open,                     NULL },  
544          {       "SPU2reset",                    (vMeth**)&SPU2reset,            SPU2_Reset },  static const LegacyApi_ReqMethod s_MethMessReq_SPU2[] =
545          {       "SPU2write",                    (vMeth**)&SPU2write,            NULL },  {
546          {       "SPU2read",                             (vMeth**)&SPU2read,                     NULL },          {       "SPU2open",                             (vMeth**)&SPU2open,                     NULL },
547  #ifdef ENABLE_NEW_IOPDMA_SPU2          {       "SPU2reset",                    (vMeth**)&SPU2reset,            SPU2_Reset },
548          {       "SPU2dmaRead",                  (vMeth**)&SPU2dmaRead,          NULL },          {       "SPU2write",                    (vMeth**)&SPU2write,            NULL },
549          {       "SPU2dmaWrite",                 (vMeth**)&SPU2dmaWrite,         NULL },          {       "SPU2read",                             (vMeth**)&SPU2read,                     NULL },
550          {       "SPU2dmaInterrupt",             (vMeth**)&SPU2dmaInterrupt, NULL },  #ifdef ENABLE_NEW_IOPDMA_SPU2
551  #else          {       "SPU2dmaRead",                  (vMeth**)&SPU2dmaRead,          NULL },
552          {       "SPU2readDMA4Mem",              (vMeth**)&SPU2readDMA4Mem,      NULL },          {       "SPU2dmaWrite",                 (vMeth**)&SPU2dmaWrite,         NULL },
553          {       "SPU2readDMA7Mem",              (vMeth**)&SPU2readDMA7Mem,      NULL },          {       "SPU2dmaInterrupt",             (vMeth**)&SPU2dmaInterrupt, NULL },
554          {       "SPU2writeDMA4Mem",             (vMeth**)&SPU2writeDMA4Mem,     NULL },  #else
555          {       "SPU2writeDMA7Mem",             (vMeth**)&SPU2writeDMA7Mem,     NULL },          {       "SPU2readDMA4Mem",              (vMeth**)&SPU2readDMA4Mem,      NULL },
556          {       "SPU2interruptDMA4",    (vMeth**)&SPU2interruptDMA4,NULL },          {       "SPU2readDMA7Mem",              (vMeth**)&SPU2readDMA7Mem,      NULL },
557          {       "SPU2interruptDMA7",    (vMeth**)&SPU2interruptDMA7,NULL },          {       "SPU2writeDMA4Mem",             (vMeth**)&SPU2writeDMA4Mem,     NULL },
558          {       "SPU2ReadMemAddr",              (vMeth**)&SPU2ReadMemAddr,      NULL },          {       "SPU2writeDMA7Mem",             (vMeth**)&SPU2writeDMA7Mem,     NULL },
559  #endif          {       "SPU2interruptDMA4",    (vMeth**)&SPU2interruptDMA4,NULL },
560          {       "SPU2irqCallback",              (vMeth**)&SPU2irqCallback,      NULL },          {       "SPU2interruptDMA7",    (vMeth**)&SPU2interruptDMA7,NULL },
561            {       "SPU2ReadMemAddr",              (vMeth**)&SPU2ReadMemAddr,      NULL },
562          { NULL }  #endif
563  };          {       "SPU2irqCallback",              (vMeth**)&SPU2irqCallback,      NULL },
564    
565  static const LegacyApi_OptMethod s_MethMessOpt_SPU2[] =          { NULL }
566  {  };
567          {       "SPU2setClockPtr",              (vMeth**)&SPU2setClockPtr       },  
568          {       "SPU2async",                    (vMeth**)&SPU2async                     },  static const LegacyApi_OptMethod s_MethMessOpt_SPU2[] =
569  #ifndef ENABLE_NEW_IOPDMA_SPU2  {
570          {       "SPU2WriteMemAddr",             (vMeth**)&SPU2WriteMemAddr      },          {       "SPU2setClockPtr",              (vMeth**)&SPU2setClockPtr       },
571          {       "SPU2setDMABaseAddr",   (vMeth**)&SPU2setDMABaseAddr},          {       "SPU2async",                    (vMeth**)&SPU2async                     },
572  #endif  #ifndef ENABLE_NEW_IOPDMA_SPU2
573          {       "SPU2setupRecording",   (vMeth**)&SPU2setupRecording},          {       "SPU2WriteMemAddr",             (vMeth**)&SPU2WriteMemAddr      },
574            {       "SPU2setDMABaseAddr",   (vMeth**)&SPU2setDMABaseAddr},
575          { NULL }  #endif
576  };          {       "SPU2setupRecording",   (vMeth**)&SPU2setupRecording},
577    
578  // ----------------------------------------------------------------------------          { NULL }
579  //  DEV9 Mess!  };
580  // ----------------------------------------------------------------------------  
581  static const LegacyApi_ReqMethod s_MethMessReq_DEV9[] =  // ----------------------------------------------------------------------------
582  {  //  DEV9 Mess!
583          {       "DEV9open",                     (vMeth**)&DEV9open,                     NULL },  // ----------------------------------------------------------------------------
584          {       "DEV9read8",            (vMeth**)&DEV9read8,            NULL },  static const LegacyApi_ReqMethod s_MethMessReq_DEV9[] =
585          {       "DEV9read16",           (vMeth**)&DEV9read16,           NULL },  {
586          {       "DEV9read32",           (vMeth**)&DEV9read32,           NULL },          {       "DEV9open",                     (vMeth**)&DEV9open,                     NULL },
587          {       "DEV9write8",           (vMeth**)&DEV9write8,           NULL },          {       "DEV9read8",            (vMeth**)&DEV9read8,            NULL },
588          {       "DEV9write16",          (vMeth**)&DEV9write16,          NULL },          {       "DEV9read16",           (vMeth**)&DEV9read16,           NULL },
589          {       "DEV9write32",          (vMeth**)&DEV9write32,          NULL },          {       "DEV9read32",           (vMeth**)&DEV9read32,           NULL },
590  #ifdef ENABLE_NEW_IOPDMA_DEV9          {       "DEV9write8",           (vMeth**)&DEV9write8,           NULL },
591          {       "DEV9dmaRead",          (vMeth**)&DEV9dmaRead,  NULL },          {       "DEV9write16",          (vMeth**)&DEV9write16,          NULL },
592          {       "DEV9dmaWrite",         (vMeth**)&DEV9dmaWrite, NULL },          {       "DEV9write32",          (vMeth**)&DEV9write32,          NULL },
593          {       "DEV9dmaInterrupt",     (vMeth**)&DEV9dmaInterrupt,     NULL },  #ifdef ENABLE_NEW_IOPDMA_DEV9
594  #else          {       "DEV9dmaRead",          (vMeth**)&DEV9dmaRead,  NULL },
595          {       "DEV9readDMA8Mem",      (vMeth**)&DEV9readDMA8Mem,      NULL },          {       "DEV9dmaWrite",         (vMeth**)&DEV9dmaWrite, NULL },
596          {       "DEV9writeDMA8Mem",     (vMeth**)&DEV9writeDMA8Mem,     NULL },          {       "DEV9dmaInterrupt",     (vMeth**)&DEV9dmaInterrupt,     NULL },
597  #endif  #else
598          {       "DEV9irqCallback",      (vMeth**)&DEV9irqCallback,      NULL },          {       "DEV9readDMA8Mem",      (vMeth**)&DEV9readDMA8Mem,      NULL },
599          {       "DEV9irqHandler",       (vMeth**)&DEV9irqHandler,       NULL },          {       "DEV9writeDMA8Mem",     (vMeth**)&DEV9writeDMA8Mem,     NULL },
600    #endif
601          { NULL }          {       "DEV9irqCallback",      (vMeth**)&DEV9irqCallback,      NULL },
602  };          {       "DEV9irqHandler",       (vMeth**)&DEV9irqHandler,       NULL },
603    
604  static const LegacyApi_OptMethod s_MethMessOpt_DEV9[] =          { NULL }
605  {  };
606          { NULL }  
607  };  static const LegacyApi_OptMethod s_MethMessOpt_DEV9[] =
608    {
609  // ----------------------------------------------------------------------------          { NULL }
610  //  USB Mess!  };
611  // ----------------------------------------------------------------------------  
612  static const LegacyApi_ReqMethod s_MethMessReq_USB[] =  // ----------------------------------------------------------------------------
613  {  //  USB Mess!
614          {       "USBopen",                      (vMeth**)&USBopen,                      NULL },  // ----------------------------------------------------------------------------
615          {       "USBread8",                     (vMeth**)&USBread8,                     NULL },  static const LegacyApi_ReqMethod s_MethMessReq_USB[] =
616          {       "USBread16",            (vMeth**)&USBread16,            NULL },  {
617          {       "USBread32",            (vMeth**)&USBread32,            NULL },          {       "USBopen",                      (vMeth**)&USBopen,                      NULL },
618          {       "USBwrite8",            (vMeth**)&USBwrite8,            NULL },          {       "USBread8",                     (vMeth**)&USBread8,                     NULL },
619          {       "USBwrite16",           (vMeth**)&USBwrite16,           NULL },          {       "USBread16",            (vMeth**)&USBread16,            NULL },
620          {       "USBwrite32",           (vMeth**)&USBwrite32,           NULL },          {       "USBread32",            (vMeth**)&USBread32,            NULL },
621          {       "USBirqCallback",       (vMeth**)&USBirqCallback,       NULL },          {       "USBwrite8",            (vMeth**)&USBwrite8,            NULL },
622          {       "USBirqHandler",        (vMeth**)&USBirqHandler,        NULL },          {       "USBwrite16",           (vMeth**)&USBwrite16,           NULL },
623          { NULL }          {       "USBwrite32",           (vMeth**)&USBwrite32,           NULL },
624  };          {       "USBirqCallback",       (vMeth**)&USBirqCallback,       NULL },
625            {       "USBirqHandler",        (vMeth**)&USBirqHandler,        NULL },
626  static const LegacyApi_OptMethod s_MethMessOpt_USB[] =          { NULL }
627  {  };
628          {       "USBasync",             (vMeth**)&USBasync },  
629          { NULL }  static const LegacyApi_OptMethod s_MethMessOpt_USB[] =
630  };  {
631            {       "USBasync",             (vMeth**)&USBasync },
632  // ----------------------------------------------------------------------------          { NULL }
633  //  FW Mess!  };
634  // ----------------------------------------------------------------------------  
635  static const LegacyApi_ReqMethod s_MethMessReq_FW[] =  // ----------------------------------------------------------------------------
636  {  //  FW Mess!
637          {       "FWopen",                       (vMeth**)&FWopen,                       NULL },  // ----------------------------------------------------------------------------
638          {       "FWread32",                     (vMeth**)&FWread32,                     NULL },  static const LegacyApi_ReqMethod s_MethMessReq_FW[] =
639          {       "FWwrite32",            (vMeth**)&FWwrite32,            NULL },  {
640          {       "FWirqCallback",        (vMeth**)&FWirqCallback,        NULL },          {       "FWopen",                       (vMeth**)&FWopen,                       NULL },
641          { NULL }          {       "FWread32",                     (vMeth**)&FWread32,                     NULL },
642  };          {       "FWwrite32",            (vMeth**)&FWwrite32,            NULL },
643            {       "FWirqCallback",        (vMeth**)&FWirqCallback,        NULL },
644  static const LegacyApi_OptMethod s_MethMessOpt_FW[] =          { NULL }
645  {  };
646          { NULL }  
647  };  static const LegacyApi_OptMethod s_MethMessOpt_FW[] =
648    {
649  static const LegacyApi_ReqMethod* const s_MethMessReq[] =          { NULL }
650  {  };
651          s_MethMessReq_GS,  
652          s_MethMessReq_PAD,  static const LegacyApi_ReqMethod* const s_MethMessReq[] =
653          s_MethMessReq_SPU2,  {
654          s_MethMessReq_CDVD,          s_MethMessReq_GS,
655          s_MethMessReq_USB,          s_MethMessReq_PAD,
656          s_MethMessReq_FW,          s_MethMessReq_SPU2,
657          s_MethMessReq_DEV9          s_MethMessReq_CDVD,
658  };          s_MethMessReq_USB,
659            s_MethMessReq_FW,
660  static const LegacyApi_OptMethod* const s_MethMessOpt[] =          s_MethMessReq_DEV9
661  {  };
662          s_MethMessOpt_GS,  
663          s_MethMessOpt_PAD,  static const LegacyApi_OptMethod* const s_MethMessOpt[] =
664          s_MethMessOpt_SPU2,  {
665          s_MethMessOpt_CDVD,          s_MethMessOpt_GS,
666          s_MethMessOpt_USB,          s_MethMessOpt_PAD,
667          s_MethMessOpt_FW,          s_MethMessOpt_SPU2,
668          s_MethMessOpt_DEV9          s_MethMessOpt_CDVD,
669  };          s_MethMessOpt_USB,
670            s_MethMessOpt_FW,
671  SysCorePlugins *g_plugins = NULL;          s_MethMessOpt_DEV9
672    };
673  // ---------------------------------------------------------------------------------  
674  //       Plugin-related Exception Implementations  SysCorePlugins *g_plugins = NULL;
675  // ---------------------------------------------------------------------------------  
676    // ---------------------------------------------------------------------------------
677  Exception::PluginOpenError::PluginOpenError( PluginsEnum_t pid )  //       Plugin-related Exception Implementations
678  {  // ---------------------------------------------------------------------------------
679          PluginId = pid;  
680          m_message_diag = L"%s plugin failed to open!";  wxString Exception::SaveStateLoadError::FormatDiagnosticMessage() const
681          m_message_user = L"%s plugin failed to open.  Your computer may have insufficient resources, or incompatible hardware/drivers.";  {
682  }          FastFormatUnicode retval;
683            retval.Write("Savestate is corrupt or incomplete!");
684  Exception::PluginInitError::PluginInitError( PluginsEnum_t pid )          _formatDiagMsg(retval);
685  {          return retval;
686          PluginId = pid;  }
687          m_message_diag = L"%s plugin initialization failed!";  
688          m_message_user = L"%s plugin failed to initialize.  Your system may have insufficient memory or resources needed.";  wxString Exception::SaveStateLoadError::FormatDisplayMessage() const
689  }  {
690            FastFormatUnicode retval;
691  Exception::PluginLoadError::PluginLoadError( PluginsEnum_t pid )          retval.Write(_("The savestate cannot be loaded, as it appears to be corrupt or incomplete."));
692  {          _formatUserMsg(retval);
693          PluginId = pid;          return retval;
694  }  }
695    
696  wxString Exception::PluginLoadError::FormatDiagnosticMessage() const  Exception::PluginOpenError::PluginOpenError( PluginsEnum_t pid )
697  {  {
698          return wxsFormat( m_message_diag, tbl_PluginInfo[PluginId].GetShortname().c_str() ) +          PluginId = pid;
699                  L"\n\n" + StreamName;          m_message_diag = L"%s plugin failed to open!";
700  }          m_message_user = _("%s plugin failed to open.  Your computer may have insufficient resources, or incompatible hardware/drivers.");
701    }
702  wxString Exception::PluginLoadError::FormatDisplayMessage() const  
703  {  Exception::PluginInitError::PluginInitError( PluginsEnum_t pid )
704          return wxsFormat( m_message_user, tbl_PluginInfo[PluginId].GetShortname().c_str() ) +  {
705                  L"\n\n" + StreamName;          PluginId = pid;
706  }          m_message_diag = L"%s plugin initialization failed!";
707            m_message_user = _("%s plugin failed to initialize.  Your system may have insufficient memory or resources needed.");
708  wxString Exception::PluginError::FormatDiagnosticMessage() const  }
709  {  
710          return wxsFormat( m_message_diag, tbl_PluginInfo[PluginId].GetShortname().c_str() );  Exception::PluginLoadError::PluginLoadError( PluginsEnum_t pid )
711  }  {
712            PluginId = pid;
713  wxString Exception::PluginError::FormatDisplayMessage() const  }
714  {  
715          return wxsFormat( m_message_user, tbl_PluginInfo[PluginId].GetShortname().c_str() );  wxString Exception::PluginLoadError::FormatDiagnosticMessage() const
716  }  {
717            return pxsFmt( m_message_diag, tbl_PluginInfo[PluginId].GetShortname().c_str() ) +
718  wxString Exception::FreezePluginFailure::FormatDiagnosticMessage() const                  L"\n\n" + StreamName;
719  {  }
720          return wxsFormat(  
721                  L"%s plugin returned an error while saving the state.\n\n",  wxString Exception::PluginLoadError::FormatDisplayMessage() const
722                  tbl_PluginInfo[PluginId].shortname  {
723          );          return pxsFmt( m_message_user, tbl_PluginInfo[PluginId].GetShortname().c_str() ) +
724  }                  L"\n\n" + StreamName;
725    }
726  wxString Exception::FreezePluginFailure::FormatDisplayMessage() const  
727  {  wxString Exception::PluginError::FormatDiagnosticMessage() const
728          // [TODO]  {
729          return m_message_user;          return pxsFmt( m_message_diag, tbl_PluginInfo[PluginId].GetShortname().c_str() );
730  }  }
731    
732  wxString Exception::ThawPluginFailure::FormatDiagnosticMessage() const  wxString Exception::PluginError::FormatDisplayMessage() const
733  {  {
734          return wxsFormat(          return pxsFmt( m_message_user, tbl_PluginInfo[PluginId].GetShortname().c_str() );
735                  L"%s plugin returned an error while loading the state.\n\n",  }
736                  tbl_PluginInfo[PluginId].shortname  
737          );  wxString Exception::FreezePluginFailure::FormatDiagnosticMessage() const
738  }  {
739            return pxsFmt(
740  wxString Exception::ThawPluginFailure::FormatDisplayMessage() const                  L"%s plugin returned an error while saving the state.\n\n",
741  {                  tbl_PluginInfo[PluginId].shortname
742          // [TODO]          );
743          return m_message_user;  }
744  }  
745    wxString Exception::FreezePluginFailure::FormatDisplayMessage() const
746  // --------------------------------------------------------------------------------------  {
747  //  PCSX2 Callbacks passed to Plugins          // [TODO]
748  // --------------------------------------------------------------------------------------          return m_message_user;
749  // This is currently unimplemented, and should be provided by the AppHost (gui) rather  }
750  // than the EmuCore.  But as a quickhackfix until the new plugin API is fleshed out, this  
751  // will suit our needs nicely. :)  wxString Exception::ThawPluginFailure::FormatDiagnosticMessage() const
752    {
753  static BOOL PS2E_CALLBACK pcsx2_GetInt( const char* name, int* dest )          return pxsFmt(
754  {                  L"%s plugin returned an error while loading the state.\n\n",
755          return FALSE;           // not implemented...                  tbl_PluginInfo[PluginId].shortname
756  }          );
757    }
758  static BOOL PS2E_CALLBACK pcsx2_GetBoolean( const char* name, BOOL* result )  
759  {  wxString Exception::ThawPluginFailure::FormatDisplayMessage() const
760          return FALSE;           // not implemented...  {
761  }          // [TODO]
762            return m_message_user;
763  static BOOL PS2E_CALLBACK pcsx2_GetString( const char* name, char* dest, int maxlen )  }
764  {  
765          return FALSE;           // not implemented...  // --------------------------------------------------------------------------------------
766  }  //  PCSX2 Callbacks passed to Plugins
767    // --------------------------------------------------------------------------------------
768  static char* PS2E_CALLBACK pcsx2_GetStringAlloc( const char* name, void* (PS2E_CALLBACK* allocator)(int size) )  // This is currently unimplemented, and should be provided by the AppHost (gui) rather
769  {  // than the EmuCore.  But as a quickhackfix until the new plugin API is fleshed out, this
770          return FALSE;           // not implemented...  // will suit our needs nicely. :)
771  }  
772    static BOOL PS2E_CALLBACK pcsx2_GetInt( const char* name, int* dest )
773  static void PS2E_CALLBACK pcsx2_OSD_WriteLn( int icon, const char* msg )  {
774  {          return FALSE;           // not implemented...
775          return;         // not implemented...  }
776  }  
777    static BOOL PS2E_CALLBACK pcsx2_GetBoolean( const char* name, BOOL* result )
778  // ---------------------------------------------------------------------------------  {
779  //  PluginStatus_t Implementations          return FALSE;           // not implemented...
780  // ---------------------------------------------------------------------------------  }
781  SysCorePlugins::PluginStatus_t::PluginStatus_t( PluginsEnum_t _pid, const wxString& srcfile )  
782          : Filename( srcfile )  static BOOL PS2E_CALLBACK pcsx2_GetString( const char* name, char* dest, int maxlen )
783  {  {
784          pid = _pid;          return FALSE;           // not implemented...
785    }
786          IsInitialized   = false;  
787          IsOpened                = false;  static char* PS2E_CALLBACK pcsx2_GetStringAlloc( const char* name, void* (PS2E_CALLBACK* allocator)(int size) )
788    {
789          if( Filename.IsEmpty() )          return FALSE;           // not implemented...
790                  throw Exception::PluginInitError( pid ).SetDiagMsg( L"Empty plugin filename" );  }
791    
792          if( !wxFile::Exists( Filename ) )  static void PS2E_CALLBACK pcsx2_OSD_WriteLn( int icon, const char* msg )
793                  throw Exception::PluginLoadError( pid ).SetStreamName(srcfile)  {
794                          .SetBothMsgs(wxLt("The configured %s plugin file was not found"));          return;         // not implemented...
795    }
796          if( !Lib.Load( Filename ) )  
797                  throw Exception::PluginLoadError( pid ).SetStreamName(Filename)  // ---------------------------------------------------------------------------------
798                          .SetBothMsgs(wxLt("The configured %s plugin file is not a valid dynamic library"));  //  PluginStatus_t Implementations
799    // ---------------------------------------------------------------------------------
800    SysCorePlugins::PluginStatus_t::PluginStatus_t( PluginsEnum_t _pid, const wxString& srcfile )
801          // Try to enumerate the new v2.0 plugin interface first.          : Filename( srcfile )
802          // If that fails, fall back on the old style interface.  {
803            pid = _pid;
804          //m_libs[i].GetSymbol( L"PS2E_InitAPI" );               // on the TODO list!  
805            IsInitialized   = false;
806                    IsOpened                = false;
807          // 2.0 API Failed; Enumerate the Old Stuff! -->  
808            if( Filename.IsEmpty() )
809          _PS2EgetLibName         GetLibName              = (_PS2EgetLibName)             Lib.GetSymbol( L"PS2EgetLibName" );                  throw Exception::PluginInitError( pid ).SetDiagMsg( L"Empty plugin filename" );
810          _PS2EgetLibVersion2     GetLibVersion2  = (_PS2EgetLibVersion2) Lib.GetSymbol( L"PS2EgetLibVersion2" );  
811          _PS2EsetEmuVersion      SetEmuVersion   = (_PS2EsetEmuVersion)  Lib.GetSymbol( L"PS2EsetEmuVersion" );          if( !wxFile::Exists( Filename ) )
812                    throw Exception::PluginLoadError( pid ).SetStreamName(srcfile)
813          if( GetLibName == NULL || GetLibVersion2 == NULL )                          .SetBothMsgs(wxLt("The configured %s plugin file was not found"));
814                  throw Exception::PluginLoadError( pid ).SetStreamName(Filename)  
815                          .SetDiagMsg(L"%s plugin init failed: Method binding failure on GetLibName or GetLibVersion2.")          if( !Lib.Load( Filename ) )
816                          .SetUserMsg(_( "The configured %s plugin is not a PCSX2 plugin, or is for an older unsupported version of PCSX2."));                  throw Exception::PluginLoadError( pid ).SetStreamName(Filename)
817                            .SetBothMsgs(wxLt("The configured %s plugin file is not a valid dynamic library"));
818          if( SetEmuVersion != NULL )  
819                  SetEmuVersion( "PCSX2", (0ul << 24) | (9ul<<16) | (7ul<<8) | 0 );  
820            // Try to enumerate the new v2.0 plugin interface first.
821          Name = fromUTF8( GetLibName() );          // If that fails, fall back on the old style interface.
822          int version = GetLibVersion2( tbl_PluginInfo[pid].typemask );  
823          Version.Printf( L"%d.%d.%d", (version>>8)&0xff, version&0xff, (version>>24)&0xff );          //m_libs[i].GetSymbol( L"PS2E_InitAPI" );               // on the TODO list!
824    
825            
826          // Bind Required Functions          // 2.0 API Failed; Enumerate the Old Stuff! -->
827          // (generate critical error if binding fails)  
828            _PS2EgetLibName         GetLibName              = (_PS2EgetLibName)             Lib.GetSymbol( L"PS2EgetLibName" );
829          BindCommon( pid );          _PS2EgetLibVersion2     GetLibVersion2  = (_PS2EgetLibVersion2) Lib.GetSymbol( L"PS2EgetLibVersion2" );
830          BindRequired( pid );          _PS2EsetEmuVersion      SetEmuVersion   = (_PS2EsetEmuVersion)  Lib.GetSymbol( L"PS2EsetEmuVersion" );
831          BindOptional( pid );  
832            if( GetLibName == NULL || GetLibVersion2 == NULL )
833          // Run Plugin's Functionality Test.                  throw Exception::PluginLoadError( pid ).SetStreamName(Filename)
834          // A lot of plugins don't bother to implement this function and return 0 (success)                          .SetDiagMsg(L"%s plugin init failed: Method binding failure on GetLibName or GetLibVersion2.")
835          // regardless, but some do so let's go ahead and check it. I mean, we're supposed to. :)                          .SetUserMsg(_( "The configured %s plugin is not a PCSX2 plugin, or is for an older unsupported version of PCSX2."));
836    
837          int testres = CommonBindings.Test();          if( SetEmuVersion != NULL )
838          if( testres != 0 )                  SetEmuVersion( "PCSX2", (0ul << 24) | (9ul<<16) | (7ul<<8) | 0 );
839                  throw Exception::PluginLoadError( pid ).SetStreamName(Filename)  
840                          .SetDiagMsg(wxsFormat( L"Plugin Test failure, return code: %d", testres ))          Name = fromUTF8( GetLibName() );
841                          .SetUserMsg(_("The plugin reports that your hardware or software/drivers are not supported."));          int version = GetLibVersion2( tbl_PluginInfo[pid].typemask );
842  }          Version.Printf( L"%d.%d.%d", (version>>8)&0xff, version&0xff, (version>>24)&0xff );
843    
844  void SysCorePlugins::PluginStatus_t::BindCommon( PluginsEnum_t pid )  
845  {          // Bind Required Functions
846          const LegacyApi_CommonMethod* current = s_MethMessCommon;          // (generate critical error if binding fails)
847          VoidMethod** target = (VoidMethod**)&CommonBindings;  
848            BindCommon( pid );
849          wxDoNotLogInThisScope please;          BindRequired( pid );
850            BindOptional( pid );
851          while( current->MethodName != NULL )  
852          {          // Run Plugin's Functionality Test.
853                  *target = (VoidMethod*)Lib.GetSymbol( current->GetMethodName( pid ) );          // A lot of plugins don't bother to implement this function and return 0 (success)
854            // regardless, but some do so let's go ahead and check it. I mean, we're supposed to. :)
855                  if( *target == NULL )  
856                          *target = current->Fallback;          int testres = CommonBindings.Test();
857            if( testres != 0 )
858                  if( *target == NULL )                  throw Exception::PluginLoadError( pid ).SetStreamName(Filename)
859                  {                          .SetDiagMsg(wxsFormat( L"Plugin Test failure, return code: %d", testres ))
860                          throw Exception::PluginLoadError( pid ).SetStreamName(Filename)                          .SetUserMsg(_("The plugin reports that your hardware or software/drivers are not supported."));
861                                  .SetDiagMsg(wxsFormat( L"\nMethod binding failure on: %s\n", current->GetMethodName( pid ).c_str() ))  }
862                                  .SetUserMsg(_("Configured plugin is not a PCSX2 plugin, or is for an older unsupported version of PCSX2."));  
863                  }  void SysCorePlugins::PluginStatus_t::BindCommon( PluginsEnum_t pid )
864    {
865                  target++;          const LegacyApi_CommonMethod* current = s_MethMessCommon;
866                  current++;          VoidMethod** target = (VoidMethod**)&CommonBindings;
867          }  
868  }          wxDoNotLogInThisScope please;
869    
870  void SysCorePlugins::PluginStatus_t::BindRequired( PluginsEnum_t pid )          while( current->MethodName != NULL )
871  {          {
872          const LegacyApi_ReqMethod* current = s_MethMessReq[pid];                  *target = (VoidMethod*)Lib.GetSymbol( current->GetMethodName( pid ) );
873          const wxDynamicLibrary& lib = Lib;  
874                    if( *target == NULL )
875          wxDoNotLogInThisScope please;                          *target = current->Fallback;
876    
877          while( current->MethodName != NULL )                  if( *target == NULL )
878          {                  {
879                  *(current->Dest) = (VoidMethod*)lib.GetSymbol( current->GetMethodName() );                          throw Exception::PluginLoadError( pid ).SetStreamName(Filename)
880                                    .SetDiagMsg(wxsFormat( L"\nMethod binding failure on: %s\n", current->GetMethodName( pid ).c_str() ))
881                  if( *(current->Dest) == NULL )                                  .SetUserMsg(_("Configured plugin is not a PCSX2 plugin, or is for an older unsupported version of PCSX2."));
882                          *(current->Dest) = current->Fallback;                  }
883    
884                  if( *(current->Dest) == NULL )                  target++;
885                  {                  current++;
886                          throw Exception::PluginLoadError( pid ).SetStreamName(Filename)          }
887                                  .SetDiagMsg(wxsFormat( L"\n%s plugin init error; Method binding failed: %s\n", current->GetMethodName().c_str() ))  }
888                                  .SetUserMsg(_( "Configured %s plugin is not a valid PCSX2 plugin, or is for an older unsupported version of PCSX2."));  
889                  }  void SysCorePlugins::PluginStatus_t::BindRequired( PluginsEnum_t pid )
890    {
891                  current++;          const LegacyApi_ReqMethod* current = s_MethMessReq[pid];
892          }          const wxDynamicLibrary& lib = Lib;
893  }  
894            wxDoNotLogInThisScope please;
895  void SysCorePlugins::PluginStatus_t::BindOptional( PluginsEnum_t pid )  
896  {          while( current->MethodName != NULL )
897          const LegacyApi_OptMethod* current = s_MethMessOpt[pid];          {
898          const wxDynamicLibrary& lib = Lib;                  *(current->Dest) = (VoidMethod*)lib.GetSymbol( current->GetMethodName() );
899    
900          wxDoNotLogInThisScope please;                  if( *(current->Dest) == NULL )
901                            *(current->Dest) = current->Fallback;
902          while( current->MethodName != NULL )  
903          {                  if( *(current->Dest) == NULL )
904                  *(current->Dest) = (VoidMethod*)lib.GetSymbol( current->GetMethodName() );                  {
905                  current++;                          throw Exception::PluginLoadError( pid ).SetStreamName(Filename)
906          }                                  .SetDiagMsg(wxsFormat( L"\n%s plugin init error; Method binding failed: %s\n", current->GetMethodName().c_str() ))
907  }                                  .SetUserMsg(_( "Configured %s plugin is not a valid PCSX2 plugin, or is for an older unsupported version of PCSX2."));
908                    }
909  // =====================================================================================  
910  //  SysCorePlugins Implementations                  current++;
911  // =====================================================================================          }
912    }
913  SysCorePlugins::SysCorePlugins()  
914  {  void SysCorePlugins::PluginStatus_t::BindOptional( PluginsEnum_t pid )
915  }  {
916            const LegacyApi_OptMethod* current = s_MethMessOpt[pid];
917  SysCorePlugins::~SysCorePlugins() throw()          const wxDynamicLibrary& lib = Lib;
918  {  
919          try          wxDoNotLogInThisScope please;
920          {  
921                  Unload();          while( current->MethodName != NULL )
922          }          {
923          DESTRUCTOR_CATCHALL                  *(current->Dest) = (VoidMethod*)lib.GetSymbol( current->GetMethodName() );
924                    current++;
925          // All library unloading done automatically by wx.          }
926  }  }
927    
928  void SysCorePlugins::Load( PluginsEnum_t pid, const wxString& srcfile )  // =====================================================================================
929  {  //  SysCorePlugins Implementations
930          ScopedLock lock( m_mtx_PluginStatus );  // =====================================================================================
931          pxAssume( (uint)pid < PluginId_Count );  
932          Console.Indent().WriteLn( L"Binding %s\t: %s ", tbl_PluginInfo[pid].GetShortname().c_str(), srcfile.c_str() );  SysCorePlugins::SysCorePlugins()
933          m_info[pid] = new PluginStatus_t( pid, srcfile );  {
934  }  }
935    
936  void SysCorePlugins::Load( const wxString (&folders)[PluginId_Count] )  SysCorePlugins::~SysCorePlugins() throw()
937  {  {
938          if( !NeedsLoad() ) return;          try
939            {
940          wxDoNotLogInThisScope please;                  Unload();
941                    }
942          Console.WriteLn( Color_StrongBlue, "\nLoading plugins..." );          DESTRUCTOR_CATCHALL
943    
944          ConsoleIndentScope indent;          // All library unloading done automatically by wx.
945          const PluginInfo* pi = tbl_PluginInfo; do  }
946          {  
947                  Load( pi->id, folders[pi->id] );  void SysCorePlugins::Load( PluginsEnum_t pid, const wxString& srcfile )
948                  pxYield( 2 );  {
949            ScopedLock lock( m_mtx_PluginStatus );
950          } while( ++pi, pi->shortname != NULL );          pxAssume( (uint)pid < PluginId_Count );
951          indent.LeaveScope();          Console.Indent().WriteLn( L"Binding %s\t: %s ", tbl_PluginInfo[pid].GetShortname().c_str(), srcfile.c_str() );
952            m_info[pid] = new PluginStatus_t( pid, srcfile );
953          CDVDapi_Plugin.newDiskCB( cdvdNewDiskCB );  }
954    
955          // Hack for PAD's stupid parameter passed on Init  void SysCorePlugins::Load( const wxString (&folders)[PluginId_Count] )
956          PADinit = (_PADinit)m_info[PluginId_PAD]->CommonBindings.Init;  {
957          m_info[PluginId_PAD]->CommonBindings.Init = _hack_PADinit;          if( !NeedsLoad() ) return;
958    
959          Console.WriteLn( Color_StrongBlue, "Plugins loaded successfully.\n" );          wxDoNotLogInThisScope please;
960            
961          // HACK!  Manually bind the Internal MemoryCard plugin for now, until          Console.WriteLn( Color_StrongBlue, "\nLoading plugins..." );
962          // we get things more completed in the new plugin api.  
963            ConsoleIndentScope indent;
964          static const PS2E_EmulatorInfo myself =          const PluginInfo* pi = tbl_PluginInfo; do
965          {          {
966                  "PCSX2",                  Load( pi->id, folders[pi->id] );
967                    pxYield( 2 );
968                  { 0, PCSX2_VersionHi, PCSX2_VersionLo, PCSX2_UPSTREAM_REVISION },  
969            } while( ++pi, pi->shortname != NULL );
970                  x86caps.PhysicalCores,          indent.LeaveScope();
971                  x86caps.LogicalCores,  
972                  sizeof(wchar_t),          CDVDapi_Plugin.newDiskCB( cdvdNewDiskCB );
973    
974                  0,0,0,0,0,0,          // Hack for PAD's stupid parameter passed on Init
975            PADinit = (_PADinit)m_info[PluginId_PAD]->CommonBindings.Init;
976                  pcsx2_GetInt,          m_info[PluginId_PAD]->CommonBindings.Init = _hack_PADinit;
977                  pcsx2_GetBoolean,  
978                  pcsx2_GetString,          Console.WriteLn( Color_StrongBlue, "Plugins loaded successfully.\n" );
979                  pcsx2_GetStringAlloc,  
980                  pcsx2_OSD_WriteLn          // HACK!  Manually bind the Internal MemoryCard plugin for now, until
981          };          // we get things more completed in the new plugin api.
982    
983          m_mcdPlugin = FileMcd_InitAPI( &myself );          static const PS2E_EmulatorInfo myself =
984          if( m_mcdPlugin == NULL )          {
985          {                  "PCSX2",
986                  // fixme: use plugin's GetLastError (not implemented yet!)  
987                  throw Exception::PluginLoadError( PluginId_Mcd ).SetDiagMsg(L"Internal Memorycard Plugin failed to load.");                  { 0, PCSX2_VersionHi, PCSX2_VersionLo, SVN_REV },
988          }  
989                    x86caps.PhysicalCores,
990          SendLogFolder();                  x86caps.LogicalCores,
991          SendSettingsFolder();                  sizeof(wchar_t),
992  }  
993                    0,0,0,0,0,0,
994  void SysCorePlugins::Unload(PluginsEnum_t pid)  
995  {                  pcsx2_GetInt,
996          ScopedLock lock( m_mtx_PluginStatus );                  pcsx2_GetBoolean,
997          pxAssume( (uint)pid < PluginId_Count );                  pcsx2_GetString,
998          m_info[pid].Delete();                  pcsx2_GetStringAlloc,
999  }                  pcsx2_OSD_WriteLn
1000            };
1001  void SysCorePlugins::Unload()  
1002  {          m_mcdPlugin = FileMcd_InitAPI( &myself );
1003          if( NeedsShutdown() )          if( m_mcdPlugin == NULL )
1004                  Console.Warning( "(SysCorePlugins) Warning: Unloading plugins prior to shutdown!" );          {
1005                    // fixme: use plugin's GetLastError (not implemented yet!)
1006          //Shutdown();                  throw Exception::PluginLoadError( PluginId_Mcd ).SetDiagMsg(L"Internal Memorycard Plugin failed to load.");
1007            }
1008          if( !NeedsUnload() ) return;  
1009            SendLogFolder();
1010          DbgCon.WriteLn( Color_StrongBlue, "Unloading plugins..." );          SendSettingsFolder();
1011    }
1012          for( int i=PluginId_Count-1; i>=0; --i )  
1013                  Unload( tbl_PluginInfo[i].id );  void SysCorePlugins::Unload(PluginsEnum_t pid)
1014    {
1015          DbgCon.WriteLn( Color_StrongBlue, "Plugins unloaded successfully." );          ScopedLock lock( m_mtx_PluginStatus );
1016  }          pxAssume( (uint)pid < PluginId_Count );
1017            m_info[pid].Delete();
1018  // Exceptions:  }
1019  //   FileNotFound - Thrown if one of the configured plugins doesn't exist.  
1020  //   NotPcsxPlugin - Thrown if one of the configured plugins is an invalid or unsupported DLL  void SysCorePlugins::Unload()
1021    {
1022  extern bool renderswitch;          if( NeedsShutdown() )
1023  extern void spu2DMA4Irq();                  Console.Warning( "(SysCorePlugins) Warning: Unloading plugins prior to shutdown!" );
1024  extern void spu2DMA7Irq();  
1025  extern void spu2Irq();          //Shutdown();
1026    
1027  bool SysCorePlugins::OpenPlugin_CDVD()          if( !NeedsUnload() ) return;
1028  {  
1029          return DoCDVDopen();          DbgCon.WriteLn( Color_StrongBlue, "Unloading plugins..." );
1030  }  
1031            for( int i=PluginId_Count-1; i>=0; --i )
1032  bool SysCorePlugins::OpenPlugin_GS()                  Unload( tbl_PluginInfo[i].id );
1033  {  
1034          GetMTGS().Resume();          DbgCon.WriteLn( Color_StrongBlue, "Plugins unloaded successfully." );
1035          return true;  }
1036  }  
1037    // Exceptions:
1038  bool SysCorePlugins::OpenPlugin_PAD()  //   FileNotFound - Thrown if one of the configured plugins doesn't exist.
1039  {  //   NotPcsxPlugin - Thrown if one of the configured plugins is an invalid or unsupported DLL
1040          return !PADopen( (void*)&pDsp );  
1041  }  extern bool renderswitch;
1042    extern void spu2DMA4Irq();
1043  bool SysCorePlugins::OpenPlugin_SPU2()  extern void spu2DMA7Irq();
1044  {  extern void spu2Irq();
1045          if( SPU2open((void*)&pDsp) ) return false;  
1046    bool SysCorePlugins::OpenPlugin_CDVD()
1047  #ifdef ENABLE_NEW_IOPDMA_SPU2  {
1048          SPU2irqCallback( spu2Irq );          return DoCDVDopen();
1049  #else  }
1050          SPU2irqCallback( spu2Irq, spu2DMA4Irq, spu2DMA7Irq );  
1051          if( SPU2setDMABaseAddr != NULL ) SPU2setDMABaseAddr((uptr)iopMem->Main);  bool SysCorePlugins::OpenPlugin_GS()
1052  #endif  {
1053          if( SPU2setClockPtr != NULL ) SPU2setClockPtr(&psxRegs.cycle);          GetMTGS().Resume();
1054          return true;          return true;
1055  }  }
1056    
1057  bool SysCorePlugins::OpenPlugin_DEV9()  bool SysCorePlugins::OpenPlugin_PAD()
1058  {  {
1059          dev9Handler = NULL;          return !PADopen( (void*)&pDsp );
1060    }
1061          if( DEV9open( (void*)&pDsp ) ) return false;  
1062          DEV9irqCallback( dev9Irq );  bool SysCorePlugins::OpenPlugin_SPU2()
1063          dev9Handler = DEV9irqHandler();  {
1064          return true;          if( SPU2open((void*)&pDsp) ) return false;
1065  }  
1066    #ifdef ENABLE_NEW_IOPDMA_SPU2
1067  bool SysCorePlugins::OpenPlugin_USB()          SPU2irqCallback( spu2Irq );
1068  {  #else
1069          usbHandler = NULL;          SPU2irqCallback( spu2Irq, spu2DMA4Irq, spu2DMA7Irq );
1070            if( SPU2setDMABaseAddr != NULL ) SPU2setDMABaseAddr((uptr)iopMem->Main);
1071          if( USBopen((void*)&pDsp) ) return false;  #endif
1072          USBirqCallback( usbIrq );          if( SPU2setClockPtr != NULL ) SPU2setClockPtr(&psxRegs.cycle);
1073          usbHandler = USBirqHandler();          return true;
1074          if( USBsetRAM != NULL )  }
1075                  USBsetRAM(iopMem->Main);  
1076          return true;  bool SysCorePlugins::OpenPlugin_DEV9()
1077  }  {
1078            dev9Handler = NULL;
1079  bool SysCorePlugins::OpenPlugin_FW()  
1080  {          if( DEV9open( (void*)&pDsp ) ) return false;
1081          if( FWopen((void*)&pDsp) ) return false;          DEV9irqCallback( dev9Irq );
1082          FWirqCallback( fwIrq );          dev9Handler = DEV9irqHandler();
1083          return true;          return true;
1084  }  }
1085    
1086  bool SysCorePlugins::OpenPlugin_Mcd()  bool SysCorePlugins::OpenPlugin_USB()
1087  {  {
1088          ScopedLock lock( m_mtx_PluginStatus );          usbHandler = NULL;
1089    
1090          // [TODO] Fix up and implement PS2E_SessionInfo here!!  (the currently NULL parameter)          if( USBopen((void*)&pDsp) ) return false;
1091          if( SysPlugins.Mcd )          USBirqCallback( usbIrq );
1092                  SysPlugins.Mcd->Base.EmuOpen( (PS2E_THISPTR) SysPlugins.Mcd, NULL );          usbHandler = USBirqHandler();
1093            if( USBsetRAM != NULL )
1094          return true;                  USBsetRAM(iopMem->Main);
1095  }          return true;
1096    }
1097  void SysCorePlugins::Open( PluginsEnum_t pid )  
1098  {  bool SysCorePlugins::OpenPlugin_FW()
1099          pxAssume( (uint)pid < PluginId_Count );  {
1100          if( IsOpen(pid) ) return;          if( FWopen((void*)&pDsp) ) return false;
1101            FWirqCallback( fwIrq );
1102          Console.Indent().WriteLn( "Opening %s", tbl_PluginInfo[pid].shortname );          return true;
1103    }
1104          // Each Open needs to be called explicitly. >_<  
1105    bool SysCorePlugins::OpenPlugin_Mcd()
1106          bool result = true;  {
1107          switch( pid )          ScopedLock lock( m_mtx_PluginStatus );
1108          {  
1109                  case PluginId_GS:       result = OpenPlugin_GS();       break;          // [TODO] Fix up and implement PS2E_SessionInfo here!!  (the currently NULL parameter)
1110                  case PluginId_PAD:      result = OpenPlugin_PAD();      break;          if( SysPlugins.Mcd )
1111                  case PluginId_CDVD:     result = OpenPlugin_CDVD();     break;                  SysPlugins.Mcd->Base.EmuOpen( (PS2E_THISPTR) SysPlugins.Mcd, NULL );
1112                  case PluginId_SPU2:     result = OpenPlugin_SPU2();     break;  
1113                  case PluginId_USB:      result = OpenPlugin_USB();      break;          return true;
1114                  case PluginId_FW:       result = OpenPlugin_FW();       break;  }
1115                  case PluginId_DEV9:     result = OpenPlugin_DEV9();     break;  
1116    void SysCorePlugins::Open( PluginsEnum_t pid )
1117                  jNO_DEFAULT;  {
1118          }          pxAssume( (uint)pid < PluginId_Count );
1119          if( !result )          if( IsOpen(pid) ) return;
1120                  throw Exception::PluginOpenError( pid );  
1121            Console.Indent().WriteLn( "Opening %s", tbl_PluginInfo[pid].shortname );
1122          ScopedLock lock( m_mtx_PluginStatus );  
1123          if( m_info[pid] ) m_info[pid]->IsOpened = true;          // Each Open needs to be called explicitly. >_<
1124  }  
1125            bool result = true;
1126  void SysCorePlugins::Open()          switch( pid )
1127  {          {
1128          Init();                  case PluginId_GS:       result = OpenPlugin_GS();       break;
1129                    case PluginId_PAD:      result = OpenPlugin_PAD();      break;
1130          if( !NeedsOpen() ) return;              // Spam stopper:  returns before writing any logs. >_<                  case PluginId_CDVD:     result = OpenPlugin_CDVD();     break;
1131                    case PluginId_SPU2:     result = OpenPlugin_SPU2();     break;
1132          Console.WriteLn( Color_StrongBlue, "Opening plugins..." );                  case PluginId_USB:      result = OpenPlugin_USB();      break;
1133                    case PluginId_FW:       result = OpenPlugin_FW();       break;
1134          SendSettingsFolder();                  case PluginId_DEV9:     result = OpenPlugin_DEV9();     break;
1135    
1136          const PluginInfo* pi = tbl_PluginInfo; do {                  jNO_DEFAULT;
1137                  Open( pi->id );          }
1138                  // If GS doesn't support GSopen2, need to wait until call to GSopen          if( !result )
1139                  // returns to populate pDsp.  If it does, can initialize other plugins                  throw Exception::PluginOpenError( pid );
1140                  // at same time as GS, as long as GSopen2 does not subclass its window.  
1141                  if (pi->id == PluginId_GS && !GSopen2) GetMTGS().WaitForOpen();          ScopedLock lock( m_mtx_PluginStatus );
1142          } while( ++pi, pi->shortname != NULL );          if( m_info[pid] ) m_info[pid]->IsOpened = true;
1143    }
1144          if (GSopen2) GetMTGS().WaitForOpen();  
1145    void SysCorePlugins::Open()
1146          if( !AtomicExchange( m_mcdOpen, true ) )  {
1147          {          Init();
1148                  DbgCon.Indent().WriteLn( "Opening Memorycards");  
1149                  OpenPlugin_Mcd();          if( !NeedsOpen() ) return;              // Spam stopper:  returns before writing any logs. >_<
1150          }  
1151            Console.WriteLn( Color_StrongBlue, "Opening plugins..." );
1152          Console.WriteLn( Color_StrongBlue, "Plugins opened successfully." );  
1153  }          SendSettingsFolder();
1154    
1155  void SysCorePlugins::_generalclose( PluginsEnum_t pid )          const PluginInfo* pi = tbl_PluginInfo; do {
1156  {                  Open( pi->id );
1157          ScopedLock lock( m_mtx_PluginStatus );                  // If GS doesn't support GSopen2, need to wait until call to GSopen
1158          if( m_info[pid] ) m_info[pid]->CommonBindings.Close();                  // returns to populate pDsp.  If it does, can initialize other plugins
1159  }                  // at same time as GS, as long as GSopen2 does not subclass its window.
1160                    if (pi->id == PluginId_GS && !GSopen2) GetMTGS().WaitForOpen();
1161  void SysCorePlugins::ClosePlugin_GS()          } while( ++pi, pi->shortname != NULL );
1162  {  
1163          // old-skool: force-close PAD before GS, because the PAD depends on the GS window.          if (GSopen2) GetMTGS().WaitForOpen();
1164    
1165          if( GetMTGS().IsSelf() )          if( !AtomicExchange( m_mcdOpen, true ) )
1166                  _generalclose( PluginId_GS );          {
1167          else                  DbgCon.Indent().WriteLn( "Opening Memorycards");
1168          {                  OpenPlugin_Mcd();
1169                  if( !GSopen2 ) Close( PluginId_PAD );          }
1170                  GetMTGS().Suspend();  
1171          }          Console.WriteLn( Color_StrongBlue, "Plugins opened successfully." );
1172  }  }
1173    
1174  void SysCorePlugins::ClosePlugin_CDVD()  void SysCorePlugins::_generalclose( PluginsEnum_t pid )
1175  {  {
1176          DoCDVDclose();          ScopedLock lock( m_mtx_PluginStatus );
1177  }          if( m_info[pid] ) m_info[pid]->CommonBindings.Close();
1178    }
1179  void SysCorePlugins::ClosePlugin_PAD()  
1180  {  void SysCorePlugins::ClosePlugin_GS()
1181          _generalclose( PluginId_PAD );  {
1182  }          // old-skool: force-close PAD before GS, because the PAD depends on the GS window.
1183    
1184  void SysCorePlugins::ClosePlugin_SPU2()          if( GetMTGS().IsSelf() )
1185  {                  _generalclose( PluginId_GS );
1186          _generalclose( PluginId_SPU2 );          else
1187  }          {
1188                    if( !GSopen2 ) Close( PluginId_PAD );
1189  void SysCorePlugins::ClosePlugin_DEV9()                  GetMTGS().Suspend();
1190  {          }
1191          _generalclose( PluginId_DEV9 );  }
1192  }  
1193    void SysCorePlugins::ClosePlugin_CDVD()
1194  void SysCorePlugins::ClosePlugin_USB()  {
1195  {          DoCDVDclose();
1196          _generalclose( PluginId_USB );  }
1197  }  
1198    void SysCorePlugins::ClosePlugin_PAD()
1199  void SysCorePlugins::ClosePlugin_FW()  {
1200  {          _generalclose( PluginId_PAD );
1201          _generalclose( PluginId_FW );  }
1202  }  
1203    void SysCorePlugins::ClosePlugin_SPU2()
1204  void SysCorePlugins::ClosePlugin_Mcd()  {
1205  {          _generalclose( PluginId_SPU2 );
1206          ScopedLock lock( m_mtx_PluginStatus );  }
1207          if( SysPlugins.Mcd ) SysPlugins.Mcd->Base.EmuClose( (PS2E_THISPTR) SysPlugins.Mcd );  
1208  }  void SysCorePlugins::ClosePlugin_DEV9()
1209    {
1210  void SysCorePlugins::Close( PluginsEnum_t pid )          _generalclose( PluginId_DEV9 );
1211  {  }
1212          pxAssume( (uint)pid < PluginId_Count );  
1213    void SysCorePlugins::ClosePlugin_USB()
1214          if( !IsOpen(pid) ) return;  {
1215                    _generalclose( PluginId_USB );
1216          if( !GetMTGS().IsSelf() )               // stop the spam!  }
1217                  Console.Indent().WriteLn( "Closing %s", tbl_PluginInfo[pid].shortname );  
1218    void SysCorePlugins::ClosePlugin_FW()
1219          switch( pid )  {
1220          {          _generalclose( PluginId_FW );
1221                  case PluginId_GS:       ClosePlugin_GS();       break;  }
1222                  case PluginId_PAD:      ClosePlugin_PAD();      break;  
1223                  case PluginId_CDVD:     ClosePlugin_CDVD();     break;  void SysCorePlugins::ClosePlugin_Mcd()
1224                  case PluginId_SPU2:     ClosePlugin_SPU2();     break;  {
1225                  case PluginId_USB:      ClosePlugin_USB();      break;          ScopedLock lock( m_mtx_PluginStatus );
1226                  case PluginId_FW:       ClosePlugin_FW();       break;          if( SysPlugins.Mcd ) SysPlugins.Mcd->Base.EmuClose( (PS2E_THISPTR) SysPlugins.Mcd );
1227                  case PluginId_DEV9:     ClosePlugin_DEV9();     break;  }
1228                  case PluginId_Mcd:      ClosePlugin_Mcd();      break;  
1229                    void SysCorePlugins::Close( PluginsEnum_t pid )
1230                  jNO_DEFAULT;  {
1231          }          pxAssume( (uint)pid < PluginId_Count );
1232    
1233          ScopedLock lock( m_mtx_PluginStatus );          if( !IsOpen(pid) ) return;
1234          if( m_info[pid] ) m_info[pid]->IsOpened = false;          
1235  }          if( !GetMTGS().IsSelf() )               // stop the spam!
1236                    Console.Indent().WriteLn( "Closing %s", tbl_PluginInfo[pid].shortname );
1237  void SysCorePlugins::Close()  
1238  {          switch( pid )
1239          if( !NeedsClose() ) return;     // Spam stopper; returns before writing any logs. >_<          {
1240                    case PluginId_GS:       ClosePlugin_GS();       break;
1241          // Close plugins in reverse order of the initialization procedure, which                  case PluginId_PAD:      ClosePlugin_PAD();      break;
1242          // ensures the GS gets closed last.                  case PluginId_CDVD:     ClosePlugin_CDVD();     break;
1243                    case PluginId_SPU2:     ClosePlugin_SPU2();     break;
1244          Console.WriteLn( Color_StrongBlue, "Closing plugins..." );                  case PluginId_USB:      ClosePlugin_USB();      break;
1245                    case PluginId_FW:       ClosePlugin_FW();       break;
1246          if( AtomicExchange( m_mcdOpen, false ) )                  case PluginId_DEV9:     ClosePlugin_DEV9();     break;
1247          {                  case PluginId_Mcd:      ClosePlugin_Mcd();      break;
1248                  DbgCon.Indent().WriteLn( "Closing Memorycards");                  
1249                  ClosePlugin_Mcd();                  jNO_DEFAULT;
1250          }          }
1251    
1252          for( int i=PluginId_Count-1; i>=0; --i )          ScopedLock lock( m_mtx_PluginStatus );
1253                  Close( tbl_PluginInfo[i].id );          if( m_info[pid] ) m_info[pid]->IsOpened = false;
1254            }
1255          Console.WriteLn( Color_StrongBlue, "Plugins closed successfully." );  
1256  }  void SysCorePlugins::Close()
1257    {
1258  void SysCorePlugins::Init( PluginsEnum_t pid )          if( !NeedsClose() ) return;     // Spam stopper; returns before writing any logs. >_<
1259  {  
1260          ScopedLock lock( m_mtx_PluginStatus );          // Close plugins in reverse order of the initialization procedure, which
1261            // ensures the GS gets closed last.
1262          if( !m_info[pid] || m_info[pid]->IsInitialized ) return;  
1263            Console.WriteLn( Color_StrongBlue, "Closing plugins..." );
1264          Console.Indent().WriteLn( "Init %s", tbl_PluginInfo[pid].shortname );  
1265          if( NULL != m_info[pid]->CommonBindings.Init() )          if( AtomicExchange( m_mcdOpen, false ) )
1266                  throw Exception::PluginInitError( pid );          {
1267                    DbgCon.Indent().WriteLn( "Closing Memorycards");
1268          m_info[pid]->IsInitialized = true;                  ClosePlugin_Mcd();
1269  }          }
1270    
1271  void SysCorePlugins::Shutdown( PluginsEnum_t pid )          for( int i=PluginId_Count-1; i>=0; --i )
1272  {                  Close( tbl_PluginInfo[i].id );
1273          ScopedLock lock( m_mtx_PluginStatus );          
1274            Console.WriteLn( Color_StrongBlue, "Plugins closed successfully." );
1275          if( !m_info[pid] || !m_info[pid]->IsInitialized ) return;  }
1276          DevCon.Indent().WriteLn( "Shutdown %s", tbl_PluginInfo[pid].shortname );  
1277          m_info[pid]->IsInitialized = false;  void SysCorePlugins::Init( PluginsEnum_t pid )
1278          m_info[pid]->CommonBindings.Shutdown();  {
1279  }          ScopedLock lock( m_mtx_PluginStatus );
1280    
1281  // Initializes all plugins.  Plugin initialization should be done once for every new emulation          if( !m_info[pid] || m_info[pid]->IsInitialized ) return;
1282  // session.  During a session emulation can be paused/resumed using Open/Close, and should be  
1283  // terminated using Shutdown().          Console.Indent().WriteLn( "Init %s", tbl_PluginInfo[pid].shortname );
1284  //          if( 0 != m_info[pid]->CommonBindings.Init() )
1285  // Returns TRUE if an init was performed for any (or all) plugins.  Returns FALSE if all                  throw Exception::PluginInitError( pid );
1286  // plugins were already in an initialized state (no action taken).  
1287  //          m_info[pid]->IsInitialized = true;
1288  // In a purist emulation sense, Init() and Shutdown() should only ever need be called for when  }
1289  // the PS2's hardware has received a *full* hard reset.  Soft resets typically should rely on  
1290  // the PS2's bios/kernel to re-initialize hardware on the fly.  void SysCorePlugins::Shutdown( PluginsEnum_t pid )
1291  //  {
1292  bool SysCorePlugins::Init()          ScopedLock lock( m_mtx_PluginStatus );
1293  {  
1294          if( !NeedsInit() ) return false;          if( !m_info[pid] || !m_info[pid]->IsInitialized ) return;
1295            DevCon.Indent().WriteLn( "Shutdown %s", tbl_PluginInfo[pid].shortname );
1296          Console.WriteLn( Color_StrongBlue, "\nInitializing plugins..." );          m_info[pid]->IsInitialized = false;
1297          const PluginInfo* pi = tbl_PluginInfo; do {          m_info[pid]->CommonBindings.Shutdown();
1298                  Init( pi->id );  }
1299          } while( ++pi, pi->shortname != NULL );  
1300    // Initializes all plugins.  Plugin initialization should be done once for every new emulation
1301          if( SysPlugins.Mcd == NULL )  // session.  During a session emulation can be paused/resumed using Open/Close, and should be
1302          {  // terminated using Shutdown().
1303                  SysPlugins.Mcd = (PS2E_ComponentAPI_Mcd*)m_mcdPlugin->NewComponentInstance( PS2E_TYPE_Mcd );  //
1304                  if( SysPlugins.Mcd == NULL )  // Returns TRUE if an init was performed for any (or all) plugins.  Returns FALSE if all
1305                  {  // plugins were already in an initialized state (no action taken).
1306                          // fixme: use plugin's GetLastError (not implemented yet!)  //
1307                          throw Exception::PluginInitError( PluginId_Mcd )  // In a purist emulation sense, Init() and Shutdown() should only ever need be called for when
1308                                  .SetBothMsgs(wxLt("Internal Memorycard Plugin failed to initialize."));  // the PS2's hardware has received a *full* hard reset.  Soft resets typically should rely on
1309                  }  // the PS2's bios/kernel to re-initialize hardware on the fly.
1310          }  //
1311    bool SysCorePlugins::Init()
1312          Console.WriteLn( Color_StrongBlue, "Plugins initialized successfully.\n" );  {
1313            if( !NeedsInit() ) return false;
1314          return true;  
1315  }          Console.WriteLn( Color_StrongBlue, "\nInitializing plugins..." );
1316            const PluginInfo* pi = tbl_PluginInfo; do {
1317                    Init( pi->id );
1318  // Shuts down all plugins.  Plugins are closed first, if necessary.          } while( ++pi, pi->shortname != NULL );
1319  // Returns TRUE if a shutdown was performed for any (or all) plugins.  Returns FALSE if all  
1320  // plugins were already in shutdown state (no action taken).          if( SysPlugins.Mcd == NULL )
1321  //          {
1322  // In a purist emulation sense, Init() and Shutdown() should only ever need be called for when                  SysPlugins.Mcd = (PS2E_ComponentAPI_Mcd*)m_mcdPlugin->NewComponentInstance( PS2E_TYPE_Mcd );
1323  // the PS2's hardware has received a *full* hard reset.  Soft resets typically should rely on                  if( SysPlugins.Mcd == NULL )
1324  // the PS2's bios/kernel to re-initialize hardware on the fly.                  {
1325  //                          // fixme: use plugin's GetLastError (not implemented yet!)
1326  bool SysCorePlugins::Shutdown()                          throw Exception::PluginInitError( PluginId_Mcd )
1327  {                                  .SetBothMsgs(wxLt("Internal Memorycard Plugin failed to initialize."));
1328          if( !NeedsShutdown() ) return false;                  }
1329            }
1330          pxAssertDev( !NeedsClose(), "Cannot shut down plugins prior to Close()" );  
1331                    Console.WriteLn( Color_StrongBlue, "Plugins initialized successfully.\n" );
1332          GetMTGS().Cancel();     // cancel it for speedier shutdown!  
1333                    return true;
1334          Console.WriteLn( Color_StrongGreen, "Shutting down plugins..." );  }
1335    
1336          // Shutdown plugins in reverse order (probably doesn't matter...  
1337          //  ... but what the heck, right?)  // Shuts down all plugins.  Plugins are closed first, if necessary.
1338    // Returns TRUE if a shutdown was performed for any (or all) plugins.  Returns FALSE if all
1339          for( int i=PluginId_Count-1; i>=0; --i )  // plugins were already in shutdown state (no action taken).
1340          {  //
1341                  Shutdown( tbl_PluginInfo[i].id );  // In a purist emulation sense, Init() and Shutdown() should only ever need be called for when
1342          }  // the PS2's hardware has received a *full* hard reset.  Soft resets typically should rely on
1343    // the PS2's bios/kernel to re-initialize hardware on the fly.
1344          // More memorycard hacks!!  //
1345    bool SysCorePlugins::Shutdown()
1346          if( (SysPlugins.Mcd != NULL) && (m_mcdPlugin != NULL) )  {
1347          {          if( !NeedsShutdown() ) return false;
1348                  m_mcdPlugin->DeleteComponentInstance( (PS2E_THISPTR)SysPlugins.Mcd );  
1349                  SysPlugins.Mcd = NULL;          pxAssertDev( !NeedsClose(), "Cannot shut down plugins prior to Close()" );
1350          }          
1351            GetMTGS().Cancel();     // cancel it for speedier shutdown!
1352          Console.WriteLn( Color_StrongGreen, "Plugins shutdown successfully." );          
1353                    Console.WriteLn( Color_StrongGreen, "Shutting down plugins..." );
1354          return true;  
1355  }          // Shutdown plugins in reverse order (probably doesn't matter...
1356            //  ... but what the heck, right?)
1357  // For internal use only, unless you're the MTGS.  Then it's for you too!  
1358  // Returns false if the plugin returned an error.          for( int i=PluginId_Count-1; i>=0; --i )
1359  bool SysCorePlugins::DoFreeze( PluginsEnum_t pid, int mode, freezeData* data )          {
1360  {                  Shutdown( tbl_PluginInfo[i].id );
1361          if( (pid == PluginId_GS) && !GetMTGS().IsSelf() )          }
1362          {  
1363                  // GS needs some thread safety love...          // More memorycard hacks!!
1364    
1365                  MTGS_FreezeData woot = { data, 0 };          if( (SysPlugins.Mcd != NULL) && (m_mcdPlugin != NULL) )
1366                  GetMTGS().Freeze( mode, woot );          {
1367                  return woot.retval != -1;                  m_mcdPlugin->DeleteComponentInstance( (PS2E_THISPTR)SysPlugins.Mcd );
1368          }                  SysPlugins.Mcd = NULL;
1369          else          }
1370          {  
1371                  ScopedLock lock( m_mtx_PluginStatus );          Console.WriteLn( Color_StrongGreen, "Plugins shutdown successfully." );
1372                  return !m_info[pid] || m_info[pid]->CommonBindings.Freeze( mode, data ) != -1;          
1373          }          return true;
1374  }  }
1375    
1376  // Thread Safety:  // For internal use only, unless you're the MTGS.  Then it's for you too!
1377  //   This function should only be called by the Main GUI thread and the GS thread (for GS states only),  // Returns false if the plugin returned an error.
1378  //   as it has special handlers to ensure that GS freeze commands are executed appropriately on the  bool SysCorePlugins::DoFreeze( PluginsEnum_t pid, int mode, freezeData* data )
1379  //   GS thread.  {
1380  //          if( (pid == PluginId_GS) && !GetMTGS().IsSelf() )
1381  void SysCorePlugins::Freeze( PluginsEnum_t pid, SaveStateBase& state )          {
1382  {                  // GS needs some thread safety love...
1383          // No locking leeded -- DoFreeze locks as needed, and this avoids MTGS deadlock.  
1384          //ScopedLock lock( m_mtx_PluginStatus );                  MTGS_FreezeData woot = { data, 0 };
1385                    GetMTGS().Freeze( mode, woot );
1386          Console.Indent().WriteLn( "%s %s", state.IsSaving() ? "Saving" : "Loading",                  return woot.retval != -1;
1387                  tbl_PluginInfo[pid].shortname );          }
1388            else
1389          freezeData fP = { 0, NULL };          {
1390          if( !DoFreeze( pid, FREEZE_SIZE, &fP ) )                  ScopedLock lock( m_mtx_PluginStatus );
1391                  fP.size = 0;                  return !m_info[pid] || m_info[pid]->CommonBindings.Freeze( mode, data ) != -1;
1392            }
1393          int fsize = fP.size;  }
1394          state.Freeze( fsize );  
1395    // Thread Safety:
1396          if( state.IsLoading() && (fsize == 0) )  //   This function should only be called by the Main GUI thread and the GS thread (for GS states only),
1397          {  //   as it has special handlers to ensure that GS freeze commands are executed appropriately on the
1398                  // no state data to read, but the plugin expects some state data.  //   GS thread.
1399                  // Issue a warning to console...  //
1400                  if( fP.size != 0 )  void SysCorePlugins::Freeze( PluginsEnum_t pid, SaveStateBase& state )
1401                          Console.Indent().Warning( "Warning: No data for this plugin was found. Plugin status may be unpredictable." );  {
1402                  return;          // No locking leeded -- DoFreeze locks as needed, and this avoids MTGS deadlock.
1403            //ScopedLock lock( m_mtx_PluginStatus );
1404                  // Note: Size mismatch check could also be done here on loading, but  
1405                  // some plugins may have built-in version support for non-native formats or          Console.Indent().WriteLn( "%s %s", state.IsSaving() ? "Saving" : "Loading",
1406                  // older versions of a different size... or could give different sizes depending                  tbl_PluginInfo[pid].shortname );
1407                  // on the status of the plugin when loading, so let's ignore it.  
1408          }          freezeData fP = { 0, NULL };
1409            if( !DoFreeze( pid, FREEZE_SIZE, &fP ) )
1410          fP.size = fsize;                  fP.size = 0;
1411          if( fP.size == 0 ) return;  
1412            int fsize = fP.size;
1413          state.PrepBlock( fP.size );          state.Freeze( fsize );
1414          fP.data = (s8*)state.GetBlockPtr();  
1415            if( state.IsLoading() && (fsize == 0) )
1416          if( state.IsSaving() )          {
1417          {                  // no state data to read, but the plugin expects some state data.
1418                  if( !DoFreeze(pid, FREEZE_SAVE, &fP) )                  // Issue a warning to console...
1419                          throw Exception::FreezePluginFailure( pid );                  if( fP.size != 0 )
1420          }                          Console.Indent().Warning( "Warning: No data for this plugin was found. Plugin status may be unpredictable." );
1421          else                  return;
1422          {  
1423                  if( !DoFreeze(pid, FREEZE_LOAD, &fP) )                  // Note: Size mismatch check could also be done here on loading, but
1424                          throw Exception::ThawPluginFailure( pid );                  // some plugins may have built-in version support for non-native formats or
1425          }                  // older versions of a different size... or could give different sizes depending
1426                    // on the status of the plugin when loading, so let's ignore it.
1427          state.CommitBlock( fP.size );          }
1428  }  
1429            fP.size = fsize;
1430  bool SysCorePlugins::KeyEvent( const keyEvent& evt )          if( fP.size == 0 ) return;
1431  {  
1432          ScopedLock lock( m_mtx_PluginStatus );          state.PrepBlock( fP.size );
1433            fP.data = (s8*)state.GetBlockPtr();
1434          // [TODO] : The plan here is to give plugins "first chance" handling of keys.  
1435          // Handling order will be fixed (GS, SPU2, PAD, etc), and the first plugin to          if( state.IsSaving() )
1436          // pick up the key and return "true" (for handled) will cause the loop to break.          {
1437          // The current version of PS2E doesn't support it yet, though.                  if( !DoFreeze(pid, FREEZE_SAVE, &fP) )
1438                            throw Exception::FreezePluginFailure( pid );
1439          const PluginInfo* pi = tbl_PluginInfo; do {          }
1440                  if( pi->id != PluginId_PAD && m_info[pi->id] )          else
1441                          m_info[pi->id]->CommonBindings.KeyEvent( const_cast<keyEvent*>(&evt) );          {
1442          } while( ++pi, pi->shortname != NULL );                  if( !DoFreeze(pid, FREEZE_LOAD, &fP) )
1443                            throw Exception::ThawPluginFailure( pid );
1444          return false;          }
1445  }  
1446            state.CommitBlock( fP.size );
1447  void SysCorePlugins::SendSettingsFolder()  }
1448  {  
1449          ScopedLock lock( m_mtx_PluginStatus );  bool SysCorePlugins::KeyEvent( const keyEvent& evt )
1450          if( m_SettingsFolder.IsEmpty() ) return;  {
1451            ScopedLock lock( m_mtx_PluginStatus );
1452          pxToUTF8 utf8buffer( m_SettingsFolder );  
1453            // [TODO] : The plan here is to give plugins "first chance" handling of keys.
1454          const PluginInfo* pi = tbl_PluginInfo; do {          // Handling order will be fixed (GS, SPU2, PAD, etc), and the first plugin to
1455                  if( m_info[pi->id] ) m_info[pi->id]->CommonBindings.SetSettingsDir( utf8buffer );          // pick up the key and return "true" (for handled) will cause the loop to break.
1456          } while( ++pi, pi->shortname != NULL );          // The current version of PS2E doesn't support it yet, though.
1457  }  
1458            const PluginInfo* pi = tbl_PluginInfo; do {
1459  void SysCorePlugins::SetSettingsFolder( const wxString& folder )                  if( pi->id != PluginId_PAD && m_info[pi->id] )
1460  {                          m_info[pi->id]->CommonBindings.KeyEvent( const_cast<keyEvent*>(&evt) );
1461          ScopedLock lock( m_mtx_PluginStatus );          } while( ++pi, pi->shortname != NULL );
1462    
1463          wxString fixedfolder( folder );          return false;
1464          if( !fixedfolder.IsEmpty() && (fixedfolder[fixedfolder.length()-1] != wxFileName::GetPathSeparator() ) )  }
1465          {  
1466                  fixedfolder += wxFileName::GetPathSeparator();  void SysCorePlugins::SendSettingsFolder()
1467          }  {
1468                    ScopedLock lock( m_mtx_PluginStatus );
1469          if( m_SettingsFolder == fixedfolder ) return;          if( m_SettingsFolder.IsEmpty() ) return;
1470          m_SettingsFolder = fixedfolder;  
1471  }          pxToUTF8 utf8buffer( m_SettingsFolder );
1472    
1473  void SysCorePlugins::SendLogFolder()          const PluginInfo* pi = tbl_PluginInfo; do {
1474  {                  if( m_info[pi->id] ) m_info[pi->id]->CommonBindings.SetSettingsDir( utf8buffer );
1475          ScopedLock lock( m_mtx_PluginStatus );          } while( ++pi, pi->shortname != NULL );
1476          if( m_LogFolder.IsEmpty() ) return;  }
1477    
1478          pxToUTF8 utf8buffer( m_LogFolder );  void SysCorePlugins::SetSettingsFolder( const wxString& folder )
1479    {
1480          const PluginInfo* pi = tbl_PluginInfo; do {          ScopedLock lock( m_mtx_PluginStatus );
1481                  if( m_info[pi->id] ) m_info[pi->id]->CommonBindings.SetLogDir( utf8buffer );  
1482          } while( ++pi, pi->shortname != NULL );          wxString fixedfolder( folder );
1483  }          if( !fixedfolder.IsEmpty() && (fixedfolder[fixedfolder.length()-1] != wxFileName::GetPathSeparator() ) )
1484            {
1485  void SysCorePlugins::SetLogFolder( const wxString& folder )                  fixedfolder += wxFileName::GetPathSeparator();
1486  {          }
1487          ScopedLock lock( m_mtx_PluginStatus );          
1488            if( m_SettingsFolder == fixedfolder ) return;
1489          wxString fixedfolder( folder );          m_SettingsFolder = fixedfolder;
1490          if( !fixedfolder.IsEmpty() && (fixedfolder[fixedfolder.length()-1] != wxFileName::GetPathSeparator() ) )  }
1491          {  
1492                  fixedfolder += wxFileName::GetPathSeparator();  void SysCorePlugins::SendLogFolder()
1493          }  {
1494            ScopedLock lock( m_mtx_PluginStatus );
1495          if( m_LogFolder == fixedfolder ) return;          if( m_LogFolder.IsEmpty() ) return;
1496          m_LogFolder = fixedfolder;  
1497  }          pxToUTF8 utf8buffer( m_LogFolder );
1498    
1499  void SysCorePlugins::Configure( PluginsEnum_t pid )          const PluginInfo* pi = tbl_PluginInfo; do {
1500  {                  if( m_info[pi->id] ) m_info[pi->id]->CommonBindings.SetLogDir( utf8buffer );
1501          ScopedLock lock( m_mtx_PluginStatus );          } while( ++pi, pi->shortname != NULL );
1502          if( m_info[pid] ) m_info[pid]->CommonBindings.Configure();  }
1503  }  
1504    void SysCorePlugins::SetLogFolder( const wxString& folder )
1505  bool SysCorePlugins::AreLoaded() const  {
1506  {          ScopedLock lock( m_mtx_PluginStatus );
1507          ScopedLock lock( m_mtx_PluginStatus );  
1508          for( int i=0; i<PluginId_Count; ++i )          wxString fixedfolder( folder );
1509          {          if( !fixedfolder.IsEmpty() && (fixedfolder[fixedfolder.length()-1] != wxFileName::GetPathSeparator() ) )
1510                  if( !m_info[i] ) return false;          {
1511          }                  fixedfolder += wxFileName::GetPathSeparator();
1512            }
1513          return true;  
1514  }          if( m_LogFolder == fixedfolder ) return;
1515            m_LogFolder = fixedfolder;
1516  bool SysCorePlugins::AreOpen() const  }
1517  {  
1518          ScopedLock lock( m_mtx_PluginStatus );  void SysCorePlugins::Configure( PluginsEnum_t pid )
1519          const PluginInfo* pi = tbl_PluginInfo; do {  {
1520                  if( !IsOpen(pi->id) ) return false;          ScopedLock lock( m_mtx_PluginStatus );
1521          } while( ++pi, pi->shortname != NULL );          if( m_info[pid] ) m_info[pid]->CommonBindings.Configure();
1522    }
1523          return true;  
1524  }  bool SysCorePlugins::AreLoaded() const
1525    {
1526  bool SysCorePlugins::AreAnyLoaded() const          ScopedLock lock( m_mtx_PluginStatus );
1527  {          for( int i=0; i<PluginId_Count; ++i )
1528          ScopedLock lock( m_mtx_PluginStatus );          {
1529          for( int i=0; i<PluginId_Count; ++i )                  if( !m_info[i] ) return false;
1530          {          }
1531                  if( m_info[i] ) return true;  
1532          }          return true;
1533    }
1534          return false;  
1535  }  bool SysCorePlugins::AreOpen() const
1536    {
1537  bool SysCorePlugins::AreAnyInitialized() const          ScopedLock lock( m_mtx_PluginStatus );
1538  {          const PluginInfo* pi = tbl_PluginInfo; do {
1539          ScopedLock lock( m_mtx_PluginStatus );                  if( !IsOpen(pi->id) ) return false;
1540          const PluginInfo* pi = tbl_PluginInfo; do {          } while( ++pi, pi->shortname != NULL );
1541                  if( IsInitialized(pi->id) ) return true;  
1542          } while( ++pi, pi->shortname != NULL );          return true;
1543    }
1544          return false;  
1545  }  bool SysCorePlugins::AreAnyLoaded() const
1546    {
1547  bool SysCorePlugins::IsOpen( PluginsEnum_t pid ) const          ScopedLock lock( m_mtx_PluginStatus );
1548  {          for( int i=0; i<PluginId_Count; ++i )
1549          pxAssume( (uint)pid < PluginId_Count );          {
1550          ScopedLock lock( m_mtx_PluginStatus );                  if( m_info[i] ) return true;
1551          return m_info[pid] && m_info[pid]->IsInitialized && m_info[pid]->IsOpened;          }
1552  }  
1553            return false;
1554  bool SysCorePlugins::IsInitialized( PluginsEnum_t pid ) const  }
1555  {  
1556          pxAssume( (uint)pid < PluginId_Count );  bool SysCorePlugins::AreAnyInitialized() const
1557          ScopedLock lock( m_mtx_PluginStatus );  {
1558          return m_info[pid] && m_info[pid]->IsInitialized;          ScopedLock lock( m_mtx_PluginStatus );
1559  }          const PluginInfo* pi = tbl_PluginInfo; do {
1560                    if( IsInitialized(pi->id) ) return true;
1561  bool SysCorePlugins::IsLoaded( PluginsEnum_t pid ) const          } while( ++pi, pi->shortname != NULL );
1562  {  
1563          pxAssume( (uint)pid < PluginId_Count );          return false;
1564          return !!m_info[pid];  }
1565  }  
1566    bool SysCorePlugins::IsOpen( PluginsEnum_t pid ) const
1567  bool SysCorePlugins::NeedsLoad() const  {
1568  {          pxAssume( (uint)pid < PluginId_Count );
1569          const PluginInfo* pi = tbl_PluginInfo; do {          ScopedLock lock( m_mtx_PluginStatus );
1570                  if( !IsLoaded(pi->id) ) return true;          return m_info[pid] && m_info[pid]->IsInitialized && m_info[pid]->IsOpened;
1571          } while( ++pi, pi->shortname != NULL );  }
1572            
1573          return false;  bool SysCorePlugins::IsInitialized( PluginsEnum_t pid ) const
1574  }                {
1575            pxAssume( (uint)pid < PluginId_Count );
1576  bool SysCorePlugins::NeedsUnload() const          ScopedLock lock( m_mtx_PluginStatus );
1577  {          return m_info[pid] && m_info[pid]->IsInitialized;
1578          const PluginInfo* pi = tbl_PluginInfo; do {  }
1579                  if( IsLoaded(pi->id) ) return true;  
1580          } while( ++pi, pi->shortname != NULL );  bool SysCorePlugins::IsLoaded( PluginsEnum_t pid ) const
1581    {
1582          return false;          pxAssume( (uint)pid < PluginId_Count );
1583  }                        return !!m_info[pid];
1584    }
1585  bool SysCorePlugins::NeedsInit() const  
1586  {  bool SysCorePlugins::NeedsLoad() const
1587          ScopedLock lock( m_mtx_PluginStatus );  {
1588            const PluginInfo* pi = tbl_PluginInfo; do {
1589          const PluginInfo* pi = tbl_PluginInfo; do {                  if( !IsLoaded(pi->id) ) return true;
1590                  if( !IsInitialized(pi->id) ) return true;          } while( ++pi, pi->shortname != NULL );
1591          } while( ++pi, pi->shortname != NULL );          
1592            return false;
1593          return false;  }              
1594  }  
1595    bool SysCorePlugins::NeedsUnload() const
1596  bool SysCorePlugins::NeedsShutdown() const  {
1597  {          const PluginInfo* pi = tbl_PluginInfo; do {
1598          ScopedLock lock( m_mtx_PluginStatus );                  if( IsLoaded(pi->id) ) return true;
1599            } while( ++pi, pi->shortname != NULL );
1600          const PluginInfo* pi = tbl_PluginInfo; do {  
1601                  if( IsInitialized(pi->id) ) return true;          return false;
1602          } while( ++pi, pi->shortname != NULL );  }              
1603    
1604          return false;  bool SysCorePlugins::NeedsInit() const
1605  }  {
1606            ScopedLock lock( m_mtx_PluginStatus );
1607  bool SysCorePlugins::NeedsOpen() const  
1608  {          const PluginInfo* pi = tbl_PluginInfo; do {
1609          const PluginInfo* pi = tbl_PluginInfo; do {                  if( !IsInitialized(pi->id) ) return true;
1610                  if( !IsOpen(pi->id) ) return true;          } while( ++pi, pi->shortname != NULL );
1611          } while( ++pi, pi->shortname != NULL );  
1612            return false;
1613          return false;  }
1614  }  
1615    bool SysCorePlugins::NeedsShutdown() const
1616  bool SysCorePlugins::NeedsClose() const  {
1617  {          ScopedLock lock( m_mtx_PluginStatus );
1618          const PluginInfo* pi = tbl_PluginInfo; do {  
1619                  if( IsOpen(pi->id) ) return true;          const PluginInfo* pi = tbl_PluginInfo; do {
1620          } while( ++pi, pi->shortname != NULL );                  if( IsInitialized(pi->id) ) return true;
1621            } while( ++pi, pi->shortname != NULL );
1622          return false;  
1623  }          return false;
1624    }
1625  const wxString SysCorePlugins::GetName( PluginsEnum_t pid ) const  
1626  {  bool SysCorePlugins::NeedsOpen() const
1627          ScopedLock lock( m_mtx_PluginStatus );  {
1628          pxAssume( (uint)pid < PluginId_Count );          const PluginInfo* pi = tbl_PluginInfo; do {
1629          return m_info[pid] ? m_info[pid]->Name : (wxString)_("Unloaded Plugin");                  if( !IsOpen(pi->id) ) return true;
1630  }          } while( ++pi, pi->shortname != NULL );
1631    
1632  const wxString SysCorePlugins::GetVersion( PluginsEnum_t pid ) const          return false;
1633  {  }
1634          ScopedLock lock( m_mtx_PluginStatus );  
1635          pxAssume( (uint)pid < PluginId_Count );  bool SysCorePlugins::NeedsClose() const
1636          return m_info[pid] ? m_info[pid]->Version : L"0.0";  {
1637  }          const PluginInfo* pi = tbl_PluginInfo; do {
1638                    if( IsOpen(pi->id) ) return true;
1639            } while( ++pi, pi->shortname != NULL );
1640    
1641            return false;
1642    }
1643    
1644    const wxString SysCorePlugins::GetName( PluginsEnum_t pid ) const
1645    {
1646            ScopedLock lock( m_mtx_PluginStatus );
1647            pxAssume( (uint)pid < PluginId_Count );
1648            return m_info[pid] ? m_info[pid]->Name : (wxString)_("Unloaded Plugin");
1649    }
1650    
1651    const wxString SysCorePlugins::GetVersion( PluginsEnum_t pid ) const
1652    {
1653            ScopedLock lock( m_mtx_PluginStatus );
1654            pxAssume( (uint)pid < PluginId_Count );
1655            return m_info[pid] ? m_info[pid]->Version : L"0.0";
1656    }

Legend:
Removed from v.273  
changed lines
  Added in v.280

  ViewVC Help
Powered by ViewVC 1.1.22