Browse Source

Refactor to expect log level parameter value after a space.

To be consistent with the rest of the Engine parameters.
Yao Wei Tjong 姚伟忠 12 years ago
parent
commit
772a546d56
2 changed files with 99 additions and 97 deletions
  1. 22 22
      Docs/GettingStarted.dox
  2. 77 75
      Source/Engine/Engine/Engine.cpp

+ 22 - 22
Docs/GettingStarted.dox

@@ -165,28 +165,28 @@ On Android and iOS the command line can not be entered, so it is instead read fr
 The engine can be configured using the following command line options.
 The engine can be configured using the following command line options.
 
 
 \verbatim
 \verbatim
--x <res>    Horizontal resolution
--y <res>    Vertical resolution
--m <level>  Enable hardware multisampling
--v          Enable vertical sync
--t          Enable triple buffering
--w          Start in windowed mode
--s          Enable resizing when in windowed mode
--q          Enable quiet mode which does not log to standard output stream
--b <length> Sound buffer length in milliseconds
--r <freq>   Sound mixing frequency in Hz
--p <paths>  Resource path(s) to use, separated by semicolons
--log<level> Change the log level, valid 'level' values are 'debug', 'info', 'warning', 'error'
--headless   Headless mode. No application window will be created
--prepass    Use light pre-pass rendering
--deferred   Use deferred rendering
--lqshadows  Use low-quality (1-sample) shadow filtering
--noshadows  Disable shadow rendering
--nolimit    Disable frame limiter
--nothreads  Disable worker threads
--nosound    Disable sound output
--noip       Disable sound mixing interpolation
--sm2        Force SM2.0 rendering
+-x <res>     Horizontal resolution
+-y <res>     Vertical resolution
+-m <level>   Enable hardware multisampling
+-v           Enable vertical sync
+-t           Enable triple buffering
+-w           Start in windowed mode
+-s           Enable resizing when in windowed mode
+-q           Enable quiet mode which does not log to standard output stream
+-b <length>  Sound buffer length in milliseconds
+-r <freq>    Sound mixing frequency in Hz
+-p <paths>   Resource path(s) to use, separated by semicolons
+-log <level> Change the log level, valid 'level' values are 'debug', 'info', 'warning', 'error'
+-headless    Headless mode. No application window will be created
+-prepass     Use light pre-pass rendering
+-deferred    Use deferred rendering
+-lqshadows   Use low-quality (1-sample) shadow filtering
+-noshadows   Disable shadow rendering
+-nolimit     Disable frame limiter
+-nothreads   Disable worker threads
+-nosound     Disable sound output
+-noip        Disable sound mixing interpolation
+-sm2         Force SM2.0 rendering
 \endverbatim
 \endverbatim
 
 
 \section Running_Xcode_AngelScript_Info Mac OS X specific - How to view/edit AngelScript within Xcode
 \section Running_Xcode_AngelScript_Info Mac OS X specific - How to view/edit AngelScript within Xcode

+ 77 - 75
Source/Engine/Engine/Engine.cpp

@@ -103,7 +103,7 @@ Engine::Engine(Context* context) :
 {
 {
     // Register self as a subsystem
     // Register self as a subsystem
     context_->RegisterSubsystem(this);
     context_->RegisterSubsystem(this);
-    
+
     // Create subsystems which do not depend on engine initialization or startup parameters
     // Create subsystems which do not depend on engine initialization or startup parameters
     context_->RegisterSubsystem(new Time(context_));
     context_->RegisterSubsystem(new Time(context_));
     context_->RegisterSubsystem(new WorkQueue(context_));
     context_->RegisterSubsystem(new WorkQueue(context_));
@@ -119,12 +119,12 @@ Engine::Engine(Context* context) :
     context_->RegisterSubsystem(new Input(context_));
     context_->RegisterSubsystem(new Input(context_));
     context_->RegisterSubsystem(new Audio(context_));
     context_->RegisterSubsystem(new Audio(context_));
     context_->RegisterSubsystem(new UI(context_));
     context_->RegisterSubsystem(new UI(context_));
-    
+
     // Register object factories for libraries which are not automatically registered along with subsystem creation
     // Register object factories for libraries which are not automatically registered along with subsystem creation
     RegisterSceneLibrary(context_);
     RegisterSceneLibrary(context_);
     RegisterPhysicsLibrary(context_);
     RegisterPhysicsLibrary(context_);
     RegisterNavigationLibrary(context_);
     RegisterNavigationLibrary(context_);
-    
+
     SubscribeToEvent(E_EXITREQUESTED, HANDLER(Engine, HandleExitRequested));
     SubscribeToEvent(E_EXITREQUESTED, HANDLER(Engine, HandleExitRequested));
 }
 }
 
 
