ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/EmuXPortal/branches/mono/EmuXPortal/Form1.cs
Revision: 612
Committed: Fri Apr 22 21:30:03 2022 UTC (5 months, 1 week ago) by william
File size: 11901 byte(s)
Log Message:
+ remove splashloader -- just add progress bar to main form
+ improve layout of main form

File Contents

# Content
1 //#define DEV_DEBUG
2
3
4 #if DEV_DEBUG
5 #define FORCE_CACHE_REBULD // when defined will force rebuilding of cache
6 #endif
7 //#define DISABLE_PLUGINS // when defined plugin loading an their use will be disabled
8
9 //#define HAVE_X11_BORDERSTYLE_ERROR // indicates that there is an error with Control.set_InternalBorderStyle resulting in an X11 Error BadWindow (invalid Window parameter)
10
11 //#define DISABLE_WORKER_PROGRESS_EVENT // when defined will disable worker progress events
12 //#define DISABLE_SPLASH // when defined will not show a splash (e.g. during cache building)
13
14 //#define DISABLE_CURSOR_HIDE // when this is present, the cursor will not be hidden
15 //#define DISABLE_PROGRESS_PERCENTAGE_MESSASGE // when this is present, no progress percent message will be shown on any progressbar
16
17
18 #if DEV_DEBUG
19 #warning DEV_DEBUG is enabled
20 #endif
21
22 using System;
23 using System.Collections.Generic;
24 using System.ComponentModel;
25 using System.Data;
26 using System.Drawing;
27 using System.Linq;
28 using System.Text;
29 using System.Windows.Forms;
30 using EmuXPortal.Api;
31 using System.Diagnostics;
32 using System.Reflection;
33 using System.Threading;
34 using Utilities.TransparentControls;
35 using Enterprise.Logging;
36 using System.IO;
37 using Enterprise.CrossPlatform;
38 using EmuXPortal.UI;
39 using EmuXPortal.UI.RenderControls;
40 using EmuXPortal.Plugins;
41 using irexec_api;
42
43 namespace EmuXPortal {
44 public partial class Form1 : Form {
45 static readonly System.Drawing.Color DEFAULT_TEXTFORECOLOR = System.Drawing.Color.Lime;
46 static readonly System.Drawing.Color DEFAULT_TEXTFORECOLOR_ERROR = System.Drawing.Color.Yellow;
47 static readonly System.Drawing.Color DEFAULT_TEXTFORECOLOR_LAUNCH = System.Drawing.Color.Blue;
48 static readonly System.Drawing.Color DEFAULT_TEXTFORECOLOR_MISSING = System.Drawing.Color.Red;
49
50 //const string irexec = "/usr/bin/irexec";
51 const string irexec = "irexec";
52 const string irexec_lircrc = "emuxportal.lircrc";
53
54 Thread irexec_thread_monitor = null;
55
56 static bool bUserAbort = false;
57
58 private const int WINDOW_MODE_WIDTH = 900;
59 private const int WINDOW_MODE_HEIGHT = 500;
60 private const int INPUT_POLLING_FREQUENCY = 100;
61
62
63 #if DEV_DEBUG && FORCE_CACHE_REBULD
64 private const bool bRebuildCache = false;
65 #else
66 private bool bRebuildCache = false;
67 #endif
68
69 private CustomProgressBar progress_bar;
70 private IPlatformCache cache = null;
71 private bool bConfigLoaded = false;
72
73 private System.Windows.Forms.Timer input_queue_handler;
74
75 private bool bInputQueuHandlerRunning = false;
76 private bool bInputQueueDisabled = false;
77
78 private Queue<KeyArrayArgs> event_queue;
79 private readonly object event_queue_lock = new object ();
80
81
82 private void do_irexec_monitor ()
83 {
84 var manager = IRExecManager.CreateManager ();
85 string arguments = Enterprise.CrossPlatform.OSInfo.FormatPath (string.Format ("{0}/{1}", Application.StartupPath, irexec_lircrc));
86 manager.SetIRExecArguments (arguments);
87
88 try {
89 while (true) {
90 manager.StartIRExec ();
91 Thread.Sleep (100);
92 }
93 } catch (ThreadAbortException) {
94 //gLog.Verbose.Error.WriteLine (ex.ToString ());
95 manager.StopIRExec ();
96 }
97
98 }
99
100 private void HookIRExec ()
101 {
102 irexec_thread_monitor = new Thread (new ThreadStart (do_irexec_monitor));
103 irexec_thread_monitor.SetApartmentState (ApartmentState.STA);
104 irexec_thread_monitor.Start ();
105 }
106 private void UnHookIRExec ()
107 {
108 if (irexec_thread_monitor != null && irexec_thread_monitor.IsAlive) {
109 irexec_thread_monitor.Abort ();
110 irexec_thread_monitor = null;
111 }
112 }
113 static bool OnAbort ()
114 {
115
116 return bUserAbort;
117 }
118 #region unhandled exception support
119 static void Application_Unhandled_ThreadException (object sender, ThreadExceptionEventArgs e)
120 {
121 UnhandledExceptionEventArgs uea = new UnhandledExceptionEventArgs (e.Exception, false);
122 UnhandledExceptionEventHandler (sender, uea);
123 }
124 static void UnhandledExceptionEventHandler (object sender, UnhandledExceptionEventArgs args)
125 {
126 Exception ex = (args.ExceptionObject as Exception);
127 if (sender == null) {
128 gLog.Error.WriteLine ("Caught an unhandled exception from an unkown source");
129 } else {
130 gLog.Error.WriteLine ("Caught an unhandled exception from type: {0}", sender.GetType ().Name);
131 }
132
133 if (ex == null) {
134 gLog.Error.WriteLine ("The exception object was null -- it probably is not derived from System.Exception");
135 } else {
136 ex = ex.GetBaseException ();
137 gLog.Error.WriteLine ("{0}:", ex.GetType ().Name);
138 gLog.Verbose.Error.WriteLine (ex.ToString ());
139 }
140
141 }
142 #endregion
143 public Form1 ()
144 {
145 InitializeComponent ();
146 this.progress_bar = new CustomProgressBar ();
147
148 #region logging support
149 string log_path = Application.StartupPath;
150 string log_filename = string.Format ("{0}.log", typeof (Form1).Assembly.GetName ().Name);
151 FileInfo log_file = new FileInfo (OSInfo.FormatPath (string.Format (@"{0}\{1}", log_path, log_filename)));
152
153 gLog.CreateLog (log_file.Name, true, LogLevel.kLogLevel_All_NoProgress, new EventHandler<LoggerOnFlushEventArgs> (Log_OnFlush));
154 LogLevel gLevel = gLog.LogLevel;
155 #if DEBUG
156 gLevel |= LogLevel.kLogLevel_Debug;
157 gLevel |= LogLevel.kLogLevel_VerboseDebug;
158 #else
159 gLevel &= ~LogLevel.kLogLevel_Debug;
160 gLevel &= ~LogLevel.kLogLevel_VerboseDebug;
161 #endif
162
163 gLog.SetLogLevel(gLevel);
164
165 #endregion
166
167 #region unhandled exception support
168 // AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionEventHandler);
169 // Application.ThreadException += Application_Unhandled_ThreadException;
170 #endregion
171
172 HookIRExec ();
173 #if !DISABLE_PLUGINS
174 event_queue = new Queue<KeyArrayArgs> ();
175 PluginLoader.LoadPlugins ();
176 PluginLoader.InitializeInputSystem ();
177
178 input_queue_handler = new System.Windows.Forms.Timer ();
179 input_queue_handler.Tick += Input_Queue_Handler_Tick;
180 input_queue_handler.Interval = INPUT_POLLING_FREQUENCY;
181 input_queue_handler.Enabled = true;
182 input_queue_handler.Start ();
183 #endif
184 }
185
186 #if !DISABLE_PLUGINS
187 void Input_Queue_Handler_Tick (object sender, EventArgs e)
188 {
189 if (bInputQueueDisabled) {
190 return;
191 }
192 if (bInputQueuHandlerRunning) { return; }
193 if (event_queue.Count > 0) {
194 bInputQueuHandlerRunning = true;
195 KeyArrayArgs key_event = null;
196 lock (event_queue_lock) {
197 key_event = event_queue.Dequeue ();
198 }
199 var keys = key_event.GetKeys ();
200 string key_string = KeyConverter.getSendKeysString (keys);
201 StringBuilder sb = new StringBuilder ();
202 keys.ToList ().ForEach ((Keys obj) => sb.AppendFormat (" {0}", obj));
203 SendKeys.Send (key_string);
204 bInputQueuHandlerRunning = false;
205 }
206 }
207
208
209 void Handle_InputPoll (object sender, KeyArrayArgs e)
210 {
211 if (!bInputQueueDisabled) {
212 lock (event_queue_lock) {
213 event_queue.Enqueue (e);
214 }
215 }
216 }
217 #endif
218
219
220 #region logging support
221 void Log_OnFlush (object sender, LoggerOnFlushEventArgs e) { OnLogFlush (e.Buffer); }
222
223
224
225
226 void OnLogFlush (string logmessage)
227 {
228 //if (this.IsDisposed) { return; }
229 ////UpdateStatus(logmessage);
230 ////UpdateLogOutput(logmessage);
231 //Application.DoEvents();
232 }
233 #endregion
234
235 private bool bCachedLoaded = false;
236 private bool OnCacheLoaded ()
237 {
238 return bCachedLoaded;
239 }
240
241
242 private void HandleCommandLine ()
243 {
244 var cargs = new List<String> (System.Environment.GetCommandLineArgs ());
245 if (cargs.Contains ("--rebuild")) {
246 #if !DEV_DEBUG
247 bRebuildCache = true;
248 #endif
249 }
250 }
251
252
253 private void Form1_Load (object sender, EventArgs e)
254 {
255 HandleCommandLine ();
256 Config.InitializePresentationForm (this);
257 this.Activated += Handle_Activated;
258
259 }
260
261
262 void Handle_Activated (object sender, EventArgs e)
263 {
264 this.Activated -= Handle_Activated;
265 this.cache_worker.RunWorkerAsync ();
266 }
267
268 void Rom_Flow_RomLaunched (object sender, RomLaunchArgs e)
269 {
270 var flags = e.RomLaunchFlags;
271 var info = e.RomInfo;
272 string game_name = "";
273 if (info == null) {
274 gLog.Warn.WriteLine ("recieved null rom info!");
275 } else {
276 game_name = info.RomTitle;
277 }
278
279 if (flags == RomLaunchFlags.BEGIN_LAUNCH) {
280 gLog.Debug.WriteLine ("Game '{0}' has been launched, disabling input queue",game_name);
281 bInputQueueDisabled = true;
282 PluginLoader.DisableInputPolling ();
283 } else if (flags == RomLaunchFlags.END_LAUNCH) {
284 gLog.Debug.WriteLine ("Game '{0}' has exited, re-enabling input queue",game_name);
285 bInputQueueDisabled = false;
286 PluginLoader.EnableInputPolling ();
287 } else {
288 if (flags != RomLaunchFlags.NONE) {
289 gLog.Debug.WriteLine ("Unknown rom launch flag: {0}", (int)flags);
290 }
291 }
292 }
293
294
295
296 void ControlsRendered (object sender, EventArgs e)
297 {
298
299 }
300
301 void SwitchControls (object sender, EventArgs e)
302 {
303 PlatformGridContrainer pc = (sender as PlatformGridContrainer);
304 if (pc != null) {
305 platform_flow.Visible = false;
306 rom_flow.Visible = true;
307 rom_flow.BringToFront ();
308 rom_flow.setCurrentRomPlatform (pc.getCurrentPlatform ());
309 rom_flow.Focus ();
310 rom_flow.renderControls ();
311 }
312 GameGridContainer gc = (sender as GameGridContainer);
313 if (gc != null) {
314 rom_flow.Visible = false;
315 platform_flow.Visible = true;
316 platform_flow.BringToFront ();
317 platform_flow.Focus ();
318 }
319 }
320
321 private void platform_flow_VisibleChanged (object sender, EventArgs e)
322 {
323 if (!platform_flow.Visible) return;
324 platform_flow.Width = this.Width - 10;
325 platform_flow.renderControls ();
326 }
327
328 private void rom_flow_VisibleChanged (object sender, EventArgs e)
329 {
330 if (!rom_flow.Visible) return;
331 rom_flow.Width = this.Width - 10;
332 }
333
334
335 private void Form1_FormClosing (object sender, FormClosingEventArgs e)
336 {
337 this.UnHookIRExec ();
338 }
339 private void Form1_FormClosed (object sender, FormClosedEventArgs e)
340 {
341 Cursor.Show ();
342 PluginLoader.EndInputPolling ();
343 }
344
345 private void Cache_Worker_DoWork (object sender, DoWorkEventArgs e)
346 {
347
348 #if !DISABLE_SPLASH
349 this.Controls.Add (splash);
350 this.splash.Width = this.Width;
351 #endif
352 Stopwatch t = new Stopwatch ();
353 t.Start ();
354 try {
355 cache = PlatformCache.Create (new AbortEvent (OnAbort), bRebuildCache);
356 bCachedLoaded = true;
357 } catch (Exception ex) {
358 gLog.Error.WriteLine (ex.ToString ());
359 }
360 t.Stop ();
361
362 if (bCachedLoaded) {
363 gLog.Profiler.WriteLine ("Cache generate/load took: {0}", TimeUtils.getTimeString (t));
364 }
365 }
366 private void Cache_Worker_RunWorkerCompleted (object sender, RunWorkerCompletedEventArgs e)
367 {
368 if (!bCachedLoaded) {
369 gLog.Warn.WriteLine ("Failed to generate cache...");
370 Application.Exit ();
371 return;
372 }
373 #if !DISABLE_SPLASH
374 this.Controls.Remove (splash);
375 #endif
376 config_worker.RunWorkerAsync ();
377 }
378 private void Config_Worker_DoWork (object sender, DoWorkEventArgs e)
379 {
380 Stopwatch t = new Stopwatch ();
381 t.Start ();
382 try {
383 bConfigLoaded = Config.LoadConfig (cache);
384 } catch (Exception ex) {
385 bConfigLoaded = false;
386 gLog.Error.WriteLine (ex.ToString ());
387 return;
388 }
389 t.Stop ();
390 gLog.Profiler.WriteLine ("Config load took: {0}", TimeUtils.getTimeString (t));
391
392
393
394 }
395 private void Config_Worker_RunWorkerCompleted (object sender, RunWorkerCompletedEventArgs e)
396 {
397 if (!bConfigLoaded) {
398 gLog.Warn.WriteLine ("Failed to load config...");
399 Application.Exit ();
400 return;
401 }
402 /* set the container control's cache */
403 platform_flow.setCache (cache);
404 rom_flow.setCache (cache);
405 platform_flow.Visible = true;
406 platform_flow.Focus ();
407 #if !DISABLE_CURSOR_HIDE
408 Cursor.Hide ();
409 #else
410 Cursor.Show();
411 #endif
412
413 #if !DISABLE_PLUGINS
414 PluginLoader.StartInputPolling (bInputQueueDisabled, Handle_InputPoll);
415 #endif
416 }
417 }
418 }