/*
* 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));
}
}
}
}