@@ -136,12 +136,12 @@ bool Engine::Initialize(const VariantMap& parameters)
 {
 {
     if (initialized_)
     if (initialized_)
         return true;
         return true;
-    
+
     PROFILE(InitEngine);
     PROFILE(InitEngine);
-    
+
     // Set headless mode
     // Set headless mode
     headless_ = GetParameter(parameters, "Headless", false).GetBool();
     headless_ = GetParameter(parameters, "Headless", false).GetBool();
-    
+
     // Register the rest of the subsystems
     // Register the rest of the subsystems
     if (!headless_)
     if (!headless_)
     {
     {
@@ -153,14 +153,14 @@ bool Engine::Initialize(const VariantMap& parameters)
         // Register graphics library objects explicitly in headless mode to allow them to work without using actual GPU resources
         // Register graphics library objects explicitly in headless mode to allow them to work without using actual GPU resources
         RegisterGraphicsLibrary(context_);
         RegisterGraphicsLibrary(context_);
     }
     }
-    
+
     // In debug mode, check now that all factory created objects can be created without crashing
     // In debug mode, check now that all factory created objects can be created without crashing
     #ifdef _DEBUG
     #ifdef _DEBUG
     const HashMap<ShortStringHash, SharedPtr<ObjectFactory> >& factories = context_->GetObjectFactories();
     const HashMap<ShortStringHash, SharedPtr<ObjectFactory> >& factories = context_->GetObjectFactories();
     for (HashMap<ShortStringHash, SharedPtr<ObjectFactory> >::ConstIterator i = factories.Begin(); i != factories.End(); ++i)
     for (HashMap<ShortStringHash, SharedPtr<ObjectFactory> >::ConstIterator i = factories.Begin(); i != factories.End(); ++i)
         SharedPtr<Object> object = i->second_->CreateObject();
         SharedPtr<Object> object = i->second_->CreateObject();
     #endif
     #endif
-    
+
     // Start logging
     // Start logging
     Log* log = GetSubsystem<Log>();
     Log* log = GetSubsystem<Log>();
     if (log)
     if (log)
@@ -170,36 +170,36 @@ bool Engine::Initialize(const VariantMap& parameters)
         log->SetQuiet(GetParameter(parameters, "LogQuiet", false).GetBool());
         log->SetQuiet(GetParameter(parameters, "LogQuiet", false).GetBool());
         log->Open(GetParameter(parameters, "LogName", "Urho3D.log").GetString());
         log->Open(GetParameter(parameters, "LogName", "Urho3D.log").GetString());
     }
     }
-    
+
     // Set maximally accurate low res timer
     // Set maximally accurate low res timer
     GetSubsystem<Time>()->SetTimerPeriod(1);
     GetSubsystem<Time>()->SetTimerPeriod(1);
-    
+
     // Configure max FPS
     // Configure max FPS
     if (GetParameter(parameters, "FrameLimiter", true) == false)
     if (GetParameter(parameters, "FrameLimiter", true) == false)
         SetMaxFps(0);
         SetMaxFps(0);
-    
+
     // Set amount of worker threads according to the available physical CPU cores. Using also hyperthreaded cores results in
     // Set amount of worker threads according to the available physical CPU cores. Using also hyperthreaded cores results in
     // unpredictable extra synchronization overhead. Also reserve one core for the main thread
     // unpredictable extra synchronization overhead. Also reserve one core for the main thread
     unsigned numThreads = GetParameter(parameters, "WorkerThreads", true).GetBool() ? GetNumPhysicalCPUs() - 1 : 0;
     unsigned numThreads = GetParameter(parameters, "WorkerThreads", true).GetBool() ? GetNumPhysicalCPUs() - 1 : 0;
     if (numThreads)
     if (numThreads)
     {
     {
         GetSubsystem<WorkQueue>()->CreateThreads(numThreads);
         GetSubsystem<WorkQueue>()->CreateThreads(numThreads);
-        
+
         LOGINFO(ToString("Created %u worker thread%s", numThreads, numThreads > 1 ? "s" : ""));
         LOGINFO(ToString("Created %u worker thread%s", numThreads, numThreads > 1 ? "s" : ""));
     }
     }
