2007-06-13 19:39:38 +00:00
2007-06-14 23:31:57 +00:00
#region = = = = = = = = = = = = = = = = = = Copyright ( c ) 2007 Pascal vd Heiden
2007-06-13 19:39:38 +00:00
/ *
* Copyright ( c ) 2007 Pascal vd Heiden , www . codeimp . com
* This program is released under GNU General Public License
*
* This program 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 .
*
* /
2007-06-14 23:31:57 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Namespaces
2007-06-13 19:39:38 +00:00
using System ;
using System.Collections ;
using System.Collections.Generic ;
using System.Globalization ;
using System.Text ;
using System.Windows.Forms ;
using System.IO ;
using System.Reflection ;
2008-05-29 11:54:45 +00:00
using CodeImp.DoomBuilder.Windows ;
2007-06-13 19:39:38 +00:00
using CodeImp.DoomBuilder.IO ;
2007-06-14 23:31:57 +00:00
using CodeImp.DoomBuilder.Map ;
2007-06-15 22:38:42 +00:00
using CodeImp.DoomBuilder.Geometry ;
2007-06-24 18:56:43 +00:00
using System.Runtime.InteropServices ;
2008-05-29 11:34:01 +00:00
using CodeImp.DoomBuilder.Actions ;
2007-10-04 18:16:05 +00:00
using System.Diagnostics ;
2007-10-20 01:04:47 +00:00
using CodeImp.DoomBuilder.Rendering ;
2007-10-21 18:06:10 +00:00
using CodeImp.DoomBuilder.Config ;
2007-11-04 22:19:30 +00:00
using SlimDX.Direct3D9 ;
using System.Drawing ;
2008-01-02 21:49:43 +00:00
using CodeImp.DoomBuilder.Plugins ;
2008-05-29 16:44:20 +00:00
using CodeImp.DoomBuilder.Types ;
2008-09-07 17:55:20 +00:00
using System.Collections.ObjectModel ;
2008-09-28 21:20:56 +00:00
using System.Threading ;
2008-11-27 11:59:17 +00:00
using CodeImp.DoomBuilder.Editing ;
2007-06-14 23:31:57 +00:00
#endregion
2007-06-13 19:39:38 +00:00
namespace CodeImp.DoomBuilder
{
2007-10-24 17:25:03 +00:00
public static class General
2007-06-13 19:39:38 +00:00
{
2007-06-24 18:56:43 +00:00
#region = = = = = = = = = = = = = = = = = = API Declarations
2008-10-27 08:19:15 +00:00
[DllImport("user32.dll")]
internal static extern bool LockWindowUpdate ( IntPtr hwnd ) ;
2007-06-24 18:56:43 +00:00
2008-10-30 20:13:12 +00:00
[DllImport("kernel32.dll", EntryPoint = "RtlZeroMemory", SetLastError = false)]
2008-01-02 21:49:43 +00:00
internal static extern void ZeroMemory ( IntPtr dest , int size ) ;
2007-09-23 22:01:21 +00:00
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
2009-01-03 19:45:59 +00:00
internal static extern unsafe void CopyMemory ( void * dst , void * src , uint length ) ;
2007-09-23 22:01:21 +00:00
2008-06-02 20:34:52 +00:00
[DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern int SendMessage ( IntPtr hwnd , uint Msg , int wParam , int lParam ) ;
2008-09-07 21:28:20 +00:00
[DllImport("user32.dll", SetLastError = true)]
internal static extern bool MessageBeep ( MessageBeepType type ) ;
2008-10-30 20:13:12 +00:00
[DllImport("kernel32.dll")]
internal extern static IntPtr LoadLibrary ( string filename ) ;
[DllImport("kernel32.dll")]
internal extern static bool FreeLibrary ( IntPtr moduleptr ) ;
[DllImport("user32.dll")]
internal static extern IntPtr CreateWindowEx ( uint exstyle , string classname , string windowname , uint style ,
int x , int y , int width , int height , IntPtr parentptr , int menu ,
IntPtr instanceptr , string param ) ;
[DllImport("user32.dll")]
internal static extern bool DestroyWindow ( IntPtr windowptr ) ;
[DllImport("user32.dll")]
internal static extern int SetWindowPos ( IntPtr windowptr , int insertafterptr , int x , int y , int cx , int cy , int flags ) ;
2008-06-02 20:34:52 +00:00
2007-06-24 18:56:43 +00:00
#endregion
2007-06-13 19:39:38 +00:00
#region = = = = = = = = = = = = = = = = = = Constants
2008-06-02 20:34:52 +00:00
// SendMessage API
2008-10-29 10:56:14 +00:00
internal const int WM_USER = 0x400 ;
2008-06-02 20:34:52 +00:00
internal const int CB_SETITEMHEIGHT = 0x153 ;
2008-10-29 10:56:14 +00:00
internal const int EM_GETSCROLLPOS = WM_USER + 221 ;
internal const int EM_SETSCROLLPOS = WM_USER + 222 ;
2008-06-02 20:34:52 +00:00
2007-06-13 19:39:38 +00:00
// Files and Folders
2007-10-04 18:52:21 +00:00
private const string SETTINGS_FILE = "Builder.cfg" ;
private const string SETTINGS_DIR = "Doom Builder" ;
2007-10-04 18:16:05 +00:00
private const string LOG_FILE = "Builder.log" ;
2007-06-14 14:44:18 +00:00
private const string GAME_CONFIGS_DIR = "Configurations" ;
2007-09-28 08:56:18 +00:00
private const string COMPILERS_DIR = "Compilers" ;
2008-01-02 21:49:43 +00:00
private const string PLUGINS_DIR = "Plugins" ;
2008-10-31 13:47:52 +00:00
private const string SCRIPTS_DIR = "Scripting" ;
2008-05-11 09:17:56 +00:00
private const string SETUP_DIR = "Setup" ;
2008-12-11 10:59:35 +00:00
private const string SPRITES_DIR = "Sprites" ;
2007-06-13 19:39:38 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Variables
// Files and Folders
private static string apppath ;
2008-05-11 09:17:56 +00:00
private static string setuppath ;
2007-10-04 18:52:21 +00:00
private static string settingspath ;
2007-10-04 18:16:05 +00:00
private static string logfile ;
2007-06-13 19:39:38 +00:00
private static string temppath ;
2007-06-14 14:44:18 +00:00
private static string configspath ;
2007-09-28 08:56:18 +00:00
private static string compilerspath ;
2008-10-31 13:47:52 +00:00
private static string scriptspath ;
2008-01-02 21:49:43 +00:00
private static string pluginspath ;
2008-12-11 10:59:35 +00:00
private static string spritespath ;
2007-06-13 19:39:38 +00:00
// Main objects
2007-06-15 18:30:55 +00:00
private static Assembly thisasm ;
2007-06-13 19:39:38 +00:00
private static MainForm mainwindow ;
2007-12-01 01:32:56 +00:00
private static ProgramConfiguration settings ;
2007-06-14 23:31:57 +00:00
private static MapManager map ;
2008-11-27 11:59:17 +00:00
private static EditingManager editing ;
2007-06-24 22:53:41 +00:00
private static ActionManager actions ;
2008-01-02 21:49:43 +00:00
private static PluginManager plugins ;
2007-10-20 01:04:47 +00:00
private static ColorCollection colors ;
2008-05-29 16:44:20 +00:00
private static TypesManager types ;
2007-10-26 18:04:54 +00:00
private static Clock clock ;
2007-06-14 23:31:57 +00:00
2007-06-14 14:44:18 +00:00
// Configurations
2007-06-14 23:31:57 +00:00
private static List < ConfigurationInfo > configs ;
2007-10-13 14:05:45 +00:00
private static List < CompilerInfo > compilers ;
2007-09-28 08:56:18 +00:00
private static List < NodebuilderInfo > nodebuilders ;
2008-10-31 13:47:52 +00:00
private static Dictionary < string , ScriptConfiguration > scriptconfigs ;
2007-06-14 14:44:18 +00:00
2008-01-06 20:56:48 +00:00
// States
private static bool debugbuild ;
2008-11-10 16:11:44 +00:00
2008-09-07 17:55:20 +00:00
// Command line arguments
private static string [ ] cmdargs ;
private static string autoloadfile = null ;
private static string autoloadmap = null ;
private static string autoloadconfig = null ;
2008-10-13 17:47:08 +00:00
private static bool delaymainwindow ;
2008-09-07 17:55:20 +00:00
2007-06-13 19:39:38 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Properties
2008-12-17 19:35:00 +00:00
public static Assembly ThisAssembly { get { return thisasm ; } }
2007-06-13 19:39:38 +00:00
public static string AppPath { get { return apppath ; } }
public static string TempPath { get { return temppath ; } }
2007-06-14 14:44:18 +00:00
public static string ConfigsPath { get { return configspath ; } }
2007-09-28 08:56:18 +00:00
public static string CompilersPath { get { return compilerspath ; } }
2008-01-02 21:49:43 +00:00
public static string PluginsPath { get { return pluginspath ; } }
2008-12-11 10:59:35 +00:00
public static string SpritesPath { get { return spritespath ; } }
2008-09-07 17:55:20 +00:00
public static ICollection < string > CommandArgs { get { return Array . AsReadOnly < string > ( cmdargs ) ; } }
2008-01-02 21:49:43 +00:00
internal static MainForm MainWindow { get { return mainwindow ; } }
public static IMainForm Interface { get { return mainwindow ; } }
2007-12-01 01:32:56 +00:00
public static ProgramConfiguration Settings { get { return settings ; } }
2007-10-20 01:04:47 +00:00
public static ColorCollection Colors { get { return colors ; } }
2008-01-02 21:49:43 +00:00
internal static List < ConfigurationInfo > Configs { get { return configs ; } }
internal static List < NodebuilderInfo > Nodebuilders { get { return nodebuilders ; } }
internal static List < CompilerInfo > Compilers { get { return compilers ; } }
2008-10-31 13:47:52 +00:00
internal static Dictionary < string , ScriptConfiguration > ScriptConfigs { get { return scriptconfigs ; } }
2007-06-14 23:31:57 +00:00
public static MapManager Map { get { return map ; } }
2009-01-05 21:41:32 +00:00
public static ActionManager Actions { get { return actions ; } }
2008-01-02 21:49:43 +00:00
internal static PluginManager Plugins { get { return plugins ; } }
2007-10-26 18:04:54 +00:00
public static Clock Clock { get { return clock ; } }
2008-01-06 20:56:48 +00:00
public static bool DebugBuild { get { return debugbuild ; } }
2008-05-29 16:44:20 +00:00
internal static TypesManager Types { get { return types ; } }
2008-10-13 17:47:08 +00:00
public static string AutoLoadFile { get { return autoloadfile ; } }
public static string AutoLoadMap { get { return autoloadmap ; } }
public static string AutoLoadConfig { get { return autoloadconfig ; } }
public static bool DelayMainWindow { get { return delaymainwindow ; } }
2008-11-27 11:59:17 +00:00
public static EditingManager Editing { get { return editing ; } }
2007-06-14 23:31:57 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Configurations
2007-09-27 22:55:03 +00:00
// This returns the game configuration info by filename
2008-01-02 21:49:43 +00:00
internal static ConfigurationInfo GetConfigurationInfo ( string filename )
2007-09-27 22:55:03 +00:00
{
// Go for all config infos
foreach ( ConfigurationInfo ci in configs )
{
// Check if filename matches
if ( string . Compare ( Path . GetFileNameWithoutExtension ( ci . Filename ) ,
Path . GetFileNameWithoutExtension ( filename ) , true ) = = 0 )
{
// Return this info
return ci ;
}
}
// None found
return null ;
}
2007-06-14 23:31:57 +00:00
// This loads and returns a game configuration
2008-01-02 21:49:43 +00:00
internal static Configuration LoadGameConfiguration ( string filename )
2007-06-14 23:31:57 +00:00
{
Configuration cfg ;
// Make the full filepathname
string filepathname = Path . Combine ( configspath , filename ) ;
// Load configuration
try
{
// Try loading the configuration
cfg = new Configuration ( filepathname , true ) ;
// Check for erors
if ( cfg . ErrorResult ! = 0 )
{
// Error in configuration
2007-10-13 14:05:45 +00:00
ShowErrorMessage ( "Unable to load the game configuration file \"" + filename + "\".\n" +
"Error near line " + cfg . ErrorLine + ": " + cfg . ErrorDescription , MessageBoxButtons . OK ) ;
2007-06-14 23:31:57 +00:00
return null ;
}
2007-09-27 22:55:03 +00:00
// Check if this is a Doom Builder 2 config
2007-06-16 19:53:51 +00:00
else if ( cfg . ReadSetting ( "type" , "" ) ! = "Doom Builder 2 Game Configuration" )
{
// Old configuration
2007-10-13 14:05:45 +00:00
ShowErrorMessage ( "Unable to load the game configuration file \"" + filename + "\".\n" +
"This configuration is not a Doom Builder 2 game configuration." , MessageBoxButtons . OK ) ;
2007-06-16 19:53:51 +00:00
return null ;
}
2007-06-14 23:31:57 +00:00
else
{
2008-05-27 22:02:51 +00:00
// The following code was used to convert the linedef types of DB1 type
// configurations into proper categorized structures for DB2.
// I keep this code here in the repository because if it failed, I might
// need this again to convert from scratch.
/ *
GameConfiguration gcfg = new GameConfiguration ( cfg ) ;
Configuration newcfg = new Configuration ( ) ;
newcfg . NewConfiguration ( true ) ;
bool doommap = ( gcfg . FormatInterface = = "DoomMapSetIO" ) ;
foreach ( LinedefActionInfo a in gcfg . SortedLinedefActions )
{
string catkey = a . Category . ToLowerInvariant ( ) . Trim ( ) ;
string cattitle = a . Category ;
string linekey = a . Index . ToString ( CultureInfo . InvariantCulture ) ;
string linetitle = a . Name ;
string lineprefix = a . Prefix ;
if ( catkey . Length = = 0 ) { catkey = "misc" ; cattitle = "" ; }
if ( cattitle . Length > 0 ) newcfg . WriteSetting ( "linedeftypes." + catkey + ".title" , cattitle ) ;
newcfg . WriteSetting ( "linedeftypes." + catkey + "." + linekey + ".title" , linetitle ) ;
if ( doommap ) newcfg . WriteSetting ( "linedeftypes." + catkey + "." + linekey + ".prefix" , lineprefix ) ;
if ( ! doommap )
{
for ( int i = 0 ; i < 5 ; i + + )
{
if ( a . ArgUsed [ i ] )
{
newcfg . WriteSetting ( "linedeftypes." + catkey + "." + linekey + ".arg" + i . ToString ( CultureInfo . InvariantCulture ) + ".title" , a . ArgTitle [ i ] ) ;
if ( a . ArgTagType [ i ] ! = TagType . None ) newcfg . WriteSetting ( "linedeftypes." + catkey + "." + linekey + ".arg" + i . ToString ( CultureInfo . InvariantCulture ) + ".tag" , ( int ) a . ArgTagType [ i ] ) ;
}
}
}
}
newcfg . SaveConfiguration ( Path . Combine ( configspath , "_" + filename ) ) ;
* /
2007-06-14 23:31:57 +00:00
// Return config
return cfg ;
}
}
catch ( Exception )
{
// Unable to load configuration
2007-10-13 14:05:45 +00:00
ShowErrorMessage ( "Unable to load the game configuration file \"" + filename + "\"." , MessageBoxButtons . OK ) ;
2007-06-14 23:31:57 +00:00
return null ;
}
}
2007-10-13 14:05:45 +00:00
// This loads all game configurations
private static void LoadAllGameConfigurations ( )
2007-06-14 23:31:57 +00:00
{
Configuration cfg ;
string [ ] filenames ;
string name , fullfilename ;
// Display status
mainwindow . DisplayStatus ( "Loading game configurations..." ) ;
2007-06-13 19:39:38 +00:00
2007-06-14 23:31:57 +00:00
// Make array
configs = new List < ConfigurationInfo > ( ) ;
2007-09-28 08:56:18 +00:00
// Go for all cfg files in the configurations directory
2007-06-14 23:31:57 +00:00
filenames = Directory . GetFiles ( configspath , "*.cfg" , SearchOption . TopDirectoryOnly ) ;
foreach ( string filepath in filenames )
{
// Check if it can be loaded
2007-06-16 19:53:51 +00:00
cfg = LoadGameConfiguration ( Path . GetFileName ( filepath ) ) ;
2007-06-14 23:31:57 +00:00
if ( cfg ! = null )
{
fullfilename = Path . GetFileName ( filepath ) ;
2008-05-05 15:16:39 +00:00
ConfigurationInfo cfginfo = new ConfigurationInfo ( cfg , fullfilename ) ;
2007-06-14 23:31:57 +00:00
// Add to lists
2008-05-05 15:16:39 +00:00
General . WriteLogLine ( "Registered game configuration '" + cfginfo . Name + "' from '" + fullfilename + "'" ) ;
configs . Add ( cfginfo ) ;
2007-06-14 23:31:57 +00:00
}
}
2007-10-13 14:05:45 +00:00
// Sort the list
2007-06-14 23:31:57 +00:00
configs . Sort ( ) ;
}
2007-10-13 14:05:45 +00:00
// This loads all nodebuilder configurations
private static void LoadAllNodebuilderConfigurations ( )
2007-09-28 08:56:18 +00:00
{
Configuration cfg ;
2007-10-13 14:05:45 +00:00
IDictionary builderslist ;
2007-09-28 08:56:18 +00:00
string [ ] filenames ;
2007-10-10 09:05:53 +00:00
2007-09-28 08:56:18 +00:00
// Display status
mainwindow . DisplayStatus ( "Loading nodebuilder configurations..." ) ;
// Make array
nodebuilders = new List < NodebuilderInfo > ( ) ;
// Go for all cfg files in the compilers directory
filenames = Directory . GetFiles ( compilerspath , "*.cfg" , SearchOption . TopDirectoryOnly ) ;
foreach ( string filepath in filenames )
{
try
{
// Try loading the configuration
cfg = new Configuration ( filepath , true ) ;
// Check for erors
if ( cfg . ErrorResult ! = 0 )
{
// Error in configuration
2007-10-13 14:05:45 +00:00
ShowErrorMessage ( "Unable to load the compiler configuration file \"" + Path . GetFileName ( filepath ) + "\".\n" +
"Error near line " + cfg . ErrorLine + ": " + cfg . ErrorDescription , MessageBoxButtons . OK ) ;
}
else
{
// Get structures
builderslist = cfg . ReadSetting ( "nodebuilders" , new Hashtable ( ) ) ;
foreach ( DictionaryEntry de in builderslist )
{
// Check if this is a structure
if ( de . Value is IDictionary )
{
try
{
// Make nodebuilder info
nodebuilders . Add ( new NodebuilderInfo ( Path . GetFileName ( filepath ) , de . Key . ToString ( ) , cfg ) ) ;
}
catch ( Exception e )
{
// Unable to load configuration
ShowErrorMessage ( "Unable to load the nodebuilder configuration '" + de . Key . ToString ( ) + "' from \"" + Path . GetFileName ( filepath ) + "\". Error: " + e . Message , MessageBoxButtons . OK ) ;
}
}
}
}
}
catch ( Exception )
{
// Unable to load configuration
ShowErrorMessage ( "Unable to load the compiler configuration file \"" + Path . GetFileName ( filepath ) + "\"." , MessageBoxButtons . OK ) ;
}
}
2007-10-04 18:16:05 +00:00
2007-10-13 14:05:45 +00:00
// Sort the list
nodebuilders . Sort ( ) ;
}
2008-10-31 13:47:52 +00:00
// This loads all script configurations
private static void LoadAllScriptConfigurations ( )
{
Configuration cfg ;
string [ ] filenames ;
// Display status
mainwindow . DisplayStatus ( "Loading script configurations..." ) ;
// Make collection
scriptconfigs = new Dictionary < string , ScriptConfiguration > ( ) ;
// Go for all cfg files in the scripts directory
filenames = Directory . GetFiles ( scriptspath , "*.cfg" , SearchOption . TopDirectoryOnly ) ;
foreach ( string filepath in filenames )
{
try
{
// Try loading the configuration
cfg = new Configuration ( filepath , true ) ;
// Check for erors
if ( cfg . ErrorResult ! = 0 )
{
// Error in configuration
ShowErrorMessage ( "Unable to load the script configuration file \"" + Path . GetFileName ( filepath ) + "\".\n" +
"Error near line " + cfg . ErrorLine + ": " + cfg . ErrorDescription , MessageBoxButtons . OK ) ;
}
else
{
try
{
// Make script configuration
ScriptConfiguration scfg = new ScriptConfiguration ( cfg ) ;
string filename = Path . GetFileName ( filepath ) ;
2008-11-02 22:07:20 +00:00
scriptconfigs . Add ( filename . ToLowerInvariant ( ) , scfg ) ;
2008-10-31 13:47:52 +00:00
}
catch ( Exception e )
{
// Unable to load configuration
ShowErrorMessage ( "Unable to load the script configuration \"" + Path . GetFileName ( filepath ) + "\". Error: " + e . Message , MessageBoxButtons . OK ) ;
}
}
}
2008-11-03 16:11:00 +00:00
catch ( Exception e )
2008-10-31 13:47:52 +00:00
{
// Unable to load configuration
2008-11-03 16:11:00 +00:00
ShowErrorMessage ( "Unable to load the script configuration file \"" + Path . GetFileName ( filepath ) + "\". Error: " + e . Message , MessageBoxButtons . OK ) ;
2008-10-31 13:47:52 +00:00
}
}
}
2007-10-13 14:05:45 +00:00
// This loads all compiler configurations
private static void LoadAllCompilerConfigurations ( )
{
Configuration cfg ;
IDictionary compilerslist ;
string [ ] filenames ;
// Display status
mainwindow . DisplayStatus ( "Loading compiler configurations..." ) ;
// Make array
compilers = new List < CompilerInfo > ( ) ;
// Go for all cfg files in the compilers directory
filenames = Directory . GetFiles ( compilerspath , "*.cfg" , SearchOption . TopDirectoryOnly ) ;
foreach ( string filepath in filenames )
{
try
{
// Try loading the configuration
cfg = new Configuration ( filepath , true ) ;
// Check for erors
if ( cfg . ErrorResult ! = 0 )
{
// Error in configuration
ShowErrorMessage ( "Unable to load the compiler configuration file \"" + Path . GetFileName ( filepath ) + "\".\n" +
"Error near line " + cfg . ErrorLine + ": " + cfg . ErrorDescription , MessageBoxButtons . OK ) ;
2007-09-28 08:56:18 +00:00
}
else
{
2007-10-10 09:05:53 +00:00
// Get structures
2007-10-13 14:05:45 +00:00
compilerslist = cfg . ReadSetting ( "compilers" , new Hashtable ( ) ) ;
foreach ( DictionaryEntry de in compilerslist )
2007-10-10 09:05:53 +00:00
{
// Check if this is a structure
if ( de . Value is IDictionary )
{
2007-10-13 14:05:45 +00:00
// Make compiler info
compilers . Add ( new CompilerInfo ( Path . GetFileName ( filepath ) , de . Key . ToString ( ) , cfg ) ) ;
2007-10-10 09:05:53 +00:00
}
}
2007-09-28 08:56:18 +00:00
}
}
catch ( Exception )
{
// Unable to load configuration
2007-10-13 14:05:45 +00:00
ShowErrorMessage ( "Unable to load the compiler configuration file \"" + Path . GetFileName ( filepath ) + "\"." , MessageBoxButtons . OK ) ;
2007-09-28 08:56:18 +00:00
}
}
2007-10-13 14:05:45 +00:00
}
// This returns a nodebuilder by name
2008-01-02 21:49:43 +00:00
internal static NodebuilderInfo GetNodebuilderByName ( string name )
2007-10-13 14:05:45 +00:00
{
// Go for all nodebuilders
foreach ( NodebuilderInfo n in nodebuilders )
{
// Name matches?
if ( n . Name = = name ) return n ;
}
2007-09-28 08:56:18 +00:00
2007-10-13 14:05:45 +00:00
// Cannot find that nodebuilder
return null ;
2007-09-28 08:56:18 +00:00
}
2007-06-13 19:39:38 +00:00
#endregion
2007-06-14 14:44:18 +00:00
#region = = = = = = = = = = = = = = = = = = Startup
2007-06-13 19:39:38 +00:00
// Main program entry
2007-06-15 10:18:03 +00:00
[STAThread]
2008-01-02 21:49:43 +00:00
internal static void Main ( string [ ] args )
2007-06-13 19:39:38 +00:00
{
2007-06-15 18:30:55 +00:00
Uri localpath ;
2007-10-04 18:16:05 +00:00
Version thisversion ;
2008-09-07 17:55:20 +00:00
2008-01-06 20:56:48 +00:00
// Determine states
#if DEBUG
debugbuild = true ;
#else
debugbuild = false ;
#endif
2007-11-04 22:19:30 +00:00
// Enable OS visual styles
Application . EnableVisualStyles ( ) ;
Application . DoEvents ( ) ; // This must be here to work around a .NET bug
2008-05-11 00:42:34 +00:00
// Hook to DLL loading failure event
AppDomain . CurrentDomain . AssemblyResolve + = new ResolveEventHandler ( CurrentDomain_AssemblyResolve ) ;
2007-06-15 18:30:55 +00:00
2008-09-28 21:20:56 +00:00
// Set current thread name
Thread . CurrentThread . Name = "Main Application" ;
2007-06-15 18:30:55 +00:00
// Get a reference to this assembly
thisasm = Assembly . GetExecutingAssembly ( ) ;
2007-10-04 18:16:05 +00:00
thisversion = thisasm . GetName ( ) . Version ;
2007-06-15 18:30:55 +00:00
2007-06-13 19:39:38 +00:00
// Find application path
2007-06-15 18:30:55 +00:00
localpath = new Uri ( Path . GetDirectoryName ( thisasm . GetName ( ) . CodeBase ) ) ;
2007-06-13 19:39:38 +00:00
apppath = Uri . UnescapeDataString ( localpath . AbsolutePath ) ;
2007-10-04 18:16:05 +00:00
2007-09-28 08:56:18 +00:00
// Setup directories
2007-06-13 19:39:38 +00:00
temppath = Path . GetTempPath ( ) ;
2008-05-11 09:17:56 +00:00
setuppath = Path . Combine ( apppath , SETUP_DIR ) ;
2007-10-04 18:52:21 +00:00
settingspath = Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) , SETTINGS_DIR ) ;
2007-06-14 14:44:18 +00:00
configspath = Path . Combine ( apppath , GAME_CONFIGS_DIR ) ;
2007-09-28 08:56:18 +00:00
compilerspath = Path . Combine ( apppath , COMPILERS_DIR ) ;
2008-01-02 21:49:43 +00:00
pluginspath = Path . Combine ( apppath , PLUGINS_DIR ) ;
2008-10-31 13:47:52 +00:00
scriptspath = Path . Combine ( apppath , SCRIPTS_DIR ) ;
2008-12-11 10:59:35 +00:00
spritespath = Path . Combine ( apppath , SPRITES_DIR ) ;
2007-10-05 07:19:57 +00:00
logfile = Path . Combine ( settingspath , LOG_FILE ) ;
2007-10-05 08:00:29 +00:00
// Make program settings directory if missing
if ( ! Directory . Exists ( settingspath ) ) Directory . CreateDirectory ( settingspath ) ;
2007-10-04 18:16:05 +00:00
// Remove the previous log file and start logging
2007-10-05 08:00:29 +00:00
if ( File . Exists ( logfile ) ) File . Delete ( logfile ) ;
2007-10-04 18:16:05 +00:00
General . WriteLogLine ( "Doom Builder " + thisversion . Major + "." + thisversion . Minor + " startup" ) ;
2008-09-07 17:55:20 +00:00
General . WriteLogLine ( "Application path: " + apppath ) ;
General . WriteLogLine ( "Temporary path: " + temppath ) ;
General . WriteLogLine ( "Local settings path: " + settingspath ) ;
General . WriteLogLine ( "Command-line arguments: " + args . Length ) ;
for ( int i = 0 ; i < args . Length ; i + + )
General . WriteLogLine ( "Argument " + i + ": \"" + args [ i ] + "\"" ) ;
// Parse command-line arguments
ParseCommandLineArgs ( args ) ;
2007-06-14 14:44:18 +00:00
2007-06-13 19:39:38 +00:00
// Load configuration
2007-10-04 18:16:05 +00:00
General . WriteLogLine ( "Loading program configuration..." ) ;
2007-12-01 01:32:56 +00:00
settings = new ProgramConfiguration ( ) ;
if ( settings . Load ( Path . Combine ( settingspath , SETTINGS_FILE ) ,
Path . Combine ( apppath , SETTINGS_FILE ) ) )
2007-10-04 18:52:21 +00:00
{
// Create action manager
actions = new ActionManager ( ) ;
2008-01-13 21:23:59 +00:00
2007-10-04 18:52:21 +00:00
// Bind static methods to actions
2008-04-27 12:07:26 +00:00
General . Actions . BindMethods ( typeof ( General ) ) ;
2007-10-04 18:52:21 +00:00
2008-09-17 19:21:45 +00:00
// Initialize static classes
MapSet . Initialize ( ) ;
2007-10-04 18:52:21 +00:00
// Create main window
General . WriteLogLine ( "Loading main interface window..." ) ;
mainwindow = new MainForm ( ) ;
2007-10-14 21:31:45 +00:00
mainwindow . UpdateInterface ( ) ;
2007-10-04 18:52:21 +00:00
2008-10-13 17:47:08 +00:00
if ( ! delaymainwindow )
{
// Show main window
General . WriteLogLine ( "Showing main interface window..." ) ;
mainwindow . Show ( ) ;
mainwindow . Update ( ) ;
}
2007-11-04 22:19:30 +00:00
// Start Direct3D
General . WriteLogLine ( "Starting Direct3D graphics driver..." ) ;
2008-09-13 13:24:06 +00:00
try { D3DDevice . Startup ( ) ; }
2008-05-11 00:42:34 +00:00
catch ( Direct3D9NotFoundException ) { AskDownloadDirectX ( ) ; return ; }
catch ( Direct3DX9NotFoundException ) { AskDownloadDirectX ( ) ; return ; }
2008-11-10 16:11:44 +00:00
2008-01-02 21:49:43 +00:00
// Load plugin manager
General . WriteLogLine ( "Loading plugins..." ) ;
plugins = new PluginManager ( ) ;
2008-05-16 20:00:49 +00:00
plugins . LoadAllPlugins ( ) ;
2008-11-10 16:11:44 +00:00
2008-11-27 19:25:13 +00:00
// Load game configurations
General . WriteLogLine ( "Loading game configurations..." ) ;
LoadAllGameConfigurations ( ) ;
// Create editing modes
General . WriteLogLine ( "Creating editing modes manager..." ) ;
editing = new EditingManager ( ) ;
2008-10-09 05:49:46 +00:00
// Now that all settings have been combined (core & plugins) apply the defaults
General . WriteLogLine ( "Applying configuration settings..." ) ;
actions . ApplyDefaultShortcutKeys ( ) ;
2008-11-10 16:11:44 +00:00
mainwindow . ApplyShortcutKeys ( ) ;
2008-11-27 19:25:13 +00:00
foreach ( ConfigurationInfo info in configs ) info . ApplyDefaults ( null ) ;
2008-01-02 21:49:43 +00:00
2007-10-13 14:05:45 +00:00
// Load compiler configurations
General . WriteLogLine ( "Loading compiler configurations..." ) ;
LoadAllCompilerConfigurations ( ) ;
2007-10-04 18:52:21 +00:00
// Load nodebuilder configurations
General . WriteLogLine ( "Loading nodebuilder configurations..." ) ;
2007-10-13 14:05:45 +00:00
LoadAllNodebuilderConfigurations ( ) ;
2008-10-31 13:47:52 +00:00
// Load script configurations
General . WriteLogLine ( "Loading script configurations..." ) ;
LoadAllScriptConfigurations ( ) ;
2007-10-20 01:04:47 +00:00
// Load color settings
General . WriteLogLine ( "Loading color settings..." ) ;
2007-12-01 01:32:56 +00:00
colors = new ColorCollection ( settings . Config ) ;
2008-11-27 11:59:17 +00:00
2007-10-26 18:04:54 +00:00
// Create application clock
General . WriteLogLine ( "Creating application clock..." ) ;
clock = new Clock ( ) ;
2008-05-29 16:44:20 +00:00
// Create types manager
General . WriteLogLine ( "Creating types manager..." ) ;
types = new TypesManager ( ) ;
2008-10-13 17:47:08 +00:00
// Do auto map loading when window is delayed
if ( delaymainwindow )
mainwindow . PerformAutoMapLoading ( ) ;
2007-10-04 18:52:21 +00:00
// Run application from the main window
General . WriteLogLine ( "Startup done" ) ;
mainwindow . DisplayReady ( ) ;
Application . Run ( mainwindow ) ;
}
else
{
// Terminate
Terminate ( false ) ;
}
}
2008-05-11 00:42:34 +00:00
// This handles DLL linking errors
private static System . Reflection . Assembly CurrentDomain_AssemblyResolve ( object sender , ResolveEventArgs args )
{
// Check if SlimDX failed loading
if ( args . Name . Contains ( "SlimDX" ) ) AskDownloadDirectX ( ) ;
// Return null
return null ;
}
// This asks the user to download DirectX
private static void AskDownloadDirectX ( )
{
2008-09-13 13:24:06 +00:00
// Cancel loading map from command-line parameters, if any.
// This causes problems, because when the window is shown, the map will
// be loaded and DirectX is initialized (which we seem to be missing)
2008-12-27 00:22:31 +00:00
CancelAutoMapLoad ( ) ;
2008-09-13 13:24:06 +00:00
2008-05-11 00:42:34 +00:00
// Ask the user to download DirectX
if ( MessageBox . Show ( "This application requires the latest version of Microsoft DirectX installed on your computer." + Environment . NewLine +
2008-09-13 13:27:20 +00:00
"Do you want to install and/or update Microsoft DirectX now?" , "DirectX Error" , System . Windows . Forms . MessageBoxButtons . YesNo ,
2008-05-11 00:42:34 +00:00
System . Windows . Forms . MessageBoxIcon . Exclamation ) = = System . Windows . Forms . DialogResult . Yes )
{
// Open DX web setup
//System.Diagnostics.Process.Start("http://www.microsoft.com/downloads/details.aspx?FamilyId=2DA43D38-DB71-4C1B-BC6A-9B6652CD92A3").WaitForExit(1000);
2008-05-11 09:17:56 +00:00
System . Diagnostics . Process . Start ( Path . Combine ( setuppath , "dxwebsetup.exe" ) ) . WaitForExit ( 1000 ) ;
2008-05-11 00:42:34 +00:00
}
// End program here
Terminate ( false ) ;
}
2008-09-07 17:55:20 +00:00
// This parses the command line arguments
private static void ParseCommandLineArgs ( string [ ] args )
{
// Keep a copy
cmdargs = args ;
// Make a queue so we can parse the values from left to right
Queue < string > argslist = new Queue < string > ( args ) ;
// Parse list
while ( argslist . Count > 0 )
{
// Get next arg
string curarg = argslist . Dequeue ( ) ;
2008-10-13 17:47:08 +00:00
// Delay window?
if ( string . Compare ( curarg , "-DELAYWINDOW" , true ) = = 0 )
{
// Delay showing the main window
delaymainwindow = true ;
}
2008-09-07 17:55:20 +00:00
// Map name info?
2008-10-13 17:47:08 +00:00
else if ( string . Compare ( curarg , "-MAP" , true ) = = 0 )
2008-09-07 17:55:20 +00:00
{
// Store next arg as map name information
autoloadmap = argslist . Dequeue ( ) ;
}
// Config name info?
else if ( ( string . Compare ( curarg , "-CFG" , true ) = = 0 ) | |
( string . Compare ( curarg , "-CONFIG" , true ) = = 0 ) )
{
// Store next arg as config filename information
autoloadconfig = argslist . Dequeue ( ) ;
}
// Every other arg
else
{
// No command to load file yet?
if ( autoloadfile = = null )
{
// Check if this is a file we can load
if ( File . Exists ( curarg ) )
{
// Load this file!
autoloadfile = curarg . Trim ( ) ;
}
else
{
// Note in the log that we cannot find this file
General . WriteLogLine ( "WARNING: Cannot find the specified file \"" + curarg + "\"" ) ;
}
}
}
}
}
2007-10-04 18:52:21 +00:00
2008-12-27 00:22:31 +00:00
// This cancels automatic map loading
internal static void CancelAutoMapLoad ( )
{
autoloadfile = null ;
}
2007-06-13 19:39:38 +00:00
#endregion
2007-06-14 15:35:37 +00:00
#region = = = = = = = = = = = = = = = = = = Terminate
2008-10-13 17:47:08 +00:00
// This is for plugins to use
public static void Exit ( bool properexit )
{
// Plugin wants to exit nicely?
if ( properexit )
{
// Close dialog forms first
while ( ( Form . ActiveForm ! = mainwindow ) & & ( Form . ActiveForm ! = null ) )
Form . ActiveForm . Close ( ) ;
// Close main window
mainwindow . Close ( ) ;
}
else
{
// Terminate, no questions asked
Terminate ( true ) ;
}
}
2007-06-14 15:35:37 +00:00
// This terminates the program
2008-01-02 21:49:43 +00:00
internal static void Terminate ( bool properexit )
2007-06-14 15:35:37 +00:00
{
2007-10-04 18:52:21 +00:00
// Terminate properly?
if ( properexit )
{
General . WriteLogLine ( "Termination requested" ) ;
2008-11-10 16:11:44 +00:00
2007-10-04 18:52:21 +00:00
// Unbind static methods from actions
2008-04-27 12:07:26 +00:00
General . Actions . UnbindMethods ( typeof ( General ) ) ;
2007-10-13 14:05:45 +00:00
2007-10-20 01:04:47 +00:00
// Save colors
2007-12-01 01:32:56 +00:00
colors . SaveColors ( settings . Config ) ;
2007-10-20 01:04:47 +00:00
2007-10-04 18:52:21 +00:00
// Save action controls
actions . SaveSettings ( ) ;
2008-11-10 16:11:44 +00:00
2007-10-04 18:52:21 +00:00
// Save game configuration settings
foreach ( ConfigurationInfo ci in configs ) ci . SaveSettings ( ) ;
2008-11-10 16:11:44 +00:00
2007-10-04 18:52:21 +00:00
// Save settings configuration
General . WriteLogLine ( "Saving program configuration..." ) ;
2007-12-01 01:32:56 +00:00
settings . Save ( Path . Combine ( settingspath , SETTINGS_FILE ) ) ;
2008-11-10 16:11:44 +00:00
2008-05-11 00:42:34 +00:00
// Clean up
if ( map ! = null ) map . Dispose ( ) ; map = null ;
2008-11-27 11:59:17 +00:00
if ( editing ! = null ) editing . Dispose ( ) ; editing = null ;
2008-05-11 00:42:34 +00:00
if ( mainwindow ! = null ) mainwindow . Dispose ( ) ;
if ( actions ! = null ) actions . Dispose ( ) ;
if ( clock ! = null ) clock . Dispose ( ) ;
if ( plugins ! = null ) plugins . Dispose ( ) ;
2008-05-29 16:44:20 +00:00
if ( types ! = null ) types . Dispose ( ) ;
2008-09-13 13:24:06 +00:00
try { D3DDevice . Terminate ( ) ; } catch ( Exception ) { }
2008-05-11 00:42:34 +00:00
2007-10-04 18:52:21 +00:00
// Application ends here and now
General . WriteLogLine ( "Termination done" ) ;
Application . Exit ( ) ;
}
else
{
// Just end now
General . WriteLogLine ( "Immediate program termination" ) ;
Application . Exit ( ) ;
}
2008-10-13 17:47:08 +00:00
// Die.
Process . GetCurrentProcess ( ) . Kill ( ) ;
2007-06-14 15:35:37 +00:00
}
#endregion
2007-06-14 23:31:57 +00:00
#region = = = = = = = = = = = = = = = = = = Management
2008-09-23 10:04:10 +00:00
// This cancels a volatile mode, as if the user presses cancel
public static bool CancelVolatileMode ( )
2008-05-08 16:39:14 +00:00
{
2008-09-13 13:24:06 +00:00
// Volatile mode?
2008-11-27 11:59:17 +00:00
if ( ( map ! = null ) & ( editing . Mode ! = null ) & & editing . Mode . Attributes . Volatile )
2008-09-13 13:24:06 +00:00
{
// Cancel
2008-11-27 11:59:17 +00:00
editing . Mode . OnCancel ( ) ;
2008-09-13 13:24:06 +00:00
return true ;
}
else
{
// Mode is not volatile
return false ;
}
2008-05-08 16:39:14 +00:00
}
2008-09-23 10:04:10 +00:00
// This disengages a volatile mode, leaving the choice to cancel or accept to the editing mode
public static bool DisengageVolatileMode ( )
{
// Volatile mode?
2008-11-27 11:59:17 +00:00
if ( ( map ! = null ) & & ( editing . Mode ! = null ) & & editing . Mode . Attributes . Volatile )
2008-09-23 10:04:10 +00:00
{
// Change back to normal mode
2008-11-27 11:59:17 +00:00
editing . ChangeMode ( editing . PreviousStableMode . Name ) ;
2008-09-23 10:04:10 +00:00
return true ;
}
else
{
// Mode is not volatile
return false ;
}
}
2007-06-14 23:31:57 +00:00
// This creates a new map
2008-04-27 12:07:26 +00:00
[BeginAction("newmap")]
2008-01-02 21:49:43 +00:00
internal static void NewMap ( )
2007-06-14 23:31:57 +00:00
{
2007-06-25 14:42:23 +00:00
MapOptions newoptions = new MapOptions ( ) ;
2007-06-14 23:31:57 +00:00
MapOptionsForm optionswindow ;
2008-11-10 16:11:44 +00:00
2008-05-08 16:39:14 +00:00
// Cancel volatile mode, if any
2008-09-23 10:04:10 +00:00
General . DisengageVolatileMode ( ) ;
2008-11-10 16:11:44 +00:00
2007-06-25 14:42:23 +00:00
// Ask the user to save changes (if any)
if ( General . AskSaveMap ( ) )
2007-06-16 19:53:51 +00:00
{
// Open map options dialog
2007-06-25 14:42:23 +00:00
optionswindow = new MapOptionsForm ( newoptions ) ;
2008-10-21 05:41:47 +00:00
optionswindow . IsForNewMap = true ;
2007-06-25 14:42:23 +00:00
if ( optionswindow . ShowDialog ( mainwindow ) = = DialogResult . OK )
2007-06-14 23:31:57 +00:00
{
2007-06-15 10:18:03 +00:00
// Display status
2007-06-25 14:42:23 +00:00
mainwindow . DisplayStatus ( "Creating new map..." ) ;
2007-10-14 18:11:03 +00:00
Cursor . Current = Cursors . WaitCursor ;
2008-11-10 16:11:44 +00:00
2008-10-13 17:47:08 +00:00
// Let the plugins know
plugins . OnMapNewBegin ( ) ;
2008-11-10 16:11:44 +00:00
2007-06-15 10:18:03 +00:00
// Clear the display
mainwindow . ClearDisplay ( ) ;
2007-06-16 19:53:51 +00:00
2007-06-15 10:18:03 +00:00
// Trash the current map, if any
if ( map ! = null ) map . Dispose ( ) ;
// Create map manager with given options
2007-06-15 18:30:55 +00:00
map = new MapManager ( ) ;
2007-06-25 14:42:23 +00:00
if ( map . InitializeNewMap ( newoptions ) )
{
// Done
}
else
2007-06-15 18:30:55 +00:00
{
// Unable to create map manager
map . Dispose ( ) ;
map = null ;
// Show splash logo on display
mainwindow . ShowSplashDisplay ( ) ;
}
2007-10-14 18:11:03 +00:00
2008-10-13 17:47:08 +00:00
// Let the plugins know
plugins . OnMapNewEnd ( ) ;
2007-10-14 18:11:03 +00:00
// All done
2008-04-20 23:22:16 +00:00
mainwindow . RedrawDisplay ( ) ;
2007-10-14 21:31:45 +00:00
mainwindow . UpdateInterface ( ) ;
2008-06-11 05:02:48 +00:00
mainwindow . HideInfo ( ) ;
2007-10-14 18:11:03 +00:00
mainwindow . DisplayReady ( ) ;
Cursor . Current = Cursors . Default ;
2007-06-14 23:31:57 +00:00
}
2007-06-15 10:18:03 +00:00
}
2007-06-25 14:42:23 +00:00
}
2007-06-16 19:53:51 +00:00
2007-06-25 14:42:23 +00:00
// This closes the current map
2008-04-27 12:07:26 +00:00
[BeginAction("closemap")]
2008-05-19 21:33:07 +00:00
internal static void ActionCloseMap ( ) { CloseMap ( ) ; }
internal static bool CloseMap ( )
2007-06-25 14:42:23 +00:00
{
2008-05-08 16:39:14 +00:00
// Cancel volatile mode, if any
2008-09-23 10:04:10 +00:00
General . DisengageVolatileMode ( ) ;
2008-05-08 16:39:14 +00:00
2007-06-25 14:42:23 +00:00
// Ask the user to save changes (if any)
if ( General . AskSaveMap ( ) )
{
// Display status
mainwindow . DisplayStatus ( "Closing map..." ) ;
2007-10-05 10:00:15 +00:00
General . WriteLogLine ( "Unloading map..." ) ;
2007-10-14 18:11:03 +00:00
Cursor . Current = Cursors . WaitCursor ;
2008-11-27 13:42:18 +00:00
2007-06-25 14:42:23 +00:00
// Trash the current map
if ( map ! = null ) map . Dispose ( ) ;
map = null ;
2008-11-27 13:42:18 +00:00
2007-06-25 14:42:23 +00:00
// Show splash logo on display
mainwindow . ShowSplashDisplay ( ) ;
2008-11-27 13:42:18 +00:00
2007-06-25 14:42:23 +00:00
// Done
2007-10-14 18:11:03 +00:00
Cursor . Current = Cursors . Default ;
2008-11-27 13:42:18 +00:00
editing . UpdateCurrentEditModes ( ) ;
2008-04-20 23:22:16 +00:00
mainwindow . RedrawDisplay ( ) ;
2008-06-11 05:02:48 +00:00
mainwindow . HideInfo ( ) ;
2007-10-14 21:31:45 +00:00
mainwindow . UpdateInterface ( ) ;
2007-06-25 14:42:23 +00:00
mainwindow . DisplayReady ( ) ;
2007-10-05 10:00:15 +00:00
General . WriteLogLine ( "Map unload done" ) ;
2008-05-19 21:33:07 +00:00
return true ;
}
else
{
// User cancelled
return false ;
2007-06-25 14:42:23 +00:00
}
}
// This loads a map from file
2008-04-27 12:07:26 +00:00
[BeginAction("openmap")]
2008-01-02 21:49:43 +00:00
internal static void OpenMap ( )
2007-06-25 14:42:23 +00:00
{
OpenFileDialog openfile ;
2008-05-08 16:39:14 +00:00
// Cancel volatile mode, if any
2008-09-23 10:04:10 +00:00
General . DisengageVolatileMode ( ) ;
2008-05-08 16:39:14 +00:00
2007-10-10 15:54:42 +00:00
// Open map file dialog
openfile = new OpenFileDialog ( ) ;
openfile . Filter = "Doom WAD Files (*.wad)|*.wad" ;
openfile . Title = "Open Map" ;
2007-10-14 15:44:55 +00:00
openfile . AddExtension = false ;
openfile . CheckFileExists = true ;
openfile . Multiselect = false ;
openfile . ValidateNames = true ;
2007-10-10 15:54:42 +00:00
if ( openfile . ShowDialog ( mainwindow ) = = DialogResult . OK )
{
// Update main window
mainwindow . Update ( ) ;
// Open map file
OpenMapFile ( openfile . FileName ) ;
}
}
// This opens the specified file
2008-01-02 21:49:43 +00:00
internal static void OpenMapFile ( string filename )
2007-10-10 15:54:42 +00:00
{
OpenMapOptionsForm openmapwindow ;
2008-05-08 16:39:14 +00:00
// Cancel volatile mode, if any
2008-09-23 10:04:10 +00:00
General . DisengageVolatileMode ( ) ;
2008-05-08 16:39:14 +00:00
2007-06-25 14:42:23 +00:00
// Ask the user to save changes (if any)
if ( General . AskSaveMap ( ) )
{
2007-10-10 15:54:42 +00:00
// Open map options dialog
openmapwindow = new OpenMapOptionsForm ( filename ) ;
if ( openmapwindow . ShowDialog ( mainwindow ) = = DialogResult . OK )
2008-09-07 17:55:20 +00:00
OpenMapFileWithOptions ( filename , openmapwindow . Options ) ;
}
}
// This opens the specified file without dialog
internal static void OpenMapFileWithOptions ( string filename , MapOptions options )
{
// Display status
mainwindow . DisplayStatus ( "Opening map file..." ) ;
Cursor . Current = Cursors . WaitCursor ;
2007-06-25 14:42:23 +00:00
2008-10-13 17:47:08 +00:00
// Let the plugins know
plugins . OnMapOpenBegin ( ) ;
2008-09-07 17:55:20 +00:00
// Clear the display
mainwindow . ClearDisplay ( ) ;
2007-06-25 14:42:23 +00:00
2008-09-07 17:55:20 +00:00
// Trash the current map, if any
if ( map ! = null ) map . Dispose ( ) ;
2007-06-25 14:42:23 +00:00
2008-09-07 17:55:20 +00:00
// Create map manager with given options
map = new MapManager ( ) ;
if ( map . InitializeOpenMap ( filename , options ) )
{
// Add recent file
mainwindow . AddRecentFile ( filename ) ;
}
else
{
// Unable to create map manager
map . Dispose ( ) ;
map = null ;
2007-10-14 18:11:03 +00:00
2008-09-07 17:55:20 +00:00
// Show splash logo on display
mainwindow . ShowSplashDisplay ( ) ;
2007-06-25 14:42:23 +00:00
}
2008-09-07 17:55:20 +00:00
2008-10-13 17:47:08 +00:00
// Let the plugins know
plugins . OnMapOpenEnd ( ) ;
2008-09-07 17:55:20 +00:00
// All done
mainwindow . RedrawDisplay ( ) ;
mainwindow . UpdateInterface ( ) ;
mainwindow . HideInfo ( ) ;
mainwindow . DisplayReady ( ) ;
Cursor . Current = Cursors . Default ;
2007-06-15 10:18:03 +00:00
}
2007-10-13 14:05:45 +00:00
// This saves the current map
2008-05-08 16:39:14 +00:00
// Returns tre when saved, false when cancelled or failed
2008-04-27 12:07:26 +00:00
[BeginAction("savemap")]
2008-05-08 16:39:14 +00:00
internal static void ActionSaveMap ( ) { SaveMap ( ) ; }
internal static bool SaveMap ( )
2007-10-13 14:05:45 +00:00
{
2008-05-08 16:39:14 +00:00
bool result = false ;
// Cancel volatile mode, if any
2008-09-23 10:04:10 +00:00
General . DisengageVolatileMode ( ) ;
2008-05-08 16:39:14 +00:00
2007-10-13 14:05:45 +00:00
// Check if a wad file is known
if ( map . FilePathName = = "" )
{
2007-10-14 15:44:55 +00:00
// Call to SaveMapAs
2008-05-08 16:39:14 +00:00
result = SaveMapAs ( ) ;
2007-10-13 14:05:45 +00:00
}
else
{
2007-10-14 18:11:03 +00:00
// Display status
mainwindow . DisplayStatus ( "Saving map file..." ) ;
Cursor . Current = Cursors . WaitCursor ;
2007-10-13 14:05:45 +00:00
// Save the map
2007-10-15 07:50:28 +00:00
if ( map . SaveMap ( map . FilePathName , MapManager . SAVE_NORMAL ) )
{
// Add recent file
mainwindow . AddRecentFile ( map . FilePathName ) ;
2008-05-08 16:39:14 +00:00
result = true ;
2007-10-15 07:50:28 +00:00
}
2007-10-14 18:11:03 +00:00
// All done
2007-10-14 21:31:45 +00:00
mainwindow . UpdateInterface ( ) ;
2007-10-14 18:11:03 +00:00
mainwindow . DisplayReady ( ) ;
Cursor . Current = Cursors . Default ;
2007-10-13 14:05:45 +00:00
}
2008-05-08 16:39:14 +00:00
return result ;
2007-10-13 14:05:45 +00:00
}
2007-10-14 15:44:55 +00:00
2008-05-08 16:39:14 +00:00
2007-10-14 15:44:55 +00:00
// This saves the current map as a different file
2008-05-08 16:39:14 +00:00
// Returns tre when saved, false when cancelled or failed
2008-04-27 12:07:26 +00:00
[BeginAction("savemapas")]
2008-05-08 16:39:14 +00:00
internal static void ActionSaveMapAs ( ) { SaveMapAs ( ) ; }
internal static bool SaveMapAs ( )
2007-10-14 15:44:55 +00:00
{
SaveFileDialog savefile ;
2008-05-08 16:39:14 +00:00
bool result = false ;
2007-10-14 15:44:55 +00:00
2008-05-08 16:39:14 +00:00
// Cancel volatile mode, if any
2008-09-23 10:04:10 +00:00
General . DisengageVolatileMode ( ) ;
2008-05-08 16:39:14 +00:00
2007-10-14 15:44:55 +00:00
// Show save as dialog
savefile = new SaveFileDialog ( ) ;
savefile . Filter = "Doom WAD Files (*.wad)|*.wad" ;
savefile . Title = "Save Map As" ;
savefile . AddExtension = true ;
savefile . CheckPathExists = true ;
savefile . OverwritePrompt = true ;
savefile . ValidateNames = true ;
if ( savefile . ShowDialog ( mainwindow ) = = DialogResult . OK )
{
2007-10-14 18:11:03 +00:00
// Display status
mainwindow . DisplayStatus ( "Saving map file..." ) ;
Cursor . Current = Cursors . WaitCursor ;
2007-10-14 15:44:55 +00:00
// Save the map
2007-10-15 07:50:28 +00:00
if ( map . SaveMap ( savefile . FileName , MapManager . SAVE_AS ) )
{
// Add recent file
mainwindow . AddRecentFile ( map . FilePathName ) ;
2008-05-08 16:39:14 +00:00
result = true ;
2007-10-15 07:50:28 +00:00
}
2007-10-14 18:11:03 +00:00
// All done
2007-10-14 21:31:45 +00:00
mainwindow . UpdateInterface ( ) ;
2007-10-14 18:11:03 +00:00
mainwindow . DisplayReady ( ) ;
2008-05-22 12:03:33 +00:00
Cursor . Current = Cursors . Default ;
}
return result ;
}
// This saves the current map as a different file
// Returns tre when saved, false when cancelled or failed
[BeginAction("savemapinto")]
internal static void ActionSaveMapInto ( ) { SaveMapInto ( ) ; }
internal static bool SaveMapInto ( )
{
SaveFileDialog savefile ;
bool result = false ;
// Cancel volatile mode, if any
2008-09-23 10:04:10 +00:00
General . DisengageVolatileMode ( ) ;
2008-05-22 12:03:33 +00:00
// Show save as dialog
savefile = new SaveFileDialog ( ) ;
savefile . Filter = "Doom WAD Files (*.wad)|*.wad" ;
savefile . Title = "Save Map Into" ;
savefile . AddExtension = true ;
savefile . CheckPathExists = true ;
savefile . OverwritePrompt = false ;
savefile . ValidateNames = true ;
if ( savefile . ShowDialog ( mainwindow ) = = DialogResult . OK )
{
// Display status
mainwindow . DisplayStatus ( "Saving map file..." ) ;
Cursor . Current = Cursors . WaitCursor ;
// Save the map
if ( map . SaveMap ( savefile . FileName , MapManager . SAVE_INTO ) )
{
// Add recent file
mainwindow . AddRecentFile ( map . FilePathName ) ;
result = true ;
}
// All done
mainwindow . UpdateInterface ( ) ;
mainwindow . DisplayReady ( ) ;
2007-10-14 18:11:03 +00:00
Cursor . Current = Cursors . Default ;
2007-10-14 15:44:55 +00:00
}
2008-05-08 16:39:14 +00:00
return result ;
2007-10-14 15:44:55 +00:00
}
2007-10-13 14:05:45 +00:00
2007-06-15 10:18:03 +00:00
// This asks to save the map if needed
// Returns false when action was cancelled
2008-01-02 21:49:43 +00:00
internal static bool AskSaveMap ( )
2007-06-15 10:18:03 +00:00
{
DialogResult result ;
// Map open and not saved?
2008-11-10 16:11:44 +00:00
if ( map ! = null )
2007-06-15 10:18:03 +00:00
{
2008-11-10 16:11:44 +00:00
if ( map . IsChanged )
2007-06-15 10:18:03 +00:00
{
2008-11-10 16:11:44 +00:00
// Ask to save changes
result = MessageBox . Show ( mainwindow , "Do you want to save changes to " + map . FileTitle + " (" + map . Options . CurrentName + ")?" , Application . ProductName , MessageBoxButtons . YesNoCancel , MessageBoxIcon . Question ) ;
if ( result = = DialogResult . Yes )
{
// Save map
if ( SaveMap ( ) )
{
// Ask to save changes to scripts
return map . AskSaveScriptChanges ( ) ;
}
else
{
// Failed to save map
return false ;
}
}
else if ( result = = DialogResult . Cancel )
{
// Abort
return false ;
}
else
{
// Ask to save changes to scripts
return map . AskSaveScriptChanges ( ) ;
}
2007-06-15 10:18:03 +00:00
}
2008-11-10 16:11:44 +00:00
else
2007-06-15 10:18:03 +00:00
{
2008-11-10 16:11:44 +00:00
// Ask to save changes to scripts
return map . AskSaveScriptChanges ( ) ;
2007-06-15 10:18:03 +00:00
}
}
2008-11-10 16:11:44 +00:00
else
{
return true ;
}
2007-06-15 10:18:03 +00:00
}
2007-06-14 23:31:57 +00:00
#endregion
2007-10-04 18:16:05 +00:00
#region = = = = = = = = = = = = = = = = = = Debug
2007-06-24 18:56:43 +00:00
2008-09-09 12:20:39 +00:00
// This shows a major failure
2008-12-06 13:20:47 +00:00
public static void Fail ( string message )
2008-09-09 12:20:39 +00:00
{
2008-12-10 22:58:58 +00:00
General . WriteLogLine ( "FAIL: " + message ) ;
2008-12-06 13:20:47 +00:00
Debug . Fail ( message ) ;
2008-12-10 22:58:58 +00:00
Terminate ( false ) ;
2008-09-09 12:20:39 +00:00
}
2007-10-04 18:16:05 +00:00
// This outputs log information
public static void WriteLogLine ( string line )
{
// Output to console
Console . WriteLine ( line ) ;
// Write to log file
2007-12-27 01:24:11 +00:00
try { File . AppendAllText ( logfile , line + Environment . NewLine ) ; }
catch ( Exception ) { }
2007-10-04 18:16:05 +00:00
}
// This outputs log information
public static void WriteLog ( string text )
{
// Output to console
Console . Write ( text ) ;
// Write to log file
2007-12-27 01:24:11 +00:00
try { File . AppendAllText ( logfile , text ) ; }
catch ( Exception ) { }
2007-10-04 18:16:05 +00:00
}
2007-12-04 19:22:14 +00:00
2007-10-04 18:16:05 +00:00
#endregion
2007-06-24 18:56:43 +00:00
#region = = = = = = = = = = = = = = = = = = Tools
2008-12-15 15:54:22 +00:00
// This swaps two pointers
public static void Swap < T > ( ref T a , ref T b )
{
T t = a ;
a = b ;
b = t ;
}
2008-11-17 00:41:52 +00:00
// This clamps a value
public static float Clamp ( float value , float min , float max )
{
return Math . Min ( Math . Max ( min , value ) , max ) ;
}
// This clamps a value
public static int Clamp ( int value , int min , int max )
{
return Math . Min ( Math . Max ( min , value ) , max ) ;
}
// This clamps a value
public static byte Clamp ( byte value , byte min , byte max )
{
return Math . Min ( Math . Max ( min , value ) , max ) ;
}
2007-12-26 00:31:32 +00:00
// This returns an element from a collection by index
public static T GetByIndex < T > ( ICollection < T > collection , int index )
{
IEnumerator < T > e = collection . GetEnumerator ( ) ;
for ( int i = - 1 ; i < index ; i + + ) e . MoveNext ( ) ;
return e . Current ;
}
2007-10-19 14:27:46 +00:00
// This returns the next power of 2
public static int NextPowerOf2 ( int v )
{
int p = 0 ;
// Continue increasing until higher than v
while ( Math . Pow ( 2 , p ) < v ) p + + ;
// Return power
return ( int ) Math . Pow ( 2 , p ) ;
}
2007-10-17 20:47:49 +00:00
// Convert bool to integer
2008-01-02 21:49:43 +00:00
internal static int Bool2Int ( bool v )
2007-10-17 20:47:49 +00:00
{
if ( v ) return 1 ; else return 0 ;
}
// Convert integer to bool
2008-01-02 21:49:43 +00:00
internal static bool Int2Bool ( int v )
2007-10-17 20:47:49 +00:00
{
return ( v ! = 0 ) ;
}
2007-10-13 14:05:45 +00:00
// This shows a message and logs the message
public static DialogResult ShowErrorMessage ( string message , MessageBoxButtons buttons )
{
2007-10-14 18:11:03 +00:00
Cursor oldcursor ;
DialogResult result ;
2007-10-13 14:05:45 +00:00
// Log the message
WriteLogLine ( message ) ;
2007-10-14 18:11:03 +00:00
// Use normal cursor
oldcursor = Cursor . Current ;
Cursor . Current = Cursors . Default ;
2007-10-13 14:05:45 +00:00
// Show message
2008-12-27 00:22:31 +00:00
IWin32Window window = null ;
if ( ( Form . ActiveForm ! = null ) & & Form . ActiveForm . Visible ) window = Form . ActiveForm ;
result = MessageBox . Show ( window , message , Application . ProductName , buttons , MessageBoxIcon . Error ) ;
2007-10-14 18:11:03 +00:00
// Restore old cursor
Cursor . Current = oldcursor ;
// Return result
return result ;
2007-10-13 14:05:45 +00:00
}
// This shows a message and logs the message
public static DialogResult ShowWarningMessage ( string message , MessageBoxButtons buttons )
2007-10-14 21:31:45 +00:00
{
return ShowWarningMessage ( message , buttons , MessageBoxDefaultButton . Button1 ) ;
}
// This shows a message and logs the message
public static DialogResult ShowWarningMessage ( string message , MessageBoxButtons buttons , MessageBoxDefaultButton defaultbutton )
2007-10-13 14:05:45 +00:00
{
2007-10-14 18:11:03 +00:00
Cursor oldcursor ;
DialogResult result ;
2007-10-13 14:05:45 +00:00
// Log the message
WriteLogLine ( message ) ;
2007-06-24 18:56:43 +00:00
2007-10-14 18:11:03 +00:00
// Use normal cursor
oldcursor = Cursor . Current ;
Cursor . Current = Cursors . Default ;
2007-10-13 14:05:45 +00:00
// Show message
2008-12-27 00:22:31 +00:00
IWin32Window window = null ;
if ( ( Form . ActiveForm ! = null ) & & Form . ActiveForm . Visible ) window = Form . ActiveForm ;
result = MessageBox . Show ( window , message , Application . ProductName , buttons , MessageBoxIcon . Warning , defaultbutton ) ;
2007-10-14 18:11:03 +00:00
// Restore old cursor
Cursor . Current = oldcursor ;
// Return result
return result ;
2007-10-13 14:05:45 +00:00
}
2007-06-24 18:56:43 +00:00
// This returns a unique temp filename
2008-01-02 21:49:43 +00:00
internal static string MakeTempFilename ( string tempdir )
2008-05-23 06:00:37 +00:00
{
return MakeTempFilename ( tempdir , "tmp" ) ;
}
// This returns a unique temp filename
internal static string MakeTempFilename ( string tempdir , string extension )
2007-06-24 18:56:43 +00:00
{
string filename ;
string chars = "abcdefghijklmnopqrstuvwxyz1234567890" ;
Random rnd = new Random ( ) ;
int i ;
do
{
// Generate a filename
filename = "" ;
for ( i = 0 ; i < 8 ; i + + ) filename + = chars [ rnd . Next ( chars . Length ) ] ;
2008-05-23 06:00:37 +00:00
filename = Path . Combine ( tempdir , filename + "." + extension ) ;
2007-06-24 18:56:43 +00:00
}
// Continue while file is not unique
2007-10-13 14:05:45 +00:00
while ( File . Exists ( filename ) | | Directory . Exists ( filename ) ) ;
2007-06-24 18:56:43 +00:00
// Return the filename
return filename ;
}
2007-10-13 14:05:45 +00:00
// This returns a unique temp directory name
2008-01-02 21:49:43 +00:00
internal static string MakeTempDirname ( )
2007-10-13 14:05:45 +00:00
{
string dirname ;
string chars = "abcdefghijklmnopqrstuvwxyz1234567890" ;
Random rnd = new Random ( ) ;
int i ;
do
{
// Generate a filename
dirname = "" ;
for ( i = 0 ; i < 8 ; i + + ) dirname + = chars [ rnd . Next ( chars . Length ) ] ;
dirname = Path . Combine ( temppath , dirname ) ;
}
// Continue while file is not unique
while ( File . Exists ( dirname ) | | Directory . Exists ( dirname ) ) ;
// Return the filename
return dirname ;
}
2007-11-04 22:19:30 +00:00
// This shows an image in a panel either zoomed or centered depending on size
public static void DisplayZoomedImage ( Panel panel , Image image )
{
// Set the image
panel . BackgroundImage = image ;
// Image not null?
if ( image ! = null )
{
// Small enough to fit in panel?
if ( ( image . Size . Width < panel . ClientRectangle . Width ) & &
( image . Size . Height < panel . ClientRectangle . Height ) )
{
// Display centered
panel . BackgroundImageLayout = ImageLayout . Center ;
}
else
{
// Display zoomed
panel . BackgroundImageLayout = ImageLayout . Zoom ;
}
}
}
// This calculates the new rectangle when one is scaled into another keeping aspect ratio
public static RectangleF MakeZoomedRect ( Size source , RectangleF target )
{
return MakeZoomedRect ( new SizeF ( ( int ) source . Width , ( int ) source . Height ) , target ) ;
}
// This calculates the new rectangle when one is scaled into another keeping aspect ratio
public static RectangleF MakeZoomedRect ( Size source , Rectangle target )
{
return MakeZoomedRect ( new SizeF ( ( int ) source . Width , ( int ) source . Height ) ,
new RectangleF ( ( int ) target . Left , ( int ) target . Top , ( int ) target . Width , ( int ) target . Height ) ) ;
}
// This calculates the new rectangle when one is scaled into another keeping aspect ratio
public static RectangleF MakeZoomedRect ( SizeF source , RectangleF target )
{
float scale ;
// Image fits?
if ( ( source . Width < = target . Width ) & &
( source . Height < = target . Height ) )
{
// Just center
scale = 1.0f ;
}
// Image is wider than tall?
else if ( ( source . Width - target . Width ) > ( source . Height - target . Height ) )
{
// Scale down by width
scale = target . Width / source . Width ;
}
else
{
// Scale down by height
scale = target . Height / source . Height ;
}
// Return centered and scaled
return new RectangleF ( target . Left + ( target . Width - source . Width * scale ) * 0.5f ,
target . Top + ( target . Height - source . Height * scale ) * 0.5f ,
source . Width * scale , source . Height * scale ) ;
}
2007-06-24 18:56:43 +00:00
#endregion
2008-11-10 16:11:44 +00:00
2008-04-27 12:07:26 +00:00
[BeginAction("testaction")]
2008-01-02 21:49:43 +00:00
internal static void TestAction ( )
2007-10-31 20:34:09 +00:00
{
2008-11-10 16:11:44 +00:00
ScriptEditorForm t = new ScriptEditorForm ( ) ;
2007-10-31 20:34:09 +00:00
t . ShowDialog ( mainwindow ) ;
t . Dispose ( ) ;
}
2007-06-13 19:39:38 +00:00
}
}
2007-09-28 08:56:18 +00:00