File: PluginCallbacks.h

package info (click to toggle)
pcsx2 1.4.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 22,172 kB
  • ctags: 40,348
  • sloc: cpp: 232,892; ansic: 22,912; asm: 2,273; lisp: 1,346; sh: 561; perl: 253; makefile: 113; xml: 69
file content (1428 lines) | stat: -rw-r--r-- 64,809 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
/*  PCSX2 - PS2 Emulator for PCs
 *  Copyright (C) 2002-2010  PCSX2 Dev Team
 *
 *  PCSX2 is free software: you can redistribute it and/or modify it under the terms
 *  of the GNU Lesser General Public License as published by the Free Software Found-
 *  ation, either version 3 of the License, or (at your option) any later version.
 *
 *  PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 *  PURPOSE.  See the GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along with PCSX2.
 *  If not, see <http://www.gnu.org/licenses/>.
 */


#ifndef __PLUGINCALLBACKS_H__
#define __PLUGINCALLBACKS_H__

// --------------------------------------------------------------------------------------
//  PS2E  -  Version 2.xx!
// --------------------------------------------------------------------------------------
// This header file defines the new PS2E interface, which is laid out to be a little more
// efficient and easy to use, and boasts significantly improved APIs over the original
// PS2E v1.xx, which was mostly a series of hacked additions on top of PS1E.  In summary:
// this API is designed from the ground up to suit PS2 emulation, instead of being built
// on top of a PS1 API.
//
// Design Philosophies:
//
//   1. Core APIs are established using a pair of DLL/library bindings (one for plugin callbacks
//      and one for emulator callbacks), which pass structures of function pointers.
//
//   2. Plugin instance data should be attached to the end of the plugin's callback api
//      data structure (see PS2E_ComponentAPI), and the PS2E_ComponentAPI struct is
//      passed along with every callback defined in the structure.
//
//   3. All plugin callbacks use __fastcall calling convention (which passes the first
//      two parameters int he ECX and EDX registers).  Most compilers support this, and
//      register parameter passing is actually the standard convention on x86/64.
//
// Rationale: This design improves code generation efficiency, especially when using
// points 2 and 3 together (typically reduces 2 or 3 dereferences to 1 dereference).
// The drawback is that not all compilers support x86/32 __fastcall, and such compilers
// will be unable to create PS2Ev2 plugins.  GCC, MSVC, Intel, and Borland (as
// __msfastcall) do support it, and Watcom as well using #pragma aux.  Anything else
// we just don't care about.  Sorry. ;)
//
//   4. Emulation is restricted to a single instance per-process, which means that use of
//      static/global instance variables by plugins is perfectly valid (however discouraged
//      due to efficiency reasons, see 2 and 3).
//
// Rationale: Due to complexities in implementing an optimized PS2 emulator (dynamic
// recompilation, memory protection, console pipe management, thread management, etc.)
// it's really just better this way.  The drawback is that every geeks' dream of having
// 6 different games emulating at once, with each output texture mapped to the side of
// a rotating cube, will probably never come true.  Tsk.
//

// --------------------------------------------------------------------------------------
//  <<< Important Notes to Plugin Authors >>>
// --------------------------------------------------------------------------------------
//  * C++ only: C++ Exceptions must be confined to your plugin!  Exceptions thrown by plugins
//    may not be handled correctly if allowed to escape the scope of the plugin, and could
//    result in unexpected behavior or odd crashes (this especially true on non-Windows
//    operating systems).  For C++ plugins this means ensuring that any code that uses
//    'new' or STL containers (string, list, vector, etc) are contained within a try{}
//    block, since the STL can throw std::bad_alloc.
//
//  * C++ on MSW only: SEH Exceptions must not be swallowed "blindly."  In simple terms this
//    means do not use these without proper re-throws, as the emulator may rely on SEH
//    for either PS2 VM cache validation or thread cancellation:
//      - catch(...)
//      - __except(EXCEPTION_EXECUTE_HANDLER)
//
//  * Many callbacks are optional, and have been marked as such. Any optional callback can be
//    left NULL.  Any callback not marked optional and left NULL will cause the emulator to
//    invalidate the plugin on either enumeration or initialization.
//

// --------------------------------------------------------------------------------------
//  <<< Important Notes to All Developers >>>
// --------------------------------------------------------------------------------------
//  * Callback APIs cannot involve LIB-C or STL objects (such as FILE or std::string).  The
//    internal layout of these structures can vary between versions of GLIB-C / MSVCRT, and
//    in the case of STL and other C++ objects, can vary based on seemingly mundane compiler
//    switches.
//
//  * Callback APIs cannot alloc/free memory across dynamic library boundaries.  An object
//    allocated by a plugin must be freed by that plugin, and cannot be freed by the emu.
//
//  * C++ exception handling cannot be used by either plugin callbacks or emulator callbacks.
//    This includes the emulator's Console callbacks, for example, since the nature of C++
//    ID-based RTTI could cause a C++ plugin with its own catch handlers to catch exceptions
//    of mismatched types from the emulator.
//
//  * Addendum to Exception Handling: On most OS's, pthreads relies on C++ exceptions to
//    cancel threads.  On Windows, this uses SEH so it works safely even across plugin stack
//    frames.  On all other non-MSW platforms pthreads cancelation *must* be disabled in
//    both emulator and plugin except for a single explicit cancelation point (usually
//    provided during vsync).
//
//  * If following all these rules, then it shouldn't matter if you mix debug/release builds
//    of plugins, SEH options (however it's recommended to ALWAYS have SEH enabled, as it
//    hardly has any impact on performance on modern CPUs), compile with different versions
//    of your MSVC/GCC compiler, or use different versions of LibC or MSVCRT. :)


#ifndef BOOL
	typedef int BOOL;
#endif

// --------------------------------------------------------------------------------------
//  PS2E_HWND  -  OS-independent window handle
// --------------------------------------------------------------------------------------
// HWND is our only operating system dependent type.  For it to be defined as accurately
// as possible, this header file needs to be included after whatever window/GUI platform
// headers you need (wxWidgets, Windows.h, GTK, etc).
//
// We could be lazy with this typedef, because window handles are always a (void*) on all
// platforms that matter to us (windows, gtk, OSX).  But Windows has some type strictness
// on its HWND define that could be useful, and well it's probably good practice to use
// platform available defines when they exist.
//
#if defined( _WX_DEFS_H_ )
	typedef WXWidget PS2E_HWND;
#elif defined( _WINDEF_ )
	// For Windows let's use HWND, since it has some type strictness applied to it.
	typedef HWND PS2E_HWND;
#else
	// Unsupported platform... use void* as a best guess.  Should work fine for almost
	// any GUI platform, and certainly works for any currently supported one.
	typedef void* PS2E_HWND;
#endif

// --------------------------------------------------------------------------------------
//  PS2E_THISPTR - (ps2 component scope 'this' object pointer type)
// --------------------------------------------------------------------------------------
// This macro provides C++ plugin authors with a reasonably friendly way to automatically
// typecast the session objects for your plugin to your internal type.  Just #define
// PS2E_THISPTR to your internal structure type prior to loading this header file, and all
// APIs will assume your struct type in their signature.  Since all pointer types are inter-
// changeable, plugin APIs will retain full compatibility as long as PS2E_THISPTR is a
// pointer type.
//
#ifndef PS2E_THISPTR
#	define PS2E_THISPTR struct _PS2E_ComponentAPI*
#else
	// Ensure the user's defined PS2E_THISPTR retains the correct signature for our
	// plugin API.
	static_assert( sizeof(PS2E_THISPTR) == sizeof(void*), "Incorrect signature for PS2E_THISPTR" );
#endif

// PS2E_LIB_THISPTR - (library scope version of PS2E_THISPTR)
#ifndef PS2E_LIB_THISPTR
#	define PS2E_LIB_THISPTR void*
#else
	// Ensure the user's defined PS2E_THISPTR retains the correct signature for our
	// plugin API.
	static_assert( sizeof(PS2E_LIB_THISPTR) == sizeof(void*), "Incorrect signature for PS2E_LIB_THISPTR" );