-    
+
     // Add resource paths
     // Add resource paths
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     FileSystem* fileSystem = GetSubsystem<FileSystem>();
     FileSystem* fileSystem = GetSubsystem<FileSystem>();
     String exePath = fileSystem->GetProgramDir();
     String exePath = fileSystem->GetProgramDir();
-    
+
     Vector<String> resourcePaths = GetParameter(parameters, "ResourcePaths", "CoreData;Data").GetString().Split(';');
     Vector<String> resourcePaths = GetParameter(parameters, "ResourcePaths", "CoreData;Data").GetString().Split(';');
     Vector<String> resourcePackages = GetParameter(parameters, "ResourcePackages").GetString().Split(';');
     Vector<String> resourcePackages = GetParameter(parameters, "ResourcePackages").GetString().Split(';');
-    
+
     for (unsigned i = 0; i < resourcePaths.Size(); ++i)
     for (unsigned i = 0; i < resourcePaths.Size(); ++i)
     {
     {
         bool success = false;
         bool success = false;
-        
+
         // If path is not absolute, prefer to add it as a package if possible
         // If path is not absolute, prefer to add it as a package if possible
         if (!IsAbsolutePath(resourcePaths[i]))
         if (!IsAbsolutePath(resourcePaths[i]))
         {
         {
@@ -213,7 +213,7 @@ bool Engine::Initialize(const VariantMap& parameters)
                     success = true;
                     success = true;
                 }
                 }
             }
             }
-            
+
             if (!success)
             if (!success)
             {
             {
                 String pathName = exePath + resourcePaths[i];
                 String pathName = exePath + resourcePaths[i];
@@ -227,19 +227,19 @@ bool Engine::Initialize(const VariantMap& parameters)
             if (fileSystem->DirExists(pathName))
             if (fileSystem->DirExists(pathName))
                 success = cache->AddResourceDir(pathName);
                 success = cache->AddResourceDir(pathName);
         }
         }
-        
+
         if (!success)
         if (!success)
         {
         {
             LOGERROR("Failed to add resource path " + resourcePaths[i]);
             LOGERROR("Failed to add resource path " + resourcePaths[i]);
             return false;
             return false;
         }
         }
     }
     }
-    
+
     // Then add specified packages
     // Then add specified packages
     for (unsigned i = 0; i < resourcePackages.Size(); ++i)
     for (unsigned i = 0; i < resourcePackages.Size(); ++i)
     {
     {
         bool success = false;
         bool success = false;
-        
+
         String packageName = exePath + resourcePackages[i];
         String packageName = exePath + resourcePackages[i];
         if (fileSystem->FileExists(packageName))
         if (fileSystem->FileExists(packageName))
         {
         {
@@ -250,21 +250,21 @@ bool Engine::Initialize(const VariantMap& parameters)
                 success = true;
                 success = true;
             }
             }
         }
         }
-        
+
         if (!success)
         if (!success)
         {
         {
             LOGERROR("Failed to add resource package " + resourcePackages[i]);
             LOGERROR("Failed to add resource package " + resourcePackages[i]);
             return false;
             return false;
         }
         }
     }
     }
-    
+
 
 
     // Initialize graphics & audio output
     // Initialize graphics & audio output
     if (!headless_)
     if (!headless_)
     {
     {
         Graphics* graphics = GetSubsystem<Graphics>();
         Graphics* graphics = GetSubsystem<Graphics>();
         Renderer* renderer = GetSubsystem<Renderer>();
         Renderer* renderer = GetSubsystem<Renderer>();
-        
+
         if (HasParameter(parameters, "ExternalWindow"))
         if (HasParameter(parameters, "ExternalWindow"))
             graphics->SetExternalWindow(GetParameter(parameters, "ExternalWindow").GetPtr());
             graphics->SetExternalWindow(GetParameter(parameters, "ExternalWindow").GetPtr());
         graphics->SetForceSM2(GetParameter(parameters, "ForceSM2", false).GetBool());
         graphics->SetForceSM2(GetParameter(parameters, "ForceSM2", false).GetBool());
@@ -279,13 +279,13 @@ bool Engine::Initialize(const VariantMap& parameters)
             GetParameter(parameters, "MultiSample", 1).GetInt()
             GetParameter(parameters, "MultiSample", 1).GetInt()
         ))
         ))
             return false;
             return false;
