2010-02-28 13:51:17 +00:00
# include <iostream>
2010-06-11 17:53:00 +00:00
# include <string>
# include <fstream>
2010-06-15 17:04:52 +00:00
# include <boost/program_options.hpp>
2010-06-10 08:31:50 +00:00
2010-07-07 08:07:15 +00:00
# include <components/misc/fileops.hpp>
2011-04-28 07:39:40 +00:00
# include <components/files/path.hpp>
2010-06-16 10:13:21 +00:00
# include "engine.hpp"
2010-02-28 13:51:17 +00:00
2010-09-19 00:01:01 +00:00
# if defined(_WIN32) && !defined(_CONSOLE)
2011-01-04 00:34:55 +00:00
# include <boost/iostreams/concepts.hpp>
2010-09-19 00:01:01 +00:00
# include <boost/iostreams/stream_buffer.hpp>
# if !defined(_DEBUG)
# include <iostream>
# include <fstream>
# endif
// For OutputDebugString
# include <Windows.h>
// makes __argc and __argv available on windows
# include <stdlib.h>
# endif
2011-06-25 15:29:11 +00:00
// for Ogre::macBundlePath
# if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
# include <OSX/macUtils.h>
# endif
2011-07-08 14:16:20 +00:00
# include "config.hpp"
2010-02-28 13:51:17 +00:00
using namespace std ;
2010-06-16 10:21:02 +00:00
/// Parse command line options and openmw.cfg file (if one exists). Results are directly
/// written to \a engine.
/// \return Run OpenMW?
2010-06-05 18:37:01 +00:00
2010-06-16 10:21:02 +00:00
bool parseOptions ( int argc , char * * argv , OMW : : Engine & engine )
2010-02-28 13:51:17 +00:00
{
2010-06-27 23:44:15 +00:00
// Create a local alias for brevity
2010-10-05 16:23:53 +00:00
namespace bpo = boost : : program_options ;
2010-06-27 23:44:15 +00:00
bpo : : options_description desc (
2010-06-16 10:21:02 +00:00
" Syntax: openmw <options> \n Allowed options " ) ;
2010-06-10 08:31:50 +00:00
desc . add_options ( )
2011-07-08 14:16:20 +00:00
( " help " , " print help message and quit " )
( " version " , " print version information and quit " )
2011-05-05 17:39:11 +00:00
( " data " , bpo : : value < std : : vector < std : : string > > ( )
- > default_value ( std : : vector < std : : string > ( ) , " data " )
- > multitoken ( ) ,
" set data directories (later directories have higher priority) " )
2011-05-05 17:50:28 +00:00
( " data-local " , bpo : : value < std : : string > ( ) - > default_value ( " " ) ,
" set local data directory (highest priority) " )
2011-01-04 00:34:55 +00:00
( " resources " , bpo : : value < std : : string > ( ) - > default_value ( " resources " ) ,
" set resources directory " )
2010-06-27 23:44:15 +00:00
( " start " , bpo : : value < std : : string > ( ) - > default_value ( " Beshara " ) ,
2010-10-05 16:23:53 +00:00
" set initial cell " )
2011-03-29 11:57:56 +00:00
( " master " , bpo : : value < std : : vector < std : : string > > ( )
- > default_value ( std : : vector < std : : string > ( ) , " " )
- > multitoken ( ) ,
" master file(s) " )
( " plugin " , bpo : : value < std : : vector < std : : string > > ( )
- > default_value ( std : : vector < std : : string > ( ) , " " )
- > multitoken ( ) ,
" plugin file(s) " )
2011-04-21 16:23:46 +00:00
( " fps " , boost : : program_options : : value < bool > ( ) - >
implicit_value ( true ) - > default_value ( false ) , " show fps counter " )
( " debug " , boost : : program_options : : value < bool > ( ) - >
implicit_value ( true ) - > default_value ( false ) , " debug mode " )
( " nosound " , boost : : program_options : : value < bool > ( ) - >
implicit_value ( true ) - > default_value ( false ) , " disable all sound " )
( " script-verbose " , boost : : program_options : : value < bool > ( ) - >
implicit_value ( true ) - > default_value ( false ) , " verbose script output " )
( " new-game " , boost : : program_options : : value < bool > ( ) - >
implicit_value ( true ) - > default_value ( false ) ,
" activate char gen/new game mechanics " )
( " script-all " , boost : : program_options : : value < bool > ( ) - >
implicit_value ( true ) - > default_value ( false ) ,
" compile all scripts (excluding dialogue scripts) at startup " )
2011-05-05 17:56:16 +00:00
( " fs-strict " , boost : : program_options : : value < bool > ( ) - >
implicit_value ( true ) - > default_value ( false ) ,
" strict file system handling (no case folding) " )
Added new command line option: "encoding"
Added new command line option: "encoding" which allow to
change font encoding used in game messages.
Currently there are three evailable encodings:
win1250 - Central and Eastern European (languages
that use Latin script, such as Polish,
Czech, Slovak, Hungarian, Slovene, Bosnian,
Croatian, Serbian (Latin script),
Romanian and Albanian)
win1251 - languages that use the Cyrillic alphabet
such as Russian, Bulgarian, Serbian Cyrillic
and others
win1252 - Western European (Latin) - default
Signed-off-by: Lukasz Gromanowski <lgromanowski@gmail.com>
2011-07-17 20:16:50 +00:00
( " encoding " , boost : : program_options : : value < std : : string > ( ) - >
default_value ( " win1252 " ) ,
2011-07-17 20:53:20 +00:00
" Character encoding used in OpenMW game messages: \n "
Added new command line option: "encoding"
Added new command line option: "encoding" which allow to
change font encoding used in game messages.
Currently there are three evailable encodings:
win1250 - Central and Eastern European (languages
that use Latin script, such as Polish,
Czech, Slovak, Hungarian, Slovene, Bosnian,
Croatian, Serbian (Latin script),
Romanian and Albanian)
win1251 - languages that use the Cyrillic alphabet
such as Russian, Bulgarian, Serbian Cyrillic
and others
win1252 - Western European (Latin) - default
Signed-off-by: Lukasz Gromanowski <lgromanowski@gmail.com>
2011-07-17 20:16:50 +00:00
" \n \t win1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages \n "
" \n \t win1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages \n "
" \n \t win1252 - Western European (Latin) alphabet, used by default " )
2010-06-16 10:21:02 +00:00
;
2010-10-05 16:23:53 +00:00
2010-06-27 23:44:15 +00:00
bpo : : variables_map variables ;
2010-10-05 16:23:53 +00:00
2011-04-03 17:37:53 +00:00
//If there is an openmw.cfg in the current path use that as global config
//Otherwise try getPath
std : : string cfgFile = " openmw.cfg " ;
2011-06-19 16:14:03 +00:00
if ( ! Misc : : isFile ( cfgFile . c_str ( ) ) )
2011-04-03 17:37:53 +00:00
{
2011-04-28 07:56:50 +00:00
cfgFile = Files : : getPath ( Files : : Path_ConfigGlobal , " openmw " , " openmw.cfg " ) ;
2011-04-03 17:37:53 +00:00
}
2011-01-04 00:34:55 +00:00
std : : cout < < " Using global config file: " < < cfgFile < < std : : endl ;
std : : ifstream globalConfigFile ( cfgFile . c_str ( ) ) ;
2011-04-28 07:56:50 +00:00
cfgFile = Files : : getPath ( Files : : Path_ConfigUser , " openmw " , " openmw.cfg " ) ;
2011-01-04 00:34:55 +00:00
std : : cout < < " Using user config file: " < < cfgFile < < std : : endl ;
std : : ifstream userConfigFile ( cfgFile . c_str ( ) ) ;
2010-06-11 17:53:00 +00:00
2010-07-04 21:16:57 +00:00
bpo : : parsed_options valid_opts = bpo : : command_line_parser ( argc , argv ) . options ( desc ) . allow_unregistered ( ) . run ( ) ;
2010-06-24 22:32:00 +00:00
2010-07-04 21:16:57 +00:00
bpo : : store ( valid_opts , variables ) ;
bpo : : notify ( variables ) ;
2010-06-10 08:31:50 +00:00
2011-01-04 00:34:55 +00:00
if ( userConfigFile . is_open ( ) )
bpo : : store ( bpo : : parse_config_file ( userConfigFile , desc ) , variables ) ;
if ( globalConfigFile . is_open ( ) )
bpo : : store ( bpo : : parse_config_file ( globalConfigFile , desc ) , variables ) ;
2010-06-11 17:53:00 +00:00
2011-07-08 14:16:20 +00:00
bool run = true ;
2010-06-10 08:31:50 +00:00
if ( variables . count ( " help " ) )
{
2010-06-16 10:21:02 +00:00
std : : cout < < desc < < std : : endl ;
2011-07-08 14:16:20 +00:00
run = false ;
}
if ( variables . count ( " version " ) )
{
std : : cout < < " OpenMW version " < < OPENMW_VERSION < < std : : endl ;
run = false ;
2010-06-10 08:31:50 +00:00
}
2010-06-16 10:21:02 +00:00
2011-07-08 14:16:20 +00:00
if ( ! run )
2010-06-16 10:21:02 +00:00
return false ;
2011-07-08 14:16:20 +00:00
Added new command line option: "encoding"
Added new command line option: "encoding" which allow to
change font encoding used in game messages.
Currently there are three evailable encodings:
win1250 - Central and Eastern European (languages
that use Latin script, such as Polish,
Czech, Slovak, Hungarian, Slovene, Bosnian,
Croatian, Serbian (Latin script),
Romanian and Albanian)
win1251 - languages that use the Cyrillic alphabet
such as Russian, Bulgarian, Serbian Cyrillic
and others
win1252 - Western European (Latin) - default
Signed-off-by: Lukasz Gromanowski <lgromanowski@gmail.com>
2011-07-17 20:16:50 +00:00
// Font encoding settings
std : : string encoding ( variables [ " encoding " ] . as < std : : string > ( ) ) ;
if ( encoding = = " win1250 " )
{
std : : cout < < " Using Central and Eastern European font encoding. " < < std : : endl ;
engine . setEncoding ( encoding ) ;
}
else if ( encoding = = " win1251 " )
{
std : : cout < < " Using Cyrillic font encoding. " < < std : : endl ;
engine . setEncoding ( encoding ) ;
}
else
{
std : : cout < < " Using default (English) font encoding. " < < std : : endl ;
engine . setEncoding ( " win1252 " ) ;
2010-06-10 08:31:50 +00:00
}
2010-06-16 10:21:02 +00:00
2011-03-29 11:57:56 +00:00
// directory settings
2011-05-05 17:56:16 +00:00
if ( variables [ " fs-strict " ] . as < bool > ( ) = = true )
engine . enableFSStrict ( ) ;
2011-05-05 17:39:11 +00:00
std : : vector < std : : string > dataDirs = variables [ " data " ] . as < std : : vector < std : : string > > ( ) ;
std : : vector < boost : : filesystem : : path > dataDirs2 ( dataDirs . begin ( ) , dataDirs . end ( ) ) ;
2011-05-05 17:50:28 +00:00
std : : string local = variables [ " data-local " ] . as < std : : string > ( ) ;
if ( ! local . empty ( ) )
dataDirs . push_back ( local ) ;
2011-05-05 17:39:11 +00:00
engine . setDataDirs ( dataDirs2 ) ;
2011-01-04 00:34:55 +00:00
engine . setResourceDir ( variables [ " resources " ] . as < std : : string > ( ) ) ;
2011-03-29 11:57:56 +00:00
// master and plugin
std : : vector < std : : string > master = variables [ " master " ] . as < std : : vector < std : : string > > ( ) ;
if ( master . empty ( ) )
{
std : : cout < < " No master file given. Assuming Morrowind.esm " < < std : : endl ;
master . push_back ( " Morrowind " ) ;
}
if ( master . size ( ) > 1 )
{
std : : cout
< < " Ignoring all but the first master file (multiple master files not yet supported). "
< < std : : endl ;
}
engine . addMaster ( master [ 0 ] ) ;
std : : vector < std : : string > plugin = variables [ " plugin " ] . as < std : : vector < std : : string > > ( ) ;
if ( ! plugin . empty ( ) )
std : : cout < < " Ignoring plugin files (plugins not yet supported). " < < std : : endl ;
// startup-settings
2010-06-16 10:21:02 +00:00
engine . setCell ( variables [ " start " ] . as < std : : string > ( ) ) ;
2010-10-05 16:23:53 +00:00
2011-04-21 16:23:46 +00:00
if ( variables [ " new-game " ] . as < bool > ( ) = = true )
2011-03-29 11:57:56 +00:00
engine . setNewGame ( ) ;
// other settings
2011-04-21 16:23:46 +00:00
if ( variables [ " fps " ] . as < bool > ( ) = = true )
2011-02-18 14:46:24 +00:00
engine . showFPS ( ) ;
2011-04-21 16:23:46 +00:00
if ( variables [ " debug " ] . as < bool > ( ) = = true )
2010-07-02 11:12:05 +00:00
engine . enableDebugMode ( ) ;
2010-08-18 09:16:15 +00:00
2011-04-21 16:23:46 +00:00
if ( variables [ " nosound " ] . as < bool > ( ) = = true )
2010-08-18 09:16:15 +00:00
engine . disableSound ( ) ;
2010-10-05 16:23:53 +00:00
2011-04-21 16:23:46 +00:00
if ( variables [ " script-verbose " ] . as < bool > ( ) = = true )
2010-07-02 14:18:25 +00:00
engine . enableVerboseScripts ( ) ;
2010-06-23 00:52:17 +00:00
2011-04-21 16:23:46 +00:00
if ( variables [ " script-all " ] . as < bool > ( ) = = true )
2010-10-06 12:52:53 +00:00
engine . setCompileAll ( true ) ;
2010-06-23 00:52:17 +00:00
return true ;
2010-06-16 10:21:02 +00:00
}
int main ( int argc , char * * argv )
{
2011-03-08 22:42:04 +00:00
# if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
2011-03-12 00:00:42 +00:00
// set current dir to bundle path
2011-06-26 16:15:42 +00:00
boost : : filesystem : : path bundlePath = boost : : filesystem : : path ( Ogre : : macBundlePath ( ) ) . parent_path ( ) ;
2011-03-12 00:00:42 +00:00
boost : : filesystem : : current_path ( bundlePath ) ;
2011-03-08 22:42:04 +00:00
# endif
2010-09-19 00:01:01 +00:00
2010-06-16 10:21:02 +00:00
try
2010-02-28 13:51:17 +00:00
{
2010-06-16 10:21:02 +00:00
OMW : : Engine engine ;
2011-03-12 00:00:42 +00:00
2010-06-16 10:21:02 +00:00
if ( parseOptions ( argc , argv , engine ) )
{
engine . go ( ) ;
}
}
catch ( exception & e )
{
cout < < " \n ERROR: " < < e . what ( ) < < endl ;
return 1 ;
2010-02-28 13:51:17 +00:00
}
2010-10-05 16:23:53 +00:00
2010-06-16 10:21:02 +00:00
return 0 ;
2010-02-28 13:51:17 +00:00
}
2010-09-19 00:01:01 +00:00
// Platform specific for Windows when there is no console built into the executable.
// Windows will call the WinMain function instead of main in this case, the normal
// main function is then called with the __argc and __argv parameters.
// In addition if it is a debug build it will redirect cout to the debug console in Visual Studio
# if defined(_WIN32) && !defined(_CONSOLE)
# if defined(_DEBUG)
class DebugOutput : public boost : : iostreams : : sink
{
public :
std : : streamsize write ( const char * str , std : : streamsize size )
{
// Make a copy for null termination
std : : string tmp ( str , size ) ;
// Write string to Visual Studio Debug output
OutputDebugString ( tmp . c_str ( ) ) ;
return size ;
}
} ;
# else
class Logger : public boost : : iostreams : : sink
{
public :
Logger ( std : : ofstream & stream )
: out ( stream )
{
}
std : : streamsize write ( const char * str , std : : streamsize size )
{
out . write ( str , size ) ;
out . flush ( ) ;
return size ;
}
private :
std : : ofstream & out ;
} ;
# endif
int WINAPI WinMain ( HINSTANCE hInstance , HINSTANCE hPrevInstance , LPSTR lpCmdLine , int nShowCmd )
{
std : : streambuf * old_rdbuf = std : : cout . rdbuf ( ) ;
int ret = 0 ;
# if defined(_DEBUG)
// Redirect cout to VS debug output when running in debug mode
{
boost : : iostreams : : stream_buffer < DebugOutput > sb ;
sb . open ( DebugOutput ( ) ) ;
# else
// Redirect cout to openmw.log
std : : ofstream logfile ( " openmw.log " ) ;
{
boost : : iostreams : : stream_buffer < Logger > sb ;
sb . open ( Logger ( logfile ) ) ;
# endif
std : : cout . rdbuf ( & sb ) ;
ret = main ( __argc , __argv ) ;
std : : cout . rdbuf ( old_rdbuf ) ;
}
return ret ;
}
# endif