#endif

// Use fastcall by default, since under most circumstances the object-model approach of the
// API will benefit considerably from it.  (Yes, this means that compilers that do not
// support fastcall are basically unusable for plugin creation.  Too bad. :p
#define PS2E_CALLBACK __fastcall


#ifndef __cplusplus
extern "C" {
#endif

// ------------------------------------------------------------------------------------
//  Plugin Type / Version Enumerations
// ------------------------------------------------------------------------------------

enum PS2E_ComponentTypes
{
	PS2E_TYPE_GS = 0,
	PS2E_TYPE_PAD,
	PS2E_TYPE_SPU2,
	PS2E_TYPE_CDVD,
	PS2E_TYPE_DEV9,
	PS2E_TYPE_USB,
	PS2E_TYPE_FW,
	PS2E_TYPE_SIO,
	PS2E_TYPE_Mcd,
};

enum PluginLibVersion
{
	PS2E_VER_GS		= 0x1000,
	PS2E_VER_PAD	= 0x1000,
	PS2E_VER_SPU2	= 0x1000,
	PS2E_VER_CDVD	= 0x1000,
	PS2E_VER_DEV9	= 0x1000,
	PS2E_VER_USB	= 0x1000,
	PS2E_VER_FW		= 0x1000,
	PS2E_VER_SIO	= 0x1000
};

enum OSDIconTypes
{
	OSD_Icon_None = 0,
	OSD_Icon_Error,
	OSD_Icon_Notice,		// An exclamation point maybe?

	// [TODO] -- dunno.  What else?

	// Emulators implementing their own custom non-standard icon extensions should do so
	// somewhere after OSD_Icon_ReserveEnd.  All values below this are reserved.
	// .
	// .
	// .
	OSD_Icon_ReserveEnd = 0x1000
};

enum PS2E_MenuItemStyle
{
	MenuType_Normal = 0,
	MenuType_Checked,
	MenuType_Radio,
	MenuType_Separator
};

typedef void* PS2E_MenuHandle;
typedef void* PS2E_MenuItemHandle;
typedef void PS2E_CALLBACK PS2E_OnMenuItemClicked( PS2E_THISPTR* thisptr, void* userptr );

// --------------------------------------------------------------------------------------
//  PS2E_ConsoleWriterAPI
// --------------------------------------------------------------------------------------
// APIs for writing text to the console.  Typically the emulator will write the text to
// both a console window and to a disk file, however actual implementation is up to the
// emulator.  All text must be either 7-bit ASCII or UTF8 encoded.  Other codepages or
// MBCS encodings will not be displayed properly.
//
// Standard streams STDIO and STDERR can be used instead, however there is no guarantee
// that they will be handled in a convenient fashion.  Different platforms and operating
// systems have different methods of standard stream pipes, which is why the ConsoleWriter
// API has been exposed to plugins.
//
// Development Notes:
//   'char' was chosen over 'wchar_t' because 'wchar_t' is a very loosely defined type that
//   can vary greatly between compilers (it can be as small as 8 bits and as large as a
//   compiler wants it to be).  Because of this we can't even make assumptions about its
//   size within the context of a single operating system; so it just won't do.  Just make
//   sure everything going into the function is UTF8 encoded and all is find.
//
typedef struct _PS2E_ConsoleWriterAPI
{
	// Writes text to console; no newline is appended.
	void (PS2E_CALLBACK* Write)( const char* fmt, ... );

	// Appends an automatic newline to the specified formatted output.
	void (PS2E_CALLBACK* WriteLn)( const char* fmt, ... );

	// This function always appends a newline.
	void (PS2E_CALLBACK* Error)( const char* fmt, ... );

	// This function always appends a newline.
	void (PS2E_CALLBACK* Warning)( const char* fmt, ... );

	void* reserved[4];

} PS2E_ConsoleWriterAPI;

// --------------------------------------------------------------------------------------
//  PS2E_ConsoleWriterWideAPI
// --------------------------------------------------------------------------------------
// This is the wide character version of the ConsoleWriter APi.  Please see the description
// of PS2E_ConsoleWriterAPI for details.
//
// Important Usage Note to Plugin Authors:
//   Before using the functions in this structure, you *must* confirm that the emulator's
//   size of wchar_t matches the size provided by your own compiler.  The size of wchar_t
//   is provided in the PS2E_EmulatorInfo struct.
//
typedef struct _PS2E_ConsoleWriterWideAPI
{
	// Writes text to console; no newline is appended.
	void (PS2E_CALLBACK* Write)( const wchar_t* fmt, ... );

	// Appends an automatic newline to the specified formatted output.
	void (PS2E_CALLBACK* WriteLn)( const wchar_t* fmt, ... );

	// This function always appends a newline.
	void (PS2E_CALLBACK* Error)( const wchar_t* fmt, ... );

	// This function always appends a newline.
	void (PS2E_CALLBACK* Warning)( const wchar_t* fmt, ... );

	void* reserved[4];

} PS2E_ConsoleWriterWideAPI;


// --------------------------------------------------------------------------------------
//  PS2E_Image
// --------------------------------------------------------------------------------------
// Simple RGBA image data container, for passing surface textures to the GS plugin, and
// for receiving snapshots from the GS plugin.
//
// fixme - this might be more ideal as BGRA or ABGR format on Windows platforms?
//
typedef struct _PS2E_Image
{
	u32 width;
	u32 height;
	u8* data;		// RGBA data.  top to bottom.

} PS2E_Image;

// --------------------------------------------------------------------------------------
//  PS2E_MenuItemInfo
// --------------------------------------------------------------------------------------
typedef struct _PS2E_MenuItemInfo
{
	const char*			LabelText;
	const char*			HelpText;

	// Optional image displayed with the menu option.  The emulator may not support
	// this option, or may choose to ignore or resize the image if the size parameters
	// are outside a valid threshold.
	const PS2E_Image*	Image;

	// Specifies the style of the menu, either Normal, Checked, Radio, or Separator.
	// This option is overridden if the SubMenu field is non-NULL (in such case the
	// menu assumes submenu mode).
	PS2E_MenuItemStyle	Style;

	// Specifies the handle of a sub menu to bind to this menu.  If NULL, the menu is
	// created normally.  If non-NULL, the menu item will use sub-menu mode and will
	// ignore the Style field.
	PS2E_MenuHandle		SubMenu;

	// Menu that this item is attached to.  When this struct is passed into AddMenuItem,
	// the menu item will be automatically appended to the menu specified in this field
	// if the field is non-NULL (if the field is NULL, then no action is taken).
	PS2E_MenuHandle		OwnerMenu;

	// When FALSE the menu item will appear grayed out to the user, and unselectable.
	BOOL				Enabled;

	// Optional user data pointer (or typecast integer value)
	void*				UserPtr;

	// Callback issued when the menu is clicked/activated.  If NULL, the menu will be
	// disabled (grayed).
	PS2E_OnMenuItemClicked* OnClicked;

} PS2E_MenuItemInfo;

// --------------------------------------------------------------------------------------
//  PS2E_MenuItemAPI
// --------------------------------------------------------------------------------------
typedef struct _PS2E_MenuItemAPI
{
	// Allocates a new MenuItem and returns its handle.  The returned item can be added to any
	// menu.
	PS2E_MenuItemHandle (PS2E_CALLBACK* MenuItem_Create)( PS2E_THISPTR thisptr );

	// Deletes the menu item and frees allocated resources.  The menu item will be removed from
	// whatever menu it is attached to.  If the menu item has a SubMenu, the SubMenu is not
	// deleted.
	void (PS2E_CALLBACK* MenuItem_Delete)( PS2E_MenuItemHandle mitem );

	// (Re-)Assigns all properties for a menu.  Assignment generally takes effect immediately.
	void (PS2E_CALLBACK* MenuItem_SetEverything)( PS2E_MenuItemHandle mitem, const PS2E_MenuItemInfo* info );

	// Sets the text label of a menu item.
	void (PS2E_CALLBACK* MenuItem_SetText)( PS2E_MenuItemHandle mitem, const char* text );

	// Assigns the help text for a menu item.  This text is typically shown in a status
	// bar at the bottom of the current window.  This value may be ignored if the emu
	// interface does not have a context for help text.
	void (PS2E_CALLBACK* MenuItem_SetHelpText)( PS2E_MenuItemHandle mitem, const char* helptxt );

	// Gives the menu item an accompanying image (orientation of the image may depend
	// on the operating system platform).
	void (PS2E_CALLBACK* MenuItem_SetImage)( PS2E_MenuItemHandle mitem, const PS2E_Image* image );

	// Gives the menu item an accompanying image (orientation of the image may depend
	// on the operating system platform).
	//
	// Returns:
	//   TRUE if the image was loaded successfully, or FALSE if the image was not found,
	//   could not be opened, or the image data is invalid (not a PNG, or data corrupted).
	BOOL (PS2E_CALLBACK* MenuItem_SetImagePng_FromFile)( PS2E_MenuItemHandle mitem, const char* filename );

	// Gives the menu item an accompanying image (orientation of the image may depend on
	// the operating system platform).  Image is loaded from memory using a memory stream
	// reader.  This method is useful for loading image data embedded into the dll.
	//
	// Returns:
	//   TRUE if the image was loaded successfully, or FALSE if the image data is invalid
	//   (not a PNG, or data corrupted).
	BOOL (PS2E_CALLBACK* MenuItem_SetImagePng_FromMemory)( PS2E_MenuItemHandle mitem, const u8* data );

	// Assigns the menu item's style.
	void (PS2E_CALLBACK* MenuItem_SetStyle)( PS2E_MenuItemHandle mitem, PS2E_MenuItemStyle style );

	// Assigns a pointer value that the plugin can use to attach user-defined data to
	// specific menu items.  The value can be any integer typecast if you don't actually
	// need more than an integers worth of data.
	void (PS2E_CALLBACK* MenuItem_SetUserData)( PS2E_MenuItemHandle mitem, void* dataptr );

	// Assigns a submenu to the menu item, causing it to open the sub menu in cascade
	// fashion.  When a submenu is assigned, the Style attribute of the menu will be
	// ignored.  Passing NULL into this function will clear the submenu and return the
	// menu item to whatever its current Style attribute is set to.
	void (PS2E_CALLBACK* MenuItem_SetSubMenu)( PS2E_MenuItemHandle mitem, PS2E_MenuHandle submenu );

	// Assigns the callback function for this menu (important!).  If passed NULL, the menu
	// item will be automatically disabled (grayed out) by the emulator.
	void (PS2E_CALLBACK* MenuItem_SetCallback)( PS2E_MenuItemHandle mitem, PS2E_OnMenuItemClicked* onClickedCallback );

	// Assigns the enabled status of a MenuItem.  Use FALSE to gray out the menuitem option.
	void (PS2E_CALLBACK* MenuItem_Enable)( PS2E_MenuItemHandle mitem, BOOL enable );

	// Returns the current enable status of the specified menu item.
	BOOL (PS2E_CALLBACK* MenuItem_IsEnabled)( PS2E_MenuItemHandle mitem );

	void* reserved[4];

} PS2E_MenuItemAPI;

// --------------------------------------------------------------------------------------
//  PS2E_VersionInfo
// --------------------------------------------------------------------------------------
// This structure is populated by the plugin via the PS2E_PluginLibAPI::GetVersion()
// callback.  Specify -1 for any Version or Revision to disable/ignore it.  The emulator
// will not factor that info into the display name of the plugin.
//
typedef struct _PS2E_VersionInfo
{
	// Low/Mid/High versions combine to form a number in the format of: 2.3.1
	// ... where 2 is the high version, 3 mid, and 1 low.
	s16 VersionHigh;
	s16 VersionMid;
	s16 VersionLow;

	// Revision typically refers a revision control system (such as SVN).  When displayed
	// by the emulator it will have an 'r' prefixed before it.
	s64 Revision;

} PS2E_VersionInfo;

// --------------------------------------------------------------------------------------
//  PS2E_SessionInfo
// --------------------------------------------------------------------------------------
// This struct is populated by the emulator prior to starting emulation, and is passed to
// each plugin via a call to PS2E_PluginLibAPI::EmuOpen().
//
typedef struct _PS2E_SessionInfo
{
	PS2E_HWND window;

	u32* CycleEE;		// current EE cycle count
	u32* CycleIOP;		// current IOP cycle count

	u32  ElfCRC;		// CRC of the ELF header for this app/game

	// Sony's assigned serial number, valid only for CD/CDVD games (ASCII-Z string).
	//   Ex: SLUS-2932
	//
	// (if the running app is not a sony-registered game, the serial will be a zero
	//  length string).
	char Serial[16];

} PS2E_SessionInfo;

// --------------------------------------------------------------------------------------
//  PS2E_EmulatorInfo
// --------------------------------------------------------------------------------------
// This struct is populated by the emulator when the application is started, and is passed
// to plugins via PS2E_InitAPI.  Plugins may optionally use this information to determine
// compatibility or to select which special CPU-oriented builds and/or functions to bind
// to callbacks.
//
// The GetInt/GetBoolean/GetString/etc methods Provide an interface through which a plugin
// can retrieve special emulator-specific settings and information, or fetch options straight
// from the emulator's ini file itself.  These are intended for advanced plugin/emu binding
// only, and should generally be accompanied with the appropriate version/name checks.
//
// Emulators may implement this as a direct match to the emu's ini file/registry contents
// (recommended), or may provide additional and/or alternative custom strings.  Direct
// ini.registry relationships are preferred since those are easy for a plugin author to
// reference without documentation.
//
typedef struct _PS2E_EmulatorInfo
{
	// Brief name of the emulator (ex: "PCSX2") [required]
	// Depending on the design of the emulator, this string may optionally include version
	// information, however that is not recommended since it can inhibit backward support.
	const char*			EmuName;

	// Version information.  All fields besides the emulator's name are optional.
	PS2E_VersionInfo	EmuVersion;

	// Number of Physical Cores, as detected by the emulator.
	// This should always match the real # of cores supported by hardware.
	int		PhysicalCores;

	// Number of Logical Cores, as detected and/or managed by the emulator.
	// This is not necessarily a reflection of real hardware capabilities.  The emu reserves
	// the right to report this value as it deems appropriate, in management of threading
	// resources.
	int		LogicalCores;

	// Specifies the size of the wchar_t of the emulator, in bytes.  Plugin authors should be
	// sure to check this against your own sizeof(wchar_t) before using any API that has
	// a wchar_t parameter (such as the ConsoleWriterWide interface).  wchar_t is a loosely
	// defined type that can range from 8 bits to 32 bits (realistically, although there is
	// no actual limit on size), and can vary between compilers for the same platform.
	int		Sizeof_wchar_t;


	// Reserved area for future expansion of the structure (avoids having to upgrade the
	// plugin api for amending new extensions).
	int		reserved1[6];

	// GetInt
	// Self-explanatory.
	//
	// Returns:
	//   0 - Value was retrieved successfully.
	//   1 - Unknown value.  Contents of dest are unchanged.
	BOOL (PS2E_CALLBACK* GetInt)( const char* name, int* dest );

	// GetBoolean
	// Assigns *dest either 1 (true) or 0 (false).  Note to Emulators: Returning any non-
	// zero value for true probably "works" but is not recommended, since C/C++ standard
	// specifically defines the result of bool->int conversions as a 0 or 1 result.
	//
	// Returns:
	//   0 - Value was retrieved successfully.
	//   1 - Unknown value.  Contents of dest are unchanged.
	BOOL (PS2E_CALLBACK* GetBoolean)( const char* name, BOOL* result );

	// GetString
	// Copies an ASCII-Z string into the dest pointer, to max length allowed.  The result
	// is always safely zero-terminated (none of that snprintf crap where you have to
	// zero-terminate yourself >_<).
	//
	// Returns:
	//   0 - Value was retrieved successfully.
	//   1 - Unknown value.  Contents of dest are unchanged.
	BOOL (PS2E_CALLBACK* GetString)( const char* name, char* dest, int maxlen );

	// GetStringAlloc
	// Provides an alternative to GetString, that can retrieve strings of arbitrary length.
	// The plugin must provide a valid allocator callback, which takes a size parameter and
	// returns a pointer to an allocation large enough to hold the size.
	//
	// It is then the responsibility of the plugin to free the allocated pointer when it
	// is done with it.
	//
	char* (PS2E_CALLBACK* GetStringAlloc)( const char* name, void* (PS2E_CALLBACK *allocator)(int size) );

	// OSD_WriteLn
	// This function allows the plugin to post messages to the emulator's On-Screen Display.
	// The OSD message will be displayed with the specified icon (optional) for the duration
	// of a few seconds, or until other messages have scrolled it out of view.
	// Implementation of the OSD is emulator specific, and there is no guarantee that the
	// OSD will be honored at all.  If the emulator does not support OSD then this function
	// call is treated as a NOP.
	//
	// Typically a plugin author should only use the OSD for infrequent notices that are
	// potentially useful to users playing games (particularly at fullscreen).  Trouble-
	// shooting and debug information is best dumped to console or to disk log, or displayed
	// using a native popup window managed by the plugin.
	//
	// Parameters:
	//  icon  - an icon identifier, typically from the PS2E_OSDIconTypes enumeration.  Specific
	//     versions of emulators may provide their own icon extensions.  The emulator will
	//     silently ignore unrecognized icon identifiers, thus retaining cross-compat.
	//
	//  msg   - string message displayed to the user.
	//
	void (PS2E_CALLBACK* OSD_WriteLn)( int icon, const char* msg );

	// ----------------------------------------------------------------------------
	//  Menu / MenuItem Section
	// ----------------------------------------------------------------------------

	void (PS2E_CALLBACK* AddMenuItem)( const PS2E_MenuItemInfo* item );

	// Allocates a new menu handle and returns it.  The returned menu can have any valid existing
	// menu items bound to it, and can be assigned as a submenu to any created MenuItem.  The menu
	// can belong to multiple menu items, however menu items can only belong to a single menu.
	PS2E_MenuHandle (PS2E_CALLBACK* Menu_Create)( PS2E_THISPTR thisptr );

	// Deletes the specified menu and frees its allocated memory resources.  NULL pointers are
	// safely ignored.  Any menu items also attached to this menu will be deleted.  Even if you
	// do not explicitly delete your plugin's menu resources, the emulator will do automatic
	// cleanup after the plugin's instance is freed.
	void (PS2E_CALLBACK* Menu_Delete)( PS2E_MenuHandle handle );

	// Adds the specified menu item to this menu. Menu items can only belong to one menu at a
	// time. If you assign an item to a created menu that already belongs to another menu, it
	// will be removed from the other menu and moved to this one.  To append a menu item to
	// multiple menus, you will need to create multiple instances of the item.
	void (PS2E_CALLBACK* Menu_AddItem)( PS2E_MenuHandle menu, PS2E_MenuItemHandle mitem );

	// Interface for creating menu items and modifying their properties.
	PS2E_MenuItemAPI MenuItem;

	// Provides a set of basic console functions for writing text to the emulator's
	// console.  Some emulators may not support a console, in which case these functions
	// will be NOPs.   For plain and simple to-disk logging, plugins should create and use
	// their own logging facilities.
	PS2E_ConsoleWriterAPI Console;

	// Optional wide-version of the Console API.  Use with caution -- wchar_t is platform and
	// compiler dependent, and so plugin authors should be sure to check the emulator's wchar_t
	// side before using this interface.  See PS2E_ConsoleWriterWideAPI comments for more info.
	PS2E_ConsoleWriterWideAPI ConsoleW;

	void* reserved2[8];

} PS2E_EmulatorInfo;


// --------------------------------------------------------------------------------------
//  PS2E_FreezeData
// --------------------------------------------------------------------------------------
// Structure used to pass savestate info between emulator and plugin.
//
typedef struct _PS2E_FreezeData
{
	u32   Size;			// size of the data being frozen or thawed.  This value is allowed to be changed by Freeze().
	void* Data;			// pointer to the data target (freeze) or source (thaw)

} PS2E_FreezeData;


// --------------------------------------------------------------------------------------
//  PS2E_ComponentAPI
// --------------------------------------------------------------------------------------
// The PluginTypeAPI is provided for every PS2 component plugin (see PS2E_ComponentTypes
// enumeration).  For typical dlls which only provide one  plugin type of functionality,
// the plugin only needs one instance of this struct.  For multi-type plugins, for example
// a plugin that supports both DEV9 and FW together, an interface must be provided for
// each component supported.
//
// These are functions provided to the PS2 emulator from the plugin.  The emulator will
// call these functions and expect the plugin to perform defined tasks.
//
typedef struct _PS2E_ComponentAPI
{
	// EmuOpen
	// This function is called by the emulator when an emulation session is started.  The
	// plugin should take this opportunity to bind itself to the given window handle, open
	// necessary audio/video/input devices, etc.
	//
	// Parameters:
	//   session - provides relevant emulation session information.  Provided pointer is
	//      valid until after the subsequent call to EmuClose()
	//
	// Threading: EmuOpen is called from the GUI thread. All other emulation threads are
	//   guaranteed to be suspended or closed at the time of this call (no locks required).
	//
	void (PS2E_CALLBACK* EmuOpen)( PS2E_THISPTR thisptr, const PS2E_SessionInfo *session );

	// EmuClose
	// This function is called by the emulator prior to stopping emulation.  The window
	// handle specified in EmuOpen is guaranteed to be valid at the time EmuClose is called,
	// and the plugin should unload/unbind all window dependencies at this time.
	//
	// Threading: EmuClose is called from the GUI thread.  All other emulation threads are
	//   guaranteed to be suspended or closed at the time of this call (no locks required).
	//
	void (PS2E_CALLBACK* EmuClose)( PS2E_THISPTR thisptr );

	// CalcFreezeSize
	// This function should calculate and return the amount of memory needed for the plugin
	// to freeze its complete emulation state.  The value can be larger than the required
	// amount of space, but cannot be smaller.
	//
	// The emulation state when this function is called is guaranteed to be the same as
	// the following call to Freeze.
	//
	// Thread Safety:
	//   May be called from any thread (GUI, Emu, GS, Unknown, etc).
	//   All Emulation threads are halted at a PS2 logical vsync-end event.
	//   No locking is necessary.
	u32  (PS2E_CALLBACK* CalcFreezeSize)( PS2E_THISPTR thisptr );

	// Freeze
	// This function should make a complete copy of the plugin's emulation state into the
	// provided dest->Data pointer.  The plugin is allowed to reduce the dest->Size value
	// but is not allowed to make it larger.  The plugin will only receive calls to Freeze
	// and Thaw while a plugin is in an EmuOpen() state.
	//
	// Parameters:
	//   dest - a pointer to the Data/Size destination buffer (never NULL).
	//
	// Thread Safety:
	//   May be called from any thread (GUI, Emu, GS, Unknown, etc).
	//   All Emulation threads are halted at a PS2 logical vsync-end event.
	//   No locking is necessary.
	void (PS2E_CALLBACK* Freeze)( PS2E_THISPTR thisptr, PS2E_FreezeData* dest );

	// Thaw
	// Plugin should restore a complete emulation state from the given FreezeData.  The
	// plugin will only receive calls to Freeze and Thaw while a plugin is in an EmuOpen()
	// state.
	//
	// Thread Safety:
	//   May be called from any thread (GUI, Emu, GS, Unknown, etc).
	//   All Emulation threads are halted at a PS2 logical vsync-end event.
	//   No locking is necessary.
	void (PS2E_CALLBACK* Thaw)( PS2E_THISPTR thisptr, const PS2E_FreezeData* src );

	// Configure
	// The plugin should open a modal dialog box with plugin-specific settings and prop-
	// erties.  This function can be NULL, in which case the user's Configure option for
	// this plugin is grayed out.
	//
	// All emulation is suspended and the plugin's state is saved to memory prior to this
	// function being called.  Configure is only called outside the context of EmuOpen()
	// (after a call to EmuClose()).
	//
	// Plugin authors should ensure to re-read and re-apply all settings on EmuOpen(),
	// which will ensure that any user changes will be applied immediately.  For changes
	// that can be applied without emulation suspension, see/use the GUI extensions for
	// menu and toolbar shortcuts.
	//
	// Thread Safety:
	//   Always called from the GUI thread, with emulation in a halted state (no locks
	//   needed).
	void (PS2E_CALLBACK* Configure)( PS2E_THISPTR thisptr );

	// GetLastError
	// This is an optional method with allows the emulator to retrieve extended formatted
	// error information about a recent failed plugin call.  If implemented by the plugin,
	// it should store message information in it's PS2E_THISPTR allocation, and free the
	// string buffers when the plugin's instance is deleted.
	//
	// The plugin is allowed to return NULL for either msg_diag or msg_user (or both).
	// Returned pointers should be static global arrays, and must be NULL terminated.  If
	// only one message is provided, it will be used for both console log and popup.
	//
	// Parameters:
	//   msg_diag - diagnostic message, which is english only and typically intended for
	//      console or disk logging.
	//
	//   msg_user - optional translated user message, which is displayed as a popup to explain
	//      to the user why the plugin failed to initialize.
	//
	// Thread safety:
	//   * Thread Affinity: none.  May be called from any thread.
	//   * Interlocking: Instance.  All calls from the emu are fully interlocked against
	//     the plugin instance.
	//
	void (PS2E_CALLBACK* GetLastError)( PS2E_THISPTR thisptr, char* const* msg_diag, wchar_t* const* msg_user );

	// Reserved area at the end of the structure, for future API expansion.
	void* reserved[8];

} PS2E_ComponentAPI;


// --------------------------------------------------------------------------------------
//  PS2E_LibraryAPI
// --------------------------------------------------------------------------------------
// The LibraryAPI is an overall library-scope set of functions that perform basic Init,
// Shutdown, and global configuration operations.
//
// These are functions provided to the PS2 emulator from the plugin.  The emulator will
// call these functions and expect the plugin to perform defined tasks.
//
// Threading:
//   - get* callbacks in this struct are not bound to any particular thread. Implementations
//     should not assume any specific thread affinity.
//
//   - set* callbacks in this struct are bound to the GUI thread of the emulator, and will
//     always be invoked from that thread.
//
typedef struct _PS2E_LibraryAPI
{
	// GetName
	// Returns an ASCII-Z (zero-terminated) string name of the plugin.  The name should
	// *not* include version or build information.  That info is returned separately
	// via GetVersion.  The return value cannot be NULL (if it is NULL, the emulator
	// will assume the DLL is invalid and ignore it).
	//
	// The pointer should reference a static/global scope char array, or an allocated
	// heap pointer (not recommended).
	//
	// This function may be called multiple times by the emulator, so it should accommodate
	// for such if it performs heap allocations or other initialization procedures.
	const char* (PS2E_CALLBACK* GetName)();

	// GetVersion
	// This function returns name and version information for the requested PS2 component.
	// If the plugin does not support the requested component, it should return NULL.
	// The returned pointer, if non-NULL, must be either a static value [recommended] or a
	// heap-allocated value, and valid for the lifetime of the plugin.
	//
	// This function may be called multiple times by the emulator, so it should accommodate
	// for such if it performs heap allocations or other initialization procedures.
	//
	// Typically a plugin will return the same version for all supported components.  The
	// component parameter is mostly provided to allow this function to serve a dual purpose
	// of both component versioning and as a component enumerator.
	//
	// See PS2E_VersionInfo for more details.
	//
	// Parameters:
	//   component - indicates the ps2 component plugin to be versioned.  If the plugin
	//       does not support the requested component, the function should return NULL.
	//
	const PS2E_VersionInfo* (PS2E_CALLBACK* GetVersion)( u32 component );

	// Test
	// Called by the plugin enumerator to check the hardware availability of the specified
	// component.  The function should return 1 if the plugin appears to be supported, or
	// 0 if the test failed.
	//
	// While a plugin is welcome to use its own CPU capabilities information, it is recommended
	// that you use the emulator provided CPU capabilities structure instead.  The emulator may
	// have provisions in its interface to allow for the forced disabling of extended CPU cap-
	// abilities, for testing purposes.
	//
	BOOL (PS2E_CALLBACK* Test)( u32 component, const PS2E_EmulatorInfo* xinfo );

	// NewComponentInstance
	// The emulator calls this function to fetch the API for the requested component.
	// The plugin is expected to perform an "availability test" (the same test as performed
	// by Test()) and return NULL if the plugin does not support the host machine's hardware
	// or software installations.
	//
	// This function is only called for components which the plugin returned a non-NULL
	// version information struct for in GetVersion().
	//
	// Plugin Allocation Strategy:
	//   The Component API has been designed with function invocation efficiency in mind.
	//   To allocate your plugin's component instance you should create a structure that
	//   contains PS2E_ComponentAPI_* as the first member (where * refers to the PS2
	//   component type), and plugin-specific instance data is stored as any number of
	//   subsequent members in the struct.
	//
	// Parameters:
	//   component - indicates the ps2 component API to return.
	//   dest      - structure to fill with plugin function implementations.  Dest should
	//      be manually typecast by the plugin to match the requested component.
	//
	// OnError:
	//   Plugins may optionally prepare more detailed information on why the plugin failed
	//   it's availability test which the emu can request via GetLastError.
	//
	PS2E_THISPTR (PS2E_CALLBACK* NewComponentInstance)( u32 component );

	// DeleteComponentInstance
	// Called by the emulator when the plugin component is to be shutdown.  The component API
	// instance pointer can be safely deleted here.
	void (PS2E_CALLBACK* DeleteComponentInstance)( PS2E_THISPTR instance );

	// SetSettingsFolder
	// Callback is passed an ASCII-Z string representing the folder where the emulator's
	// settings files are stored (may either be under the user's documents folder, or a
	// location relative to the CWD of the emu application).
	//
	// Typically this callback is only issued once per plugin session, aand prior to the
	// opening of any PS2 components.  It is the responsibility of the emu to save the
	// emulation state, shutdown plugins, and restart everything anew from the new settings
	// in such an event as a dynamic change of the settings folder.
	//
	void (PS2E_CALLBACK* SetSettingsFolder)( const char* folder );

	// SetLogFolder
	// This callback may be issued at any time.  It is the responsibility of the plugin
	// to do the necessary actions to close existing disk logging facilities and re-open
	// new facilities.
	//
	// Thread Safety:
	//   This function is always called from the GUI thread.  All emulation threads are
	//   suspended during the call, so no locking is required.
	//
	void (PS2E_CALLBACK* SetLogFolder)( const char* folder );

	// Reserved area at the end of the structure, for future API expansion.  This area
	// should always be zeroed out, so that future versions of emulators that may have
	// defined functions here will recognize the functions as not supported by the plugin.
	void* reserved[12];

} PS2E_LibraryAPI;

// --------------------------------------------------------------------------------------
//  PS2E_ComponentAPI_GS
// --------------------------------------------------------------------------------------
// Thread Safety:
//   Most GS callbacks are issued from the GS thread only, and are always called synchronously
//   with all other component API functions.  No locks are needed, and DirectX-based GS
//   plugins can safely disable DX multithreading support for speedup (unless the plugin
//   utilizes multiple threads of its own internally).
//
typedef struct _PS2E_ComponentAPI_GS
{
	// Base Component API (inherited structure)
	struct _PS2E_ComponentAPI Base;

	// SetSnapshotsFolder
	// Callback is passed an ASCII-Z string representing the folder where the emulator's
	// snapshots are to be saved (typically located under user documents, but may be CWD
	// or any user-specified location).
	//
	// Thread Safety:
	//   This function may be called from either GUI thread or GS thread.  Emulators calling
	//   it from non-GS threads must ensure mutex locking with TakeSnapshot (meaning the
	//   plugin should be free to disregard threading concerns).
	void (PS2E_CALLBACK* GsSetSnapshotsFolder)( PS2E_THISPTR thisptr, const char* folder );

	// TakeSnapshot
	// The GS plugin is to save the current frame into the given target image.  This
	// function is always called immediately after a GSvsync(), ensuring that the current
	// framebuffer is safely intact for capture.
	//
	// Returns TRUE if the snapshot succeeded, or FALSE if it failed (contents of dest
	// are considered indeterminate and will be ignored by the emu).
	BOOL (PS2E_CALLBACK* GsTakeSnapshot)( PS2E_THISPTR thisptr, PS2E_Image* dest );

	// OSD_QueueMessage
	// Queues a message to the GS for display to the user.  The GS can print the message
	// where-ever it pleases, though it's suggested that the messages be printed either
	// near the top or the bottom of the window (and in the black/empty area if the
	// game's display is letterboxed).
	//
	// Parameters:
	//  message      - text to queue (UTF8 format); will always be a single line (emulator
	//    is responsible for pre-processing linebreaks into multiple messages).  The pointer
	//    will become invalid after this call retunrs, so be sure to make a local copy of the
	//    text.
	//
	//  timeout		 - Suggested timeout period, in milliseconds.  This is a hint and need
	//    not be strictly adhered to by the GS.
	//
	void (PS2E_CALLBACK* OSD_QueueMessage)( PS2E_THISPTR thisptr, const char* msg, int timeout );

	// OSD_IconStatus
	// Sets the visibility status of an icon.  Icon placement can be determined by the GS,
	// although it's recommended that the icon be displayed near a corner of the screen, and
	// be displayed in the empty/black areas if present (letterboxing).
	//
	// Parameters:
	//   iconId     - Icon status to change
	//   alpha      - 0.0 is hdden, 1.0 is visible.  Other alpha values may be used as either
	//     transparency or as a scrolling factor (ie, to scroll the icon in and out of view, in
	//     any way the GS plugin sees fit).
	void (PS2E_CALLBACK* OSD_IconStatus)( PS2E_THISPTR thisptr, OSDIconTypes iconId, float alpha );

	// GSvsync
	//
	// Returns FALSE if the plugin encountered a critical error while updating the display;
	// indicating a device or emulation failure that should terminate the current emulation.
	// (if any critical errors accumulated during GStransferTags or GStransferImage, they
	//  should also be handled here by returning FALSE)
	//
	BOOL (PS2E_CALLBACK* GsVsync)(int field);

	// GSwriteRegs
	// Sends a GIFtag and associated register data.  This is the main transfer method for all
	// GIF register data.  REGLIST mode is unpacked into the forat described below.
	//
	// Note that SIGNAL, FINISH, and LABEL tags are handled internally by the emulator in a
	// thread-safe manner -- the GS plugin should ignore those tags when processing.
	//
	// Returns FALSE if the plugin encountered a critical error while setting texture;
	// indicating a device failure.
	//
	// Parameters:
	//   pMem    - pointer to source memory for the register descriptors and register data.
	//      The first 128 bits (1 qwc) is the descriptors unrolled into 16x8 format.  The
	//      following data is (regcnt x tagcnt) QWCs in length.
	//
	//   regcnt  - number of registers per loop packet (register descriptors are filled
	//      low->high).  Valid range is 1->16, and will never be zero.
	//
	//   nloop   - number of loops of register data.  Valid range is 1->32767 (upper 17
	//      bits are always zero).  This value will never be zero.
	void (PS2E_CALLBACK* GsWriteRegs)(const u128 *pMem, int regcnt, int nloop);

	// GSwritePrim
	// Starts a new prim by sending the specified value to the PRIM register.  The emulator
	// only posts this data to the GS s per the rules of GIFpath processing (note however
	// that packed register data can also contain PRIM writes).
	//
	// Parameters:
	//   primData    - value to write to the PRIM register.  Only the bottom 10 bits are
	//      valid.  Upper bits are always zero.
	void (PS2E_CALLBACK* GsWritePrim)(int primData);

	// GSwriteImage
	// Uploads new image data.  Data uploaded may be in any number of partial chunks, for
	// which the GS is responsible for managing the state machine for writes to GS memory.
	//
	// Plugin authors: Note that it is valid for games to only modify a small portion of a
	// larger texture buffer, or for games to modify several portions of a single large
	// buffer, by using mid-transfer writes to TRXPOS and TRXDIR (TRXPOS writes only become
	// effective once TRXDIR has been written).
	void (PS2E_CALLBACK* GsWriteImage)(const u128 *pMem, int qwc_cnt);

	// GSreadImage
	// This special callback is for implementing the Read mode direction of the GIFpath.
	// The GS plugin writes the texture data as requested by it's internally managed state
	// values for TRXPOS/TRXREG to the buffer provided by pMem.  The buffer size is qwc_cnt
	// and the GS must not write more than that.
	void (PS2E_CALLBACK* GsReadImage)(u128 *pMem, int qwc_cnt);

	void* reserved[8];

} PS2E_ComponentAPI_GS;


// --------------------------------------------------------------------------------------
//  PS2E_McdSizeInfo
// --------------------------------------------------------------------------------------
struct PS2E_McdSizeInfo
{
	u16	SectorSize;					// Size of each sector, in bytes.  (only 512 and 1024 are valid)
	u16 EraseBlockSizeInSectors;	// Size of the erase block, in sectors (max is 16)
	u32	McdSizeInSectors;			// Total size of the card, in sectors (no upper limit)
	u8	Xor;						// Checksum of previous data
};

// --------------------------------------------------------------------------------------
//  PS2E_ComponentAPI_Mcd
// --------------------------------------------------------------------------------------
// Thread Safety:
//  * Thread affinity is not guaranteed.  Calls may be made from either the main emu thread
//    or an IOP child thread (if the emulator uses one).
//
//  * No locking required: All calls to the memory cards are interlocked by the emulator.
//
typedef struct _PS2E_ComponentAPI_Mcd
{
	// Base Component API (inherited structure)
	struct _PS2E_ComponentAPI Base;

	// McdIsPresent
	// Called by the emulator to detect the availability of a memory card.  This function
	// will be called frequently -- essentially whenever the SIO port for the memory card
	// has its status polled - so its overhead should be minimal when possible.
	//
	// Returns:
	//   False if the card is not available, or True if it is available.
	//
	BOOL (PS2E_CALLBACK* McdIsPresent)( PS2E_THISPTR thisptr, uint port, uint slot );

	// McdGetSectorSize  (can be NULL)
	// Requests memorycard formatting information from the Mcd provider.  See the description of
	// PS2E_McdSizeInfo for details on each field.  If the Mcd provider supports only standard 8MB
	// carts, then this function can be NULL.
	// 
	// Returns:
	//   Assigned values for memorycard sector size and sector count in 'outways.' 
	//
	void (PS2E_CALLBACK* McdGetSizeInfo)( PS2E_THISPTR thisptr, uint port, uint slot, PS2E_McdSizeInfo* outways );

	// McdIsPSX
	// Checks if the memorycard is a PSX one from the Mcd provider.
	// 
	// Returns:
	//   False: PS2, True: PSX
	//
	bool (PS2E_CALLBACK* McdIsPSX)( PS2E_THISPTR thisptr, uint port, uint slot );

	// McdRead
	// Requests that a block of data be loaded from the memorycard into the specified dest
	// buffer (which is allocated by the caller).  Bytes read should match the requested
	// size.  Reads *must* be performed synchronously (function cannot return until the
	// read op has finished).
	//
	// Returns:
	//   False on failure, and True on success.  Emulator may use GetLastError to retrieve additional
	//   information for logging or displaying to the user.
	//
	BOOL (PS2E_CALLBACK* McdRead)( PS2E_THISPTR thisptr, uint port, uint slot, u8 *dest, u32 adr, int size );

	// McdSave
	// Saves the provided block of data to the memorycard at the specified seek address.
	// Writes *must* be performed synchronously (function cannot return until the write op
	// has finished).  Write cache flushing is optional.
	//
	// Returns:
	//   False on failure, and True on success.  Emulator may use GetLastError to retrieve additional
	//   information for logging or displaying to the user.
	//
	BOOL (PS2E_CALLBACK* McdSave)( PS2E_THISPTR thisptr, uint port, uint slot, const u8 *src, u32 adr, int size );

	// McdEraseBlock
	// Saves "cleared" data to the memorycard at the specified seek address.  Cleared data
	// is a series of 0xff values (all bits set to 1).
	// Writes *must* be performed synchronously (function cannot return until the write op
	// has finished).  Write cache flushing is optional.
	//
	// Returns:
	//   False on failure, and True on success.  Emulator may use GetLastError to retrieve additional
	//   information for logging or displaying to the user.
	//
	BOOL (PS2E_CALLBACK* McdEraseBlock)( PS2E_THISPTR thisptr, uint port, uint slot, u32 adr );

	u64 (PS2E_CALLBACK* McdGetCRC)( PS2E_THISPTR thisptr, uint port, uint slot );

	// McdNextFrame
	// Inform the memory card that a frame of emulation time has passed.
	// Used by the FolderMemoryCard to find a good time to flush written data to the host file system.
	void (PS2E_CALLBACK* McdNextFrame)( PS2E_THISPTR thisptr, uint port, uint slot );

	void (PS2E_CALLBACK* McdReIndex)( PS2E_THISPTR thisptr, uint port, uint slot, const wxString& filter );

	void* reserved[6];

} PS2E_ComponentAPI_Mcd;


// ------------------------------------------------------------------------------------
//  KeyEvent type enumerations
// ------------------------------------------------------------------------------------

enum PS2E_KeyEventTypes
{
	PS2E_KEY_UP = 0,
	PS2E_KEY_DOWN
};

enum PS2E_KeyModifiers
{
	PS2E_SHIFT = 1,
	PS2E_CONTROL = 2,
	PS2E_ALT = 4
};

// --------------------------------------------------------------------------------------
//  PS2E_KeyEvent
// --------------------------------------------------------------------------------------
// Structure used to key event data from pad plugin to emulator.
//
typedef struct _PS2E_KeyEvent
{
	PS2E_KeyEventTypes event;

	// Value of the key being pressed or released
	uint value;

	// Combination of PS2E_SHIFT, PS2E_CONTROL, and/or PS2E_ALT, indicating which
	// modifier keys were also down when the key was pressed.
	uint flags;

} PS2E_KeyEvent;


// --------------------------------------------------------------------------------------
//  PS2E_ComponentAPI_Pad
// --------------------------------------------------------------------------------------
// Thread Safety:
//  * Thread affinity is not guaranteed.  Even PadKeyEvent may be called from a thread not
//    belonging to the active window (the window where the GA is output).  Other calls may
//    be made from either the main emu thread or an EE/IOP/GS child thread (if the emulator
//    uses them).
//
typedef struct _PS2E_ComponentAPI_Pad
{
	// Base Component API (inherited structure)
	struct _PS2E_ComponentAPI Base;

	// PadIsPresent
	// Called by the emulator to detect the availability of a pad.  This function will
	// be called frequently -- essentially whenever the SIO port for the pad has its
	// status polled - so its overhead should be minimal when possible.
	//
	// A plugin should behave reasonably when a pad that's not plugged in is polled.
	//
	// Returns:
	//   False if the card/pad is not available, or True if it is available.
	//
	BOOL (PS2E_CALLBACK* PadIsPresent)( PS2E_THISPTR thisptr, uint port, uint slot );

	// PadStartPoll
	// Called by the emulator to start polling the specified pad.
	//
	// Returns:
	//   First byte in response to the poll (Typically 0xff).
	//
	// Threading:
	//   Called from the EEcore thread.  The emulator performs no locking of its own, so
	//   calls to this may occur concurrently with calls to PadUpdate.
	//
	u8 (PS2E_CALLBACK* PadStartPoll)( PS2E_THISPTR thisptr, uint port, uint slot );

	// PadPoll
	// Continues polling the specified pad, sending the given value.
	//
	// Returns:
	//   Next byte in response to the poll.
	//
	// Threading:
	//   Called from the EEcore thread.  The emulator performs no locking of its own, so
	//   calls to this may occur concurrently with calls to PadUpdate.
	//
	u8 (PS2E_CALLBACK* PadPoll)( PS2E_THISPTR thisptr, u8 value );

	// PadKeyEvent
	// Called by the emulator in the gui thread to check for keys being pressed or released.
	//
	// Returns:
	//   PS2E_KeyEvent:  Key being pressed or released.  Should stay valid until next call to
	//                   PadKeyEvent or plugin is closed with EmuClose.
	//
	// Threading:
	//   May be called from any thread.  The emulator performs no locking of its own, so
	//   calls to this may occur concurrently with calls to PadUpdate.
	//
	PS2E_KeyEvent* (PS2E_CALLBACK* PadGetKeyEvent)( PS2E_THISPTR thisptr );

	// PadUpdate
	// This callback is issued from the thread that owns the GSwindow, at roughly 50/60hz,
	// allowing the Pad plugin to use it for update logic that expects thread affinity with
	// the GSwindow.
	//
	// Threading:
	//   Called from the same thread that owns the GSwindow (typically either a GUI thread
	//   or an MTGS thread). The emulator performs no locking of its own, so calls to this
	//   may occur concurrently with calls to PadKeyEvent and PadPoll.
	//
	void (PS2E_CALLBACK* PadUpdate)( PS2E_THISPTR thisptr );

	void* reserved[8];

} PS2E_ComponentAPI_Pad;


// --------------------------------------------------------------------------------------
//  PS2E_InitAPI
// --------------------------------------------------------------------------------------
// Called by the emulator when the plugin is loaded into memory.  The emulator uses the
// presence of this function to detect PS2E-v2 plugin API, and will direct all subsequent
// calls through the returned LibraryAPI.  The function is allowed to return NULL if the
// emulator's version information or machine capabilities are insufficient for the
// plugin's needs.
//
// Note: It is recommended that plugins query machine capabilities from the emulator rather
// than the operating system or CPUID directly, since it allows the emulator the option of
// overriding the reported capabilities, for diagnostic purposes.  (such behavior is not
// required, however)
//
// This function is called *once* for the duration of a loaded plugin.
//
// Returns:
//   A pointer to a static structure that contains the API for this plugin, or NULL if
//   the plugin explicitly does not support the emulator version or machine specs.
//
// OnError:
//   Plugins may optionally prepare more detailed information on why the plugin failed
//   it's availability test which the emu can request via PS2E_GetLastError.
//
// Thread Safety:
//  * Affinity: Called only from the Main/GUI thread.
//  * Interlocking: Full interlocking garaunteed.
//
typedef const PS2E_LibraryAPI* (PS2E_CALLBACK* _PS2E_InitAPI)( const PS2E_EmulatorInfo* emuinfo );

// --------------------------------------------------------------------------------------
//  PS2E_GetLastError
// --------------------------------------------------------------------------------------
// Optional method which may be called by the emulator if the plugin returned NULL on
// PS2E_InitAPI.  Plugins may return NULL for either/both msg_diag and msg_user.  Returned
// pointers should be static global arrays, and must be NULL terminated.  If only one
// message is provided, it will be used for both console log and popup.
//
// Parameters:
//   msg_diag - diagnostic message, which is english only and typically intended for console
//      or disk logging.
//
//   msg_user - optional translated user message, which is displayed as a popup to explain
//      to the user why the plugin failed to initialize.
//
typedef void (PS2E_CALLBACK* _PS2E_GetLastError)( char* const* msg_diag, wchar_t* const* msg_user  );

//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Begin old legacy API here (present for reference purposes only, until all plugin API
// specifics have been accounted for)
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////

#if 0
// SPU2
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
typedef s32  (CALLBACK* _SPU2init)(char *configpath);
typedef s32  (CALLBACK* _SPU2open)(void *pDisplay);
typedef void (CALLBACK* _SPU2close)();
typedef void (CALLBACK* _SPU2shutdown)();
typedef void (CALLBACK* _SPU2write)(u32 mem, u16 value);
typedef u16  (CALLBACK* _SPU2read)(u32 mem);

typedef void (CALLBACK* _SPU2readDMA4Mem)(u16 *pMem, u32 size);
typedef void (CALLBACK* _SPU2writeDMA4Mem)(u16 *pMem, u32 size);
typedef void (CALLBACK* _SPU2interruptDMA4)();
typedef void (CALLBACK* _SPU2readDMA7Mem)(u16 *pMem, u32 size);
typedef void (CALLBACK* _SPU2writeDMA7Mem)(u16 *pMem, u32 size);
typedef void (CALLBACK* _SPU2interruptDMA7)();

typedef void (CALLBACK* _SPU2readDMAMem)(u16 *pMem, u32 size, u8 core);
typedef void (CALLBACK* _SPU2writeDMAMem)(u16 *pMem, u32 size, u8 core);
typedef void (CALLBACK* _SPU2interruptDMA)(u8 core);
typedef void (CALLBACK* _SPU2setDMABaseAddr)(uptr baseaddr);
typedef void (CALLBACK* _SPU2irqCallback)(void (*SPU2callback)(),void (*DMA4callback)(),void (*DMA7callback)());
typedef bool (CALLBACK* _SPU2setupRecording)(bool start);

typedef void (CALLBACK* _SPU2setClockPtr)(u32*ptr);
typedef void (CALLBACK* _SPU2setTimeStretcher)(short int enable);

typedef u32 (CALLBACK* _SPU2ReadMemAddr)(u8 core);
typedef void (CALLBACK* _SPU2WriteMemAddr)(u8 core,u32 value);
typedef void (CALLBACK* _SPU2async)(u32 cycles);
typedef s32  (CALLBACK* _SPU2freeze)(u8 mode, freezeData *data);
typedef void (CALLBACK* _SPU2keyEvent)(keyEvent* ev);
typedef void (CALLBACK* _SPU2configure)();
typedef s32  (CALLBACK* _SPU2test)();
typedef void (CALLBACK* _SPU2about)();

// CDVD
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
typedef s32  (CALLBACK* _CDVDinit)(char *configpath);
typedef s32  (CALLBACK* _CDVDopen)(const char* pTitleFilename);
typedef void (CALLBACK* _CDVDclose)();
typedef void (CALLBACK* _CDVDshutdown)();
typedef s32  (CALLBACK* _CDVDreadTrack)(u32 lsn, int mode);
typedef u8*  (CALLBACK* _CDVDgetBuffer)();
typedef s32  (CALLBACK* _CDVDreadSubQ)(u32 lsn, cdvdSubQ* subq);
typedef s32  (CALLBACK* _CDVDgetTN)(cdvdTN *Buffer);
typedef s32  (CALLBACK* _CDVDgetTD)(u8 Track, cdvdTD *Buffer);
typedef s32  (CALLBACK* _CDVDgetTOC)(void* toc);
typedef s32  (CALLBACK* _CDVDgetDiskType)();
typedef s32  (CALLBACK* _CDVDgetTrayStatus)();
typedef s32  (CALLBACK* _CDVDctrlTrayOpen)();
typedef s32  (CALLBACK* _CDVDctrlTrayClose)();

typedef void (CALLBACK* _CDVDkeyEvent)(keyEvent* ev);
typedef s32  (CALLBACK* _CDVDfreeze)(u8 mode, freezeData *data);
typedef void (CALLBACK* _CDVDconfigure)();
typedef s32  (CALLBACK* _CDVDtest)();
typedef void (CALLBACK* _CDVDabout)();
typedef void (CALLBACK* _CDVDnewDiskCB)(void (*callback)());

// DEV9
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
typedef s32  (CALLBACK* _DEV9init)(char *configpath);
typedef s32  (CALLBACK* _DEV9open)(void *pDisplay);
typedef void (CALLBACK* _DEV9close)();
typedef void (CALLBACK* _DEV9shutdown)();
typedef u8   (CALLBACK* _DEV9read8)(u32 mem);
typedef u16  (CALLBACK* _DEV9read16)(u32 mem);
typedef u32  (CALLBACK* _DEV9read32)(u32 mem);
typedef void (CALLBACK* _DEV9write8)(u32 mem, u8 value);
typedef void (CALLBACK* _DEV9write16)(u32 mem, u16 value);
typedef void (CALLBACK* _DEV9write32)(u32 mem, u32 value);
typedef void (CALLBACK* _DEV9readDMA8Mem)(u32 *pMem, int size);
typedef void (CALLBACK* _DEV9writeDMA8Mem)(u32 *pMem, int size);
typedef void (CALLBACK* _DEV9irqCallback)(DEV9callback callback);
typedef DEV9handler (CALLBACK* _DEV9irqHandler)(void);

typedef void (CALLBACK* _DEV9keyEvent)(keyEvent* ev);
typedef s32  (CALLBACK* _DEV9freeze)(int mode, freezeData *data);
typedef void (CALLBACK* _DEV9configure)();
typedef s32  (CALLBACK* _DEV9test)();
typedef void (CALLBACK* _DEV9about)();

// USB
// NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones
typedef s32  (CALLBACK* _USBinit)(char *configpath);
typedef s32  (CALLBACK* _USBopen)(void *pDisplay);
typedef void (CALLBACK* _USBclose)();
typedef void (CALLBACK* _USBshutdown)();
typedef u8   (CALLBACK* _USBread8)(u32 mem);
typedef u16  (CALLBACK* _USBread16)(u32 mem);
typedef u32  (CALLBACK* _USBread32)(u32 mem);
typedef void (CALLBACK* _USBwrite8)(u32 mem, u8 value);
typedef void (CALLBACK* _USBwrite16)(u32 mem, u16 value);
typedef void (CALLBACK* _USBwrite32)(u32 mem, u32 value);
typedef void (CALLBACK* _USBasync)(u32 cycles);


typedef void (CALLBACK* _USBirqCallback)(USBcallback callback);
typedef USBhandler (CALLBACK* _USBirqHandler)(void);
typedef void (CALLBACK* _USBsetRAM)(void *mem);

typedef void (CALLBACK* _USBkeyEvent)(keyEvent* ev);
typedef s32  (CALLBACK* _USBfreeze)(int mode, freezeData *data);
typedef void (CALLBACK* _USBconfigure)();
typedef s32  (CALLBACK* _USBtest)();
typedef void (CALLBACK* _USBabout)();

//FW
typedef s32  (CALLBACK* _FWinit)(char *configpath);
typedef s32  (CALLBACK* _FWopen)(void *pDisplay);
typedef void (CALLBACK* _FWclose)();
typedef void (CALLBACK* _FWshutdown)();
typedef u32  (CALLBACK* _FWread32)(u32 mem);
typedef void (CALLBACK* _FWwrite32)(u32 mem, u32 value);
typedef void (CALLBACK* _FWirqCallback)(void (*callback)());

typedef void (CALLBACK* _FWkeyEvent)(keyEvent* ev);
typedef s32  (CALLBACK* _FWfreeze)(int mode, freezeData *data);
typedef void (CALLBACK* _FWconfigure)();
typedef s32  (CALLBACK* _FWtest)();
typedef void (CALLBACK* _FWabout)();

// General
extern _PS2EgetLibType PS2EgetLibType;
extern _PS2EgetLibVersion2 PS2EgetLibVersion2;
extern _PS2EgetLibName PS2EgetLibName;
extern _PS2EpassConfig PS2EpassConfig;

#endif

#ifndef __cplusplus
}
#endif

#endif // __PLUGINCALLBACKS_H__