-        
+
         if (HasParameter(parameters, "RenderPath"))
         if (HasParameter(parameters, "RenderPath"))
             renderer->SetDefaultRenderPath(cache->GetResource<XMLFile>(GetParameter(parameters, "RenderPath").GetString()));
             renderer->SetDefaultRenderPath(cache->GetResource<XMLFile>(GetParameter(parameters, "RenderPath").GetString()));
         renderer->SetDrawShadows(GetParameter(parameters, "Shadows", true).GetBool());
         renderer->SetDrawShadows(GetParameter(parameters, "Shadows", true).GetBool());
         if (renderer->GetDrawShadows() && GetParameter(parameters, "LowQualityShadows", false).GetBool())
         if (renderer->GetDrawShadows() && GetParameter(parameters, "LowQualityShadows", false).GetBool())
             renderer->SetShadowQuality(SHADOWQUALITY_LOW_16BIT);
             renderer->SetShadowQuality(SHADOWQUALITY_LOW_16BIT);
-        
+
         if (GetParameter(parameters, "Sound", true).GetBool())
         if (GetParameter(parameters, "Sound", true).GetBool())
         {
         {
             GetSubsystem<Audio>()->SetMode(
             GetSubsystem<Audio>()->SetMode(
@@ -296,12 +296,12 @@ bool Engine::Initialize(const VariantMap& parameters)
             );
             );
         }
         }
     }
     }
-    
+
     // Init FPU state of main thread
     // Init FPU state of main thread
     InitFPU();
     InitFPU();
-    
+
     frameTimer_.Reset();
     frameTimer_.Reset();
-    
+
     initialized_ = true;
     initialized_ = true;
     return true;
     return true;
 }
 }
@@ -309,22 +309,22 @@ bool Engine::Initialize(const VariantMap& parameters)
 void Engine::RunFrame()
 void Engine::RunFrame()
 {
 {
     assert(initialized_);
     assert(initialized_);
-    
+
     // If not headless, and the graphics subsystem no longer has a window open, assume we should exit
     // If not headless, and the graphics subsystem no longer has a window open, assume we should exit
     if (!headless_ && !GetSubsystem<Graphics>()->IsInitialized())
     if (!headless_ && !GetSubsystem<Graphics>()->IsInitialized())
         exiting_ = true;
         exiting_ = true;
-    
+
     if (exiting_)
     if (exiting_)
         return;
         return;
-    
+
     // Note: there is a minimal performance cost to looking up subsystems (uses a hashmap); if they would be looked up several
     // Note: there is a minimal performance cost to looking up subsystems (uses a hashmap); if they would be looked up several
     // times per frame it would be better to cache the pointers
     // times per frame it would be better to cache the pointers
     Time* time = GetSubsystem<Time>();
     Time* time = GetSubsystem<Time>();
     Input* input = GetSubsystem<Input>();
     Input* input = GetSubsystem<Input>();
     Audio* audio = GetSubsystem<Audio>();
     Audio* audio = GetSubsystem<Audio>();
-    
+
     time->BeginFrame(timeStep_);
     time->BeginFrame(timeStep_);
-    
+
     // If pause when minimized -mode is in use, stop updates and audio as necessary
     // If pause when minimized -mode is in use, stop updates and audio as necessary
     if (pauseMinimized_ && input->IsMinimized())
     if (pauseMinimized_ && input->IsMinimized())
     {
     {
@@ -342,13 +342,13 @@ void Engine::RunFrame()
             audio->Play();
             audio->Play();
             audioPaused_ = false;
             audioPaused_ = false;
         }
         }
-        
+
         Update();
         Update();
     }
     }
-    
+
     Render();
     Render();
     ApplyFrameLimit();
     ApplyFrameLimit();
-    
+
     time->EndFrame();
     time->EndFrame();
 }
 }
 
 
