/* * MainForm.cs - Main window of the Level9.Net application. * * Copyright (C) 2004 - 2011 Andreas Scherrer * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This software 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 this software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ /** * \mainpage * \image html level9net.png *
*/ using System; using System.Drawing; using System.IO; using System.Windows.Forms; namespace Level9 { /// /// Main window of the Level9.Net application. /// public partial class MainForm : Form { // -- Constants ------------------------------------------------------ /// /// The command line argument that switches on logging. /// const string COMMAND_LINE_LOGGING = "-logging"; /// /// The text displayed in the window title bar. /// const string TITLE_BAR_TEXT = Config.PROGRAM_NAME + " " + Config.PROGRAM_VERSION; // -- Attributes ----------------------------------------------------- /// /// The 'Load Game' toolbar button. /// private SimpleToolBarButton toolbarButtonLoadGame; /// /// The 'Save Current Position' toolbar button. /// private SimpleToolBarButton toolbarButtonSavePos; /// /// The 'Restore Saved Position' toolbar button. /// private SimpleToolBarButton toolbarButtonRestorePos; /// /// The 'Scrollback' toolbar button. /// private SimpleToolBarButton toolbarButtonScrollback; /// /// The 'Fullscreen' toolbar button. /// private SimpleToolBarButton toolbarButtonFullscreen; /// /// The 'Settings' toolbar button. /// private SimpleToolBarButton toolbarButtonSettings; /// /// The 'Dictionary' toolbar button. /// private SimpleToolBarButton toolbarButtonDictionary; /// /// The 'L9Cut' toolbar button. /// private SimpleToolBarButton toolbarButtonL9Cut; /// /// The 'Manage Scripts' toolbar button. /// private SimpleToolBarButton toolbarButtonScripts; /// /// This property stores the last window size before the fullscreen /// mode starts. /// Size prevSize; /// /// This property stores the instance of a non-modal 'Scripts' form. /// ScriptForm scriptForm = null; /// /// The timer for script playback. /// System.Windows.Forms.Timer scriptTimer = new System.Windows.Forms.Timer(); /// /// The event data of the last InputMode event. /// InputModeEventArgs inputModeArgs = null; /// /// Timestamp of the last InputMode event that ScriptTimerTick() /// processed. /// DateTime scriptInputModeEventTs; // -- Constructors --------------------------------------------------- /// /// Initializes a new instance of the MainForm class. /// /// the program arguments public MainForm(string[] args) { // // The InitializeComponent() call is required for Windows Forms // designer support // InitializeComponent(); // // Event handling // Application.ApplicationExit += new EventHandler(ApplicationExit); Interpreter.NewGameFile += new NewGameFileEventHandler(InterpreterNewGameFile); Interpreter.GameFileError += new GameFileErrorEventHandler(InterpreterGameFileError); Interpreter.OsSaveFile += new OsSaveFileEventHandler(InterpreterOsSaveFile); Interpreter.OsLoadFile += new OsLoadFileEventHandler(InterpreterOsLoadFile); Interpreter.OsGetGameFile += new OsGetGameFileEventHandler(InterpreterOsGetGameFile); gamePanel.InputMode += new InputModeEventHandler(GamePanelInputMode); Script.Instance.ScriptChanged += new ScriptChangedEventHandler(ScriptChanged); // // Set menu icons // menuItemLoadGame.Image = Images.Get(Images.Stock.Open_16x16); menuItemSavePos.Image = Images.Get(Images.Stock.Savepos_16x16); menuItemRestorePos.Image = Images.Get(Images.Stock.Restore_16x16); menuItemExit.Image = Images.Get(Images.Stock.Exit_16x16); menuItemFullscreen.Image = Images.Get(Images.Stock.Fullscreen_16x16); menuItemScrollback.Image = Images.Get(Images.Stock.Scrollback_16x16); menuItemDictionary.Image = Images.Get(Images.Stock.Dictionary_16x16); menuItemL9Cut.Image = Images.Get(Images.Stock.L9cut_16x16); menuItemSettings.Image = Images.Get(Images.Stock.Settings_16x16); menuItemScriptRecording.Image = Images.Get(Images.Stock.Scripts_16x16); menuItemL9netHelp.Image = Images.Get(Images.Stock.Help_16x16); menuItemAbout.Image = Images.Get(Images.Stock.About_16x16); // // Set toolbar icons // toolbarButtonLoadGame = new SimpleToolBarButton( menuItemLoadGame.Image, menuItemLoadGame.Text); toolbarButtonSavePos = new SimpleToolBarButton( menuItemSavePos.Image, menuItemSavePos.Text); toolbarButtonRestorePos = new SimpleToolBarButton( menuItemRestorePos.Image, menuItemRestorePos.Text); toolbarButtonScrollback = new SimpleToolBarButton( menuItemScrollback.Image, menuItemScrollback.Text); toolbarButtonFullscreen = new SimpleToolBarButton( menuItemFullscreen.Image, menuItemFullscreen.Text); toolbarButtonSettings = new SimpleToolBarButton( menuItemSettings.Image, menuItemSettings.Text); toolbarButtonDictionary = new SimpleToolBarButton( menuItemDictionary.Image, menuItemDictionary.Text); toolbarButtonL9Cut = new SimpleToolBarButton( menuItemL9Cut.Image, menuItemL9Cut.Text); toolbarButtonScripts = new SimpleToolBarButton( menuItemScriptRecording.Image, menuItemScriptRecording.Text); // // Add buttons to the toolbar // mainFormToolBar.AddButton(toolbarButtonLoadGame); mainFormToolBar.AddButton(SimpleToolBarButton.Separator); mainFormToolBar.AddButton(toolbarButtonSavePos); mainFormToolBar.AddButton(toolbarButtonRestorePos); mainFormToolBar.AddButton(SimpleToolBarButton.Separator); mainFormToolBar.AddButton(toolbarButtonDictionary); mainFormToolBar.AddButton(toolbarButtonScripts); mainFormToolBar.AddButton(toolbarButtonL9Cut); mainFormToolBar.AddButton(toolbarButtonSettings); mainFormToolBar.AddButton(SimpleToolBarButton.Separator); mainFormToolBar.AddButton(toolbarButtonScrollback); mainFormToolBar.AddButton(toolbarButtonFullscreen); // // Script playback // buttonPlaybackPlay.Image = Images.Get(Images.Stock.Play_16x16); buttonPlaybackStop.Image = Images.Get(Images.Stock.Stop_16x16); int[] inputDelays = Config.Instance.ScriptInputDelays; for (int i = inputDelays.Length - 1; i >= 0; i--) { domainUpDownInputDelay.Items.Add(inputDelays[i]); } domainUpDownInputDelay.SelectedItem = Config.Instance.ScriptInputDelay; // // Configuration settings // gamePanel.ForeColor = Config.Instance.TextColor; gamePanel.BackColor = Config.Instance.BackColor; menuItemToolBar.Checked = Config.Instance.ShowToolbar; menuItemStatusBar.Checked = Config.Instance.ShowStatusBar; menuItemTitleBar.Checked = Config.Instance.ShowTitleBar; menuItemPlayback.Checked = Config.Instance.ShowScriptPlayback; menuItemTimer.Checked = Config.Instance.ShowTimer; mainFormToolBar.Visible = Config.Instance.ShowToolbar; mainFormPlayback.Visible = Config.Instance.ShowScriptPlayback; this.ClientSize = prevSize = Config.Instance.ClientSize.ToSize(); this.Text = TITLE_BAR_TEXT; UpdateRecentFiles(); // // Script timer initialization // scriptTimer.Tick += new EventHandler(ScriptTimerTick); SetScriptTimerInterval(); // // Initialize menu items and toolbar buttons // menuItemReloadCurrentGame.Enabled = false; menuItemSaveScreenshot.Enabled = false; InputModeEventArgs imeArgs = new InputModeEventArgs(false, false); GamePanelInputMode(imeArgs); // // Command line arguments // if (args.Length > 0) { string fileName = null; for (int i = 0; i < args.Length; i++) { if (COMMAND_LINE_LOGGING.Equals(args[i])) { Config.LoggingEnabled = true; } else { fileName = args[i]; } } if (fileName != null && fileName.Length > 0) { LoadGame(args[0]); } } } // -- Event handling ------------------------------------------------- /// /// Invoked when the application exits. /// /// the object that originated the event /// an EventArgs that contains the event data void ApplicationExit(object sender, EventArgs e) { if (GameThread.IsRunning) { GameThread.Stop(); GameThread.Join(); } if (!menuStrip.Visible) { // Fullscreen mode Config.Instance.ClientSize.FromSize(prevSize); } else { Config.Instance.ClientSize.FromSize(this.ClientSize); } Config.Instance.WriteSettings(); } /// /// Invoked when the 'Exit' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemExitClick(object sender, EventArgs e) { Application.Exit(); } /// /// Invoked when the 'Load game...' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemLoadGameClick(object sender, EventArgs e) { string filename = FileUtils.OFDGameFiles(menuItemLoadGame.Text); if (filename != null) { LoadGame(filename); } } /// /// Invoked when the 'About' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemAboutClick(object sender, EventArgs e) { AboutForm about = new AboutForm(); about.ShowDialog(this); } /// /// Invoked when the 'Scrollback...' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemScrollbackClick(object sender, EventArgs e) { gamePanel.ShowScrollback(); } /// /// Invoked when the 'Save current position...' menu item has been /// pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemSavePosClick(object sender, EventArgs e) { Interpreter.AddInputRequest(Interpreter.Commands.Save); gamePanel.SimulateKey('\n'); } /// /// Invoked when the 'Restore saved position...' menu item has been /// pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemRestorePosClick(object sender, EventArgs e) { Interpreter.AddInputRequest(Interpreter.Commands.Restore); SendKeys.Send("\n"); } /// /// Invoked when the 'Toolbar' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemToolBarClick(object sender, EventArgs e) { if (menuItemToolBar.Checked) { mainFormToolBar.Visible = false; menuItemToolBar.Checked = false; Config.Instance.ShowToolbar = false; } else { mainFormToolBar.Visible = true; menuItemToolBar.Checked = true; Config.Instance.ShowToolbar = true; } } /// /// Invoked when the 'Script playback' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemPlaybackClick(object sender, EventArgs e) { if (menuItemPlayback.Checked) { mainFormPlayback.Visible = false; menuItemPlayback.Checked = false; Config.Instance.ShowScriptPlayback = false; } else { mainFormPlayback.Visible = true; menuItemPlayback.Checked = true; Config.Instance.ShowScriptPlayback = true; } } /// /// Invoked when the 'Title bar' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemTitleBarClick(object sender, EventArgs e) { if (menuItemTitleBar.Checked) { menuItemTitleBar.Checked = false; Config.Instance.ShowTitleBar = false; } else { menuItemTitleBar.Checked = true; Config.Instance.ShowTitleBar = true; } Config.Instance.FireConfigChanged(); } /// /// Invoked when the 'Timer' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemTimerClick(object sender, EventArgs e) { if (menuItemTimer.Checked) { menuItemTimer.Checked = false; Config.Instance.ShowTimer = false; } else { menuItemTimer.Checked = true; Config.Instance.ShowTimer = true; } Config.Instance.FireConfigChanged(); } /// /// Invoked when the 'Status bar' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemStatusBarClick(object sender, EventArgs e) { if (menuItemStatusBar.Checked) { menuItemStatusBar.Checked = false; Config.Instance.ShowStatusBar = false; } else { menuItemStatusBar.Checked = true; Config.Instance.ShowStatusBar = true; } Config.Instance.FireConfigChanged(); } /// /// Invoked when the 'L9Cut...' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemL9CutClick(object sender, EventArgs e) { L9CutForm l9Cut = new L9CutForm(); l9Cut.ShowDialog(this); } /// /// Invoked when the 'Dictionary...' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemDictionaryClick(object sender, EventArgs e) { Dictionary.Instance.Show(this); } /// /// Invoked when the 'Fullscreen' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemFullscreenClick(object sender, EventArgs e) { this.SuspendLayout(); if (this.menuStrip.Visible) { if (this.WindowState == FormWindowState.Maximized) { this.WindowState = FormWindowState.Normal; } prevSize = this.Size; gamePanel.BorderStyle = BorderStyle.None; this.FormBorderStyle = FormBorderStyle.None; this.WindowState = FormWindowState.Maximized; mainFormToolBar.Visible = false; menuStrip.Visible = false; this.TopLevel = true; } else { gamePanel.BorderStyle = BorderStyle.Fixed3D; mainFormToolBar.Visible = Config.Instance.ShowToolbar; menuStrip.Visible = true; this.FormBorderStyle = FormBorderStyle.Sizable; this.WindowState = FormWindowState.Normal; this.Size = prevSize; } this.ResumeLayout(); } /// /// Invoked when the 'Settings...' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemSettingsClick(object sender, EventArgs e) { ConfigForm config = new ConfigForm(); config.ShowDialog(this); } /// /// Invoked when the 'Scripts...' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemScriptRecordingClick(object sender, EventArgs e) { if (scriptForm == null || scriptForm.IsDisposed) { scriptForm = new ScriptForm(); } scriptForm.BringToFront(); scriptForm.Show(); } /// /// Invoked when a button has been pressed on the toolbar. /// /// the object that originated the event /// /// a ButtonClickedEventArgs that contains the event data /// void MainFormToolBarButtonClicked(object sender, ToolbarButtonClickedEventArgs e) { if (e.Button == toolbarButtonLoadGame) { MenuItemLoadGameClick(sender, e); } else if (e.Button == toolbarButtonScrollback) { MenuItemScrollbackClick(sender, e); } else if (e.Button == toolbarButtonDictionary) { MenuItemDictionaryClick(sender, e); } else if (e.Button == toolbarButtonSettings) { MenuItemSettingsClick(sender, e); } else if (e.Button == toolbarButtonRestorePos) { MenuItemRestorePosClick(sender, e); } else if (e.Button == toolbarButtonFullscreen) { MenuItemFullscreenClick(sender, e); } else if (e.Button == toolbarButtonSavePos) { MenuItemSavePosClick(sender, e); } else if (e.Button == toolbarButtonL9Cut) { MenuItemL9CutClick(sender, e); } else if (e.Button == toolbarButtonScripts) { MenuItemScriptRecordingClick(sender, e); } } /// /// Invoked when a 'Recent files' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemRecentFileClick(object sender, System.EventArgs e) { ToolStripMenuItem item = (ToolStripMenuItem)sender; LoadGame(item.Text); } /// /// Invoked when the 'Reload current game' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemReloadCurrentGameClick(object sender, EventArgs e) { LoadGame(Interpreter.GameFilePath); } /// /// Invoked when the 'Save screenshot' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemSaveScreenshotClick(object sender, EventArgs e) { gamePanel.SaveScreenshot(); } /// /// Invoked when the 'Level9.Net help' menu item has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void MenuItemL9netHelpClick(object sender, EventArgs e) { try { System.Diagnostics.Process.Start(Config.GetHelpFilePath()); } catch (Exception) { // Do nothing } } /// /// Invoked when a drag-and-drop operation finished within the game /// panel. /// /// the object that originated the event /// a DragEventArgs that contains the event data void GamePanelDragDrop(object sender, DragEventArgs e) { IDataObject data = e.Data; string[] filenames = (string[])e.Data.GetData(DataFormats.FileDrop); if (filenames != null && filenames.Length > 0) { LoadGame(filenames[0]); } } /// /// Invoked when the mouse drags an item into the game panel. /// /// the object that originated the event /// a DragEventArgs that contains the event data void GamePanelDragEnter(object sender, DragEventArgs e) { if( e.Data.GetDataPresent(DataFormats.FileDrop) ) { e.Effect = DragDropEffects.Copy; } else { e.Effect = DragDropEffects.None; } } /// /// Invoked when the dialog form closes. /// /// the object that originated the event /// /// a FormClosedEventArgs that contains the event data /// void MainFormFormClosed(object sender, FormClosedEventArgs e) { Application.Exit(); } /// /// Invoked when the form is activated. Sets the focus for the game /// panel. /// /// the object that originated the event /// an EventArgs that contains the event data void MainFormActivated(object sender, EventArgs e) { gamePanel.Focus(); } /// /// Invoked when the game panel is clicked. Sets the focus for the /// game panel. /// /// the object that originated the event /// an EventArgs that contains the event data void GamePanelClick(object sender, EventArgs e) { gamePanel.Focus(); } /// /// Invoked when the script input delay changes. /// /// the object that originated the event /// an EventArgs that contains the event data void DomainUpDownInputDelaySelectedItemChanged(object sender, EventArgs e) { int inputDelay = (int)domainUpDownInputDelay.SelectedItem; Config.Instance.ScriptInputDelay = inputDelay; SetScriptTimerInterval(); } /// /// Invoked when the 'Play' button for script playback has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void ButtonPlaybackPlayClick(object sender, EventArgs e) { gamePanel.Focus(); Image pauseIcon = Images.Get(Images.Stock.Pause_16x16); Image playIcon = Images.Get(Images.Stock.Play_16x16); if (Script.Instance.IsPlaying) { if (buttonPlaybackPlay.Image.Equals(playIcon)) { buttonPlaybackPlay.Image = pauseIcon; scriptTimer.Start(); } else { textBoxScriptStatus.Text = Script.Instance.PlaybackPos + ": Playback interrupted"; buttonPlaybackPlay.Image = playIcon; scriptTimer.Stop(); } } else { Script.Instance.StartPlayback(); textBoxScriptStatus.Text = "Playback started"; buttonPlaybackPlay.Image = pauseIcon; scriptTimer.Start(); } } /// /// Invoked when the 'Stop' button for script playback has been pressed. /// /// the object that originated the event /// an EventArgs that contains the event data void ButtonPlaybackStopClick(object sender, EventArgs e) { Script.Instance.StopPlayback(); scriptTimer.Stop(); textBoxScriptStatus.Text = "Playback stopped"; gamePanel.Focus(); } /// /// Invoked when the 'Input delay' control is focused. /// /// the object that originated the event /// an EventArgs that contains the event data void DomainUpDownInputDelayEnter(object sender, EventArgs e) { gamePanel.Focus(); } /// /// Invoked when the 'Status' text box is focused. /// /// the object that originated the event /// an EventArgs that contains the event data void TextBoxScriptStatusEnter(object sender, EventArgs e) { gamePanel.Focus(); } /// /// Invoked when a script timer interval has expired. /// /// the object that originated the event /// an EventArgs that contains the event data void ScriptTimerTick(Object sender, EventArgs e) { bool skip = Script.Instance.IsRecording || !GameThread.IsSleeping || (inputModeArgs != null && !inputModeArgs.MoreLines && inputModeArgs.Timestamp.Equals(scriptInputModeEventTs)) || (inputModeArgs != null && !inputModeArgs.Active && !inputModeArgs.MoreLines); if (skip) { return; } scriptInputModeEventTs = inputModeArgs.Timestamp; if (inputModeArgs.MoreLines) { gamePanel.SimulateKey('x'); return; } string input = null; bool pause = false; int nextIndex = Script.Instance.GetNextInput(out input, out pause); if (nextIndex >= 0) { textBoxScriptStatus.Text = nextIndex + ": " + input; gamePanel.SimulateKeys(input + "\n"); if (pause) { ButtonPlaybackPlayClick(buttonPlaybackPlay, null); } } else { textBoxScriptStatus.Text = "Playback stopped"; scriptTimer.Stop(); scriptInputModeEventTs = DateTime.MinValue; } } /// /// Invoked when a Level9.Net script has changed. /// /// /// a ScriptChangedEventArgs that contains the event data /// void ScriptChanged(ScriptChangedEventArgs e) { if (!this.InvokeRequired) { if (inputModeArgs != null && inputModeArgs.Active && Script.Instance.GetEntriesCount() > 0 && !Script.Instance.IsRecording) { buttonPlaybackPlay.Enabled = true; buttonPlaybackStop.Enabled = true; } else { buttonPlaybackPlay.Enabled = false; buttonPlaybackStop.Enabled = false; } buttonPlaybackPlay.Image = Images.Get(Images.Stock.Play_16x16); } else if (!GameThread.StopRequest) { ScriptChangedEventHandler scriptChangedHandler = new ScriptChangedEventHandler(ScriptChanged); this.Invoke(scriptChangedHandler, new object[] { e }); } } /// /// Invoked when the game panel's input mode changes. /// /// an EventArgs that contains the event data void GamePanelInputMode(InputModeEventArgs e) { if (!this.InvokeRequired) { inputModeArgs = e; if (e.Active) { toolbarButtonRestorePos.Enabled = true; toolbarButtonSavePos.Enabled = true; toolbarButtonDictionary.Enabled = true; menuItemRestorePos.Enabled = true; menuItemSavePos.Enabled = true; menuItemDictionary.Enabled = true; if (!Script.Instance.IsRecording && Script.Instance.GetEntriesCount() > 0) { buttonPlaybackPlay.Enabled = true; buttonPlaybackStop.Enabled = true; } } else { toolbarButtonRestorePos.Enabled = false; toolbarButtonSavePos.Enabled = false; toolbarButtonDictionary.Enabled = false; menuItemRestorePos.Enabled = false; menuItemSavePos.Enabled = false; menuItemDictionary.Enabled = false; if (!Script.Instance.IsPlaying) { buttonPlaybackPlay.Enabled = false; buttonPlaybackStop.Enabled = false; } } } else if (!GameThread.StopRequest) { InputModeEventHandler inputModeHandler = new InputModeEventHandler(GamePanelInputMode); this.Invoke(inputModeHandler, new object[] { e }); } } /// /// Invoked when the Level 9 Interpreter requests to save a file. /// /// /// a OsSaveFileEventArgs that contains the event data /// void InterpreterOsSaveFile(OsSaveFileEventArgs e) { if (GameThread.StopRequest) { return; } if (!this.InvokeRequired) { string filename = FileUtils.SFDSavedGameFiles(menuItemSavePos.Text); if (filename != null) { try { FileStream fs = new FileStream(filename, FileMode.OpenOrCreate); BinaryWriter writer = new BinaryWriter(fs); writer.Write(e.Bytes); writer.Close(); fs.Close(); e.Success = true; } catch (Exception ex) { ErrorHandler.Handle(this, "Error writing saved game file.", ex); e.Success = false; } } else { e.Success = false; } } else { OsSaveFileEventHandler osSaveFileHandler = new OsSaveFileEventHandler(InterpreterOsSaveFile); this.Invoke(osSaveFileHandler, new object[] { e }); } } /// /// Invoked when the Level 9 Interpreter requests to load a file. /// /// /// a OsLoadFileEventArgs that contains the event data /// void InterpreterOsLoadFile(OsLoadFileEventArgs e) { if (GameThread.StopRequest) { return; } if (!this.InvokeRequired) { string filename = FileUtils.OFDSavedGameFiles(menuItemRestorePos.Text); if (filename != null) { try { FileStream fs = new FileStream(filename, FileMode.Open); BinaryReader reader = new BinaryReader(fs); e.Bytes = reader.ReadBytes(e.MaxBytes); reader.Close(); fs.Close(); e.Success = true; } catch (Exception ex) { ErrorHandler.Handle(this, "Error loading saved game file.", ex); e.Success = false; } } else { e.Success = false; } } else { OsLoadFileEventHandler osLoadFileHandler = new OsLoadFileEventHandler(InterpreterOsLoadFile); this.Invoke(osLoadFileHandler, new object[] { e }); } } /// /// Invoked when the Level 9 interpreter requests for a game file. /// /// /// a OsGetGameFileEventArgs that contains the event data /// void InterpreterOsGetGameFile(OsGetGameFileEventArgs e) { if (!this.InvokeRequired) { string filename = FileUtils.OFDGameFiles(menuItemLoadGame.Text); if (filename != null) { e.Filename = filename; e.Success = true; } else { e.Success = false; } } else if (!GameThread.StopRequest) { OsGetGameFileEventHandler osGetGameFileHandler = new OsGetGameFileEventHandler(InterpreterOsGetGameFile); this.Invoke(osGetGameFileHandler, new object[] { e }); } } /// /// Invoked when a new game has been loaded. /// /// /// a NewGameFileEventArgs that contains the event data /// void InterpreterNewGameFile(NewGameFileEventArgs e) { if (!this.InvokeRequired) { menuItemReloadCurrentGame.Enabled = true; menuItemSaveScreenshot.Enabled = true; this.Text = TITLE_BAR_TEXT + " - " + Interpreter.GameTitle; } else if (!GameThread.StopRequest) { NewGameFileEventHandler newGameFileHandler = new NewGameFileEventHandler(InterpreterNewGameFile); this.Invoke(newGameFileHandler, new object[] { e }); } } /// /// Invoked when the interpreter detects an error. /// /// /// a GameFileErrorEventArgs that contains the event data /// void InterpreterGameFileError(GameFileErrorEventArgs e) { if (!this.InvokeRequired) { this.Text = TITLE_BAR_TEXT; menuItemReloadCurrentGame.Enabled = false; menuItemSaveScreenshot.Enabled = false; } else if (!GameThread.StopRequest) { GameFileErrorEventHandler gameFileErrorHandler = new GameFileErrorEventHandler(InterpreterGameFileError); this.Invoke(gameFileErrorHandler, new object[] { e }); } } // -- Methods -------------------------------------------------------- void SetScriptTimerInterval() { int interval = 100; if (Config.Instance.ScriptInputDelay != 0) { interval = Config.Instance.ScriptInputDelay * 1000; } scriptTimer.Interval = interval; } /// /// Loads a game file. /// /// the filename of a game file void LoadGame(string filename) { string picname = Path.ChangeExtension(filename, "pic"); if (!File.Exists(picname)) { picname = Path.ChangeExtension(filename, "cga"); } if (!File.Exists(picname)) { picname = Path.ChangeExtension(filename, "hrc"); } if (!File.Exists(picname)) { picname = Path.GetDirectoryName(filename) + "\\picture.dat"; } if (GameThread.IsRunning) { scriptTimer.Stop(); GameThread.Stop(); GameThread.Join(); } if (Interpreter.LoadGame(filename, picname)) { GameThread.Start(); Config.Instance.AddToRecentFiles(filename); UpdateRecentFiles(); } } /// /// Updates the 'recent files' list in the main menu. /// void UpdateRecentFiles() { string[] recent = Config.Instance.RecentFiles; menuItemRecentFiles.DropDownItems.Clear(); for (int i = 0; recent != null && i < recent.Length; i++) { if (recent[i] != null) { ToolStripMenuItem item = new ToolStripMenuItem(recent[i]); item.Click += new System.EventHandler( this.MenuItemRecentFileClick); menuItemRecentFiles.DropDownItems.Add(item); } } } /// /// Level 9 application entry point. /// /// the program arguments [STAThread] public static void Main(string[] args) { bool exit = false; if (!File.Exists(Config.GetLevel9DLLPath())) { ErrorHandler.Handle(typeof(MainForm), "\"" + Config.LEVEL9_DLL + "\" " + "not found in application directory!"); exit = true; } if (!File.Exists(Config.GetAntlrPath())) { ErrorHandler.Handle(typeof(MainForm), "\"" + Config.ANTLR_DLL + "\" " + "not found in application directory!"); exit = true; } if (!Directory.Exists(Config.GetAppDataPath())) { try { Directory.CreateDirectory(Config.GetAppDataPath()); } catch (Exception ex) { ErrorHandler.Handle(typeof(MainForm), "Unable to create application data directory", ex); exit = true; } } if (!exit) { Application.Run(new MainForm(args)); } } } }