2 using System.Runtime.InteropServices;
4 using System.Text.RegularExpressions;
5 using System.Collections.Generic;
25 int LastPBXState = -1;
26 private void UpdatePBXState(
int State)
28 if (State != LastPBXState)
30 string StateName = GetPBXStateName(LastPBXState);
31 if (StateName != null)
36 StateName = GetPBXStateName(State);
37 if (StateName != null)
49 private string GetPBXStateName(
int State)
63 private enum InputActionEnum
75 private Dictionary<int, InputActionEnum> KeyInputs =
new Dictionary<int, InputActionEnum>();
76 private Dictionary<int, InputActionEnum> JoyInputs =
new Dictionary<int, InputActionEnum>();
77 private bool OneClickLaunch =
false;
79 private void AddToDict(Dictionary<int, InputActionEnum> D,
string Code, InputActionEnum Action)
82 if (
int.TryParse(Code, out C))
84 if (!D.ContainsKey(C))
91 private void ReadPBXConfig()
93 Log(
"Loading PBX config data");
94 string IniFileName = Path.Combine(
new DirectoryInfo(
".").FullName,
"config\\PinballX.ini");
96 if (File.Exists(IniFileName))
99 I.
Load(IniFileName,
false);
101 AddToDict(KeyInputs, I.
GetKeyValue(
"KeyCodes",
"quit"), InputActionEnum.Quit);
102 AddToDict(KeyInputs, I.
GetKeyValue(
"KeyCodes",
"left"), InputActionEnum.Left);
103 AddToDict(KeyInputs, I.
GetKeyValue(
"KeyCodes",
"right"), InputActionEnum.Right);
104 AddToDict(KeyInputs, I.
GetKeyValue(
"KeyCodes",
"select"), InputActionEnum.Select);
105 AddToDict(KeyInputs, I.
GetKeyValue(
"KeyCodes",
"pageleft"), InputActionEnum.PageLeft);
106 AddToDict(KeyInputs, I.
GetKeyValue(
"KeyCodes",
"pageright"), InputActionEnum.PageRight);
107 AddToDict(KeyInputs, I.
GetKeyValue(
"KeyCodes",
"instructions"), InputActionEnum.Instructions);
110 AddToDict(JoyInputs, I.
GetKeyValue(
"JoyCodes",
"quit"), InputActionEnum.Quit);
111 AddToDict(JoyInputs, I.
GetKeyValue(
"JoyCodes",
"left"), InputActionEnum.Left);
112 AddToDict(JoyInputs, I.
GetKeyValue(
"JoyCodes",
"right"), InputActionEnum.Right);
113 AddToDict(JoyInputs, I.
GetKeyValue(
"JoyCodes",
"select"), InputActionEnum.Select);
114 AddToDict(JoyInputs, I.
GetKeyValue(
"JoyCodes",
"instructions"), InputActionEnum.Instructions);
118 OneClickLaunch = I.
GetKeyValue(
"Interface",
"OneClickLaunch").Equals(
"True", StringComparison.InvariantCultureIgnoreCase);
124 OneClickLaunch =
false;
127 Log(
"PBX config data loaded");
131 Log(
"No PBX copnfig data found");
136 List<string> TableRomNames =
new List<string>();
142 private void SetupRomNameLinks()
144 Log(
"Loading Table/Romname mappings");
153 Log(
"Table mapping filename: " + TableMappingFileName);
154 if (!
string.IsNullOrEmpty(TableMappingFileName))
159 Log(AllTableMappings.ToString() +
" TableMappings loaded");
162 foreach (
string R
in L)
164 if (R.StartsWith(
"$"))
166 TableRomNames.Add(R.Substring(1).Trim().ToUpper());
171 if (TableRomNames.Count > 0)
173 Log(
"The following " + TableRomNames.Count +
" RomNames are configured in DOF: " +
string.Join(
",", TableRomNames.ToArray()));
177 Log(
"No romnames are configured in DOF.");
180 Log(
"Table/RomName mapping loaded");
193 Dictionary<string, string> RomLookupCache =
new Dictionary<string, string>();
195 private string GetRom(
string GameDecriptionShort)
197 string GameDesc = CleanGameDescription(GameDecriptionShort.ToUpper());
200 if (TableRomNames.Contains(GameDecriptionShort))
return GameDesc;
203 if (RomLookupCache.ContainsKey(GameDesc))
return RomLookupCache[GameDesc];
207 double MatchValue = 0;
216 MatchMapping = Mapping;
220 if(MatchMapping!=null) {
221 Log(
"Best match for " + GameDesc +
" is " + MatchMapping.TableName.ToUpper() +
" (" + MatchMapping.RomName +
"). Match Value: " + MatchValue.ToString());
223 if (MatchValue > 0.55 && MatchMapping!=null)
225 string Rom = MatchMapping.RomName;
228 string UseTableRom = null;
230 foreach (
string TableRomName
in TableRomNames)
232 if (TableRomName.Equals(Rom,StringComparison.InvariantCultureIgnoreCase))
234 UseTableRom = TableRomName;
241 if (!RomLookupCache.ContainsKey(GameDesc))
243 RomLookupCache.Add(GameDesc, UseTableRom);
246 if (UseTableRom != null)
257 private string CleanGameDescription(
string GameName)
259 Regex rgx =
new Regex(
"[^a-zA-Z0-9 ]");
260 RegexOptions options = RegexOptions.None;
261 Regex regex =
new Regex(
@"[ ]{2,}", options);
264 return regex.Replace(rgx.Replace(GameName,
""),
@" ");
270 private void LoadConfig()
272 Log(
"Loading plugin config");
280 Log(
"Plugin config loading failed. Using default values.");
281 Config =
new Config();
284 Log(
"Plugin config loaded");
288 private void Log(
string Text)
292 TextWriter tw = null;
295 tw =
new StreamWriter(Path.Combine(
new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName,
"PinballX DirectOutput Plugin.log"),
true);
297 tw.WriteLine(
"{1:yy.MM.dd hh:mm:ss.fff} {0}", Text, DateTime.Now);
326 Log(
"Initializing plugin");
332 Log(
"Initializing DOF");
334 Log(
"DOF initialized");
339 Log(
"Sending initial PBX state to DOF");
343 Log(
"Init complete");
347 Log(
"Init failed: " + E.Message);
361 Config CO =
new Config(); ;
392 if (!
string.IsNullOrEmpty(LastGameSelect))
407 Log(
"App_Exit failed: " + E.Message);
418 private string LastGameSelect = null;
425 if (!
string.IsNullOrEmpty(LastGameSelect))
429 SendAction(
"PBXGameSelect");
431 if (!
string.IsNullOrEmpty(LastGameSelect))
436 Log(
"Game selected " + Info.
GameShortDescription +
" (" + (
string.IsNullOrEmpty(LastGameSelect) ?
"No update sent" :
"Update sent for " + LastGameSelect) +
")");
440 Log(
"GameSelect failed: " + E.Message);
456 if (!
string.IsNullOrEmpty(LastGameSelect))
467 Log(
"GameRun failed: " + E.Message);
513 Log(
"GameExit failed: " + E.Message);
524 public bool Event_Input(
bool[] Input_Keys,
bool[] Input_Buttons,
int PinballXStatus)
530 InputActionEnum InputAction = GetInputAction(KeyInputs, Input_Keys);
531 if (InputAction == InputActionEnum.NoInput)
533 InputAction = GetInputAction(JoyInputs, Input_Buttons);
536 string PBXAction = null;
537 if (InputAction != InputActionEnum.NoInput)
540 switch (PinballXStatus)
546 case InputActionEnum.Quit:
547 PBXAction =
"PBXQuit";
549 case InputActionEnum.Left:
550 PBXAction =
"PBXWheelRight";
552 case InputActionEnum.Right:
553 PBXAction =
"PBXWheelLeft";
555 case InputActionEnum.Select:
558 PBXAction =
"PBXMenuOpen";
561 case InputActionEnum.PageLeft:
562 PBXAction =
"PBXWheelPageRight";
564 case InputActionEnum.PageRight:
565 PBXAction =
"PBXWheelPageLeft";
567 case InputActionEnum.Instructions:
568 PBXAction =
"PBXInstructions";
579 case InputActionEnum.Quit:
580 PBXAction =
"PBXMenuQuit";
582 case InputActionEnum.Left:
583 PBXAction =
"PBXMenuUp";
585 case InputActionEnum.Right:
586 PBXAction =
"PBXMenuDown";
588 case InputActionEnum.Select:
589 PBXAction =
"PBXMenuSelect";
605 SendAction(PBXAction);
606 UpdatePBXState(PinballXStatus);
611 Log(
"Event_Input failed: " + E.Message);
619 private InputActionEnum GetInputAction(Dictionary<int, InputActionEnum> InputDefs,
bool[] Input)
621 foreach (
int K
in InputDefs.Keys)
629 return InputActionEnum.NoInput;
635 private void SendAction(
string Action)
637 if (!
string.IsNullOrEmpty(Action))
640 Log(
"Action: " + Action);
661 SendAction(
"PBXScreenSaverStart");
666 SendAction(
"PBXScreenSaverQuit");
675 Log(
"Event screensaver failed: " + E.Message);
705 GC.SuppressFinalize(
this);
709 private bool disposed =
false;
715 private void Dispose(
bool disposing)
718 if (!(this.disposed))
738 #region PluginInfo Properties
void Configure()
The method is called when the configure button in the plugin manager of PinballX is clicked...
This is the base calls for PinballX plugins. It contains the public methods which are called from Pin...
bool Event_Input(bool[] Input_Keys, bool[] Input_Buttons, int PinballXStatus)
This method is called when PinballX receives input from keyboard or buttons
string Event_Parameters(IntPtr InfoPtr)
This method is after PinballX has built the command line parameters. You can return a modified comman...
void SignalNamedTableElement(string TableElementName)
string GetKeyValue(string sSection, string sKey)
void Event_GameExit(IntPtr InfoPtr)
This method is called when the emulator exits from a game.
static TableNameMappings LoadTableMappings(string Filename)
Simple class containing the mappinging between tablename and romname
void Dispose()
Releases unmanaged and managed resources.
bool Initialize(IntPtr InfoPtr)
Initializes the plugin. This method is called when PinballX loads and initializes the plugin...
Plugin()
Initializes a new instance of the Plugin class.
string GameShortDescription
static Config GetConfigFromXmlFile(string FileName=null)
Instanciates a config object from a cabinet configuration in a XML file.
const string PluginVersion
void Event_GameSelect(IntPtr InfoPtr)
string GetTableMappingFilename()
void Load(string sFileName, bool bMerge=false)
void Event_App_Exit()
This method is called when PinballX exits
void UpdateNamedTableElement(string TableElementName, int Value)
string[] GetConfiguredTableElmentDescriptors()
bool Event_ScreenSaver(int Type)
This event is called when PinballX starts or quits the screen saver.
static string ConfigFileName
bool Event_GameRun(IntPtr InfoPtr)
This method is called before a game is launched. Return true to tell PinballX process the event Retur...
void SaveConfigXmlFile(string FileName=null)
Serializes the configuration to a XML file.
string TableName
Gets or sets the name of the table. This is not necessarly the same as the name of the table file...