@@ -356,7 +356,7 @@ Console* Engine::CreateConsole()
 {
 {
     if (headless_ || !initialized_)
     if (headless_ || !initialized_)
         return 0;
         return 0;
-    
+
     // Return existing console if possible
     // Return existing console if possible
     Console* console = GetSubsystem<Console>();
     Console* console = GetSubsystem<Console>();
     if (!console)
     if (!console)
@@ -364,7 +364,7 @@ Console* Engine::CreateConsole()
         console = new Console(context_);
         console = new Console(context_);
         context_->RegisterSubsystem(console);
         context_->RegisterSubsystem(console);
     }
     }
-    
+
     return console;
     return console;
 }
 }
 
 
@@ -372,7 +372,7 @@ DebugHud* Engine::CreateDebugHud()
 {
 {
     if (headless_ || !initialized_)
     if (headless_ || !initialized_)
         return 0;
         return 0;
-    
+
      // Return existing debug HUD if possible
      // Return existing debug HUD if possible
     DebugHud* debugHud = GetSubsystem<DebugHud>();
     DebugHud* debugHud = GetSubsystem<DebugHud>();
     if (!debugHud)
     if (!debugHud)
@@ -380,7 +380,7 @@ DebugHud* Engine::CreateDebugHud()
         debugHud = new DebugHud(context_);
         debugHud = new DebugHud(context_);
         context_->RegisterSubsystem(debugHud);
         context_->RegisterSubsystem(debugHud);
     }
     }
-    
+
     return debugHud;
     return debugHud;
 }
 }
 
 
@@ -447,20 +447,20 @@ void Engine::DumpResources()
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     const HashMap<ShortStringHash, ResourceGroup>& resourceGroups = cache->GetAllResources();
     const HashMap<ShortStringHash, ResourceGroup>& resourceGroups = cache->GetAllResources();
     LOGRAW("\n");
     LOGRAW("\n");
-    
+
     for (HashMap<ShortStringHash, ResourceGroup>::ConstIterator i = resourceGroups.Begin();
     for (HashMap<ShortStringHash, ResourceGroup>::ConstIterator i = resourceGroups.Begin();
         i != resourceGroups.End(); ++i)
         i != resourceGroups.End(); ++i)
     {
     {
         unsigned num = i->second_.resources_.Size();
         unsigned num = i->second_.resources_.Size();
         unsigned memoryUse = i->second_.memoryUse_;
         unsigned memoryUse = i->second_.memoryUse_;
-        
+
         if (num)
         if (num)
         {
         {
             LOGRAW("Resource type " + i->second_.resources_.Begin()->second_->GetTypeName() +
             LOGRAW("Resource type " + i->second_.resources_.Begin()->second_->GetTypeName() +
                 ": count " + String(num) + " memory use " + String(memoryUse) + "\n");
                 ": count " + String(num) + " memory use " + String(memoryUse) + "\n");
         }
         }
     }
     }
-    
+
     LOGRAW("Total memory use of all resources " + String(cache->GetTotalMemoryUse()) + "\n\n");
     LOGRAW("Total memory use of all resources " + String(cache->GetTotalMemoryUse()) + "\n\n");
     #endif
     #endif
 }
 }
@@ -474,7 +474,7 @@ void Engine::DumpMemory()
     _CrtMemBlockHeader* block = state.pBlockHeader;
     _CrtMemBlockHeader* block = state.pBlockHeader;
     unsigned total = 0;
     unsigned total = 0;
     unsigned blocks = 0;
     unsigned blocks = 0;
-    
+
     for (;;)
     for (;;)
     {
     {
         if (block && block->pBlockHeaderNext)
         if (block && block->pBlockHeaderNext)
@@ -482,7 +482,7 @@ void Engine::DumpMemory()
         else
         else
             break;
             break;
     }
     }
-    
+
     while (block)
     while (block)
     {
     {
         if (block->nBlockUse > 0)
         if (block->nBlockUse > 0)
@@ -491,13 +491,13 @@ void Engine::DumpMemory()
                 LOGRAW("Block " + String((int)block->lRequest) + ": " + String(block->nDataSize) + " bytes, file " + String(block->szFileName) + " line " + String(block->nLine) + "\n");
                 LOGRAW("Block " + String((int)block->lRequest) + ": " + String(block->nDataSize) + " bytes, file " + String(block->szFileName) + " line " + String(block->nLine) + "\n");
             else
             else
                 LOGRAW("Block " + String((int)block->lRequest) + ": " + String(block->nDataSize) + " bytes\n");
                 LOGRAW("Block " + String((int)block->lRequest) + ": " + String(block->nDataSize) + " bytes\n");
-            
+
             total += block->nDataSize;
             total += block->nDataSize;
             ++blocks;
             ++blocks;
         }
         }
         block = block->pBlockHeaderPrev;
         block = block->pBlockHeaderPrev;
     }
     }
-    
+
     LOGRAW("Total allocated memory " + String(total) + " bytes in " + String(blocks) + " blocks\n\n");
     LOGRAW("Total allocated memory " + String(total) + " bytes in " + String(blocks) + " blocks\n\n");
     #else
     #else
     LOGRAW("DumpMemory() supported on MSVC debug mode only\n\n");
     LOGRAW("DumpMemory() supported on MSVC debug mode only\n\n");
@@ -508,20 +508,20 @@ void Engine::DumpMemory()
 void Engine::Update()
 void Engine::Update()
 {
 {
     PROFILE(Update);
     PROFILE(Update);
-    
+
     // Logic update event
     // Logic update event
     using namespace Update;
     using namespace Update;
-    
+
     VariantMap eventData;
     VariantMap eventData;
     eventData[P_TIMESTEP] = timeStep_;
     eventData[P_TIMESTEP] = timeStep_;
     SendEvent(E_UPDATE, eventData);
     SendEvent(E_UPDATE, eventData);
-    
+
     // Logic post-update event
     // Logic post-update event
     SendEvent(E_POSTUPDATE, eventData);
     SendEvent(E_POSTUPDATE, eventData);
-    
+
     // Rendering update event
     // Rendering update event
     SendEvent(E_RENDERUPDATE, eventData);
     SendEvent(E_RENDERUPDATE, eventData);
-    
+
     // Post-render update event
     // Post-render update event
     SendEvent(E_POSTRENDERUPDATE, eventData);
     SendEvent(E_POSTRENDERUPDATE, eventData);
 }
 }
@@ -530,14 +530,14 @@ void Engine::Render()
 {
 {
     if (headless_)
     if (headless_)
         return;
         return;
-    
+
     PROFILE(Render);
     PROFILE(Render);
-    
+
     // If device is lost, BeginFrame will fail and we skip rendering
     // If device is lost, BeginFrame will fail and we skip rendering
     Graphics* graphics = GetSubsystem<Graphics>();
     Graphics* graphics = GetSubsystem<Graphics>();
     if (!graphics->BeginFrame())
     if (!graphics->BeginFrame())
         return;
         return;
-    
+
     GetSubsystem<Renderer>()->Render();
     GetSubsystem<Renderer>()->Render();
     GetSubsystem<UI>()->Render();
     GetSubsystem<UI>()->Render();
     graphics->EndFrame();
     graphics->EndFrame();
@@ -547,27 +547,27 @@ void Engine::ApplyFrameLimit()
 {
 {
     if (!initialized_)
     if (!initialized_)
         return;
         return;
-    
+
     int maxFps = maxFps_;
     int maxFps = maxFps_;
     Input* input = GetSubsystem<Input>();
     Input* input = GetSubsystem<Input>();
     if (input && !input->HasFocus())
     if (input && !input->HasFocus())
         maxFps = Min(maxInactiveFps_, maxFps);
         maxFps = Min(maxInactiveFps_, maxFps);
-    
+
     long long elapsed = 0;
     long long elapsed = 0;
-    
+
     // Perform waiting loop if maximum FPS set
     // Perform waiting loop if maximum FPS set
     if (maxFps)
     if (maxFps)
     {
     {
         PROFILE(ApplyFrameLimit);
         PROFILE(ApplyFrameLimit);
-        
+
         long long targetMax = 1000000LL / maxFps;
         long long targetMax = 1000000LL / maxFps;
-        
+
         for (;;)
         for (;;)
         {
         {
             elapsed = frameTimer_.GetUSec(false);
             elapsed = frameTimer_.GetUSec(false);
             if (elapsed >= targetMax)
             if (elapsed >= targetMax)
                 break;
                 break;
-            
+
             // Sleep if 1 ms or more off the frame limiting goal
             // Sleep if 1 ms or more off the frame limiting goal
             if (targetMax - elapsed >= 1000LL)
             if (targetMax - elapsed >= 1000LL)
             {
             {
@@ -576,9 +576,9 @@ void Engine::ApplyFrameLimit()
             }
             }
         }
         }
     }
     }
-    
+
     elapsed = frameTimer_.GetUSec(true);
     elapsed = frameTimer_.GetUSec(true);
-    
+
     // If FPS lower than minimum, clamp elapsed time
     // If FPS lower than minimum, clamp elapsed time
     if (minFps_)
     if (minFps_)
     {
     {
@@ -586,7 +586,7 @@ void Engine::ApplyFrameLimit()
         if (elapsed > targetMin)
         if (elapsed > targetMin)
             elapsed = targetMin;
             elapsed = targetMin;
     }
     }
-    
+
     // Perform timestep smoothing
     // Perform timestep smoothing
     timeStep_ = 0.0f;
     timeStep_ = 0.0f;
     lastTimeSteps_.Push(elapsed / 1000000.0f);
     lastTimeSteps_.Push(elapsed / 1000000.0f);
@@ -605,23 +605,16 @@ void Engine::ApplyFrameLimit()
 VariantMap Engine::ParseParameters(const Vector<String>& arguments)
 VariantMap Engine::ParseParameters(const Vector<String>& arguments)
 {
 {
     VariantMap ret;
     VariantMap ret;
-    
+
     for (unsigned i = 0; i < arguments.Size(); ++i)
     for (unsigned i = 0; i < arguments.Size(); ++i)
     {
     {
         if (arguments[i].Length() > 1 && arguments[i][0] == '-')
         if (arguments[i].Length() > 1 && arguments[i][0] == '-')
         {
         {
             String argument = arguments[i].Substring(1).ToLower();
             String argument = arguments[i].Substring(1).ToLower();
             String value = i + 1 < arguments.Size() ? arguments[i + 1] : String::EMPTY;
             String value = i + 1 < arguments.Size() ? arguments[i + 1] : String::EMPTY;
-            
+
             if (argument == "headless")
             if (argument == "headless")
                 ret["Headless"] = true;
                 ret["Headless"] = true;
-            else if (argument.Substring(0, 3) == "log")
-            {
-                argument = argument.Substring(3);
-                int logLevel = GetStringListIndex(argument.CString(), logLevelPrefixes, -1);
-                if (logLevel != -1)
-                    ret["LogLevel"] = logLevel;
-            }
             else if (argument == "nolimit")
             else if (argument == "nolimit")
                 ret["FrameLimiter"] = false;
                 ret["FrameLimiter"] = false;
             else if (argument == "nosound")
             else if (argument == "nosound")
@@ -652,6 +645,15 @@ VariantMap Engine::ParseParameters(const Vector<String>& arguments)
                 ret["WindowResizable"] = true;
                 ret["WindowResizable"] = true;
             else if (argument == "q")
             else if (argument == "q")
                 ret["LogQuiet"] = true;
                 ret["LogQuiet"] = true;
+            else if (argument == "log" && !value.Empty())
+            {
+                int logLevel = GetStringListIndex(value.CString(), logLevelPrefixes, -1);
+                if (logLevel != -1)
+                {
+                    ret["LogLevel"] = logLevel;
+                    ++i;
+                }
+            }
             else if (argument == "x" && !value.Empty())
             else if (argument == "x" && !value.Empty())
             {
             {
                 ret["WindowWidth"] = ToInt(value);
                 ret["WindowWidth"] = ToInt(value);
@@ -684,7 +686,7 @@ VariantMap Engine::ParseParameters(const Vector<String>& arguments)
             }
             }
         }
         }
     }
     }
-    
+
     return ret;
     return ret;
 }
 }
 
 
@@ -716,7 +718,7 @@ void Engine::DoExit()
     Graphics* graphics = GetSubsystem<Graphics>();
     Graphics* graphics = GetSubsystem<Graphics>();
     if (graphics)
     if (graphics)
         graphics->Close();
         graphics->Close();
-    
+
     exiting_ = true;
     exiting_ = true;
 }
 }