bool Engine::Initialize(const VariantMap& parameters) { if (initialized_) return true; PROFILE(InitEngine); // Set headless mode headless_ = GetParameter(parameters, "Headless", false).GetBool(); // Register the rest of the subsystems if (!headless_) { context_->RegisterSubsystem(new Graphics(context_)); context_->RegisterSubsystem(new Renderer(context_)); } else { // Register graphics library objects explicitly in headless mode to allow them to work without using actual GPU resources RegisterGraphicsLibrary(context_); } // In debug mode, check now that all factory created objects can be created without crashing #ifdef _DEBUG const HashMap<ShortStringHash, SharedPtr<ObjectFactory> >& factories = context_->GetObjectFactories(); for (HashMap<ShortStringHash, SharedPtr<ObjectFactory> >::ConstIterator i = factories.Begin(); i != factories.End(); ++i) SharedPtr<Object> object = i->second_->CreateObject(); #endif // Start logging Log* log = GetSubsystem<Log>(); if (log) { if (HasParameter(parameters, "LogLevel")) log->SetLevel(GetParameter(parameters, "LogLevel").GetInt()); log->SetQuiet(GetParameter(parameters, "LogQuiet", false).GetBool()); log->Open(GetParameter(parameters, "LogName", "Urho3D.log").GetString()); } // Set maximally accurate low res timer GetSubsystem<Time>()->SetTimerPeriod(1); // Configure max FPS if (GetParameter(parameters, "FrameLimiter", true) == false) SetMaxFps(0); // 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 unsigned numThreads = GetParameter(parameters, "WorkerThreads", true).GetBool() ? GetNumPhysicalCPUs() - 1 : 0; if (numThreads) { GetSubsystem<WorkQueue>()->CreateThreads(numThreads); LOGINFO(ToString("Created %u worker thread%s", numThreads, numThreads > 1 ? "s" : "")); } // Add resource paths ResourceCache* cache = GetSubsystem<ResourceCache>(); FileSystem* fileSystem = GetSubsystem<FileSystem>(); String exePath = fileSystem->GetProgramDir(); Vector<String> resourcePaths = GetParameter(parameters, "ResourcePaths", "CoreData;Data").GetString().Split(';'); Vector<String> resourcePackages = GetParameter(parameters, "ResourcePackages").GetString().Split(';'); for (unsigned i = 0; i < resourcePaths.Size(); ++i) { bool success = false; // If path is not absolute, prefer to add it as a package if possible if (!IsAbsolutePath(resourcePaths[i])) { String packageName = exePath + resourcePaths[i] + ".pak"; if (fileSystem->FileExists(packageName)) { SharedPtr<PackageFile> package(new PackageFile(context_)); if (package->Open(packageName)) { cache->AddPackageFile(package); success = true; } } if (!success) { String pathName = exePath + resourcePaths[i]; if (fileSystem->DirExists(pathName)) success = cache->AddResourceDir(pathName); } } else { String pathName = resourcePaths[i]; if (fileSystem->DirExists(pathName)) success = cache->AddResourceDir(pathName); } if (!success) { LOGERROR("Failed to add resource path " + resourcePaths[i]); return false; } } // Then add specified packages for (unsigned i = 0; i < resourcePackages.Size(); ++i) { bool success = false; String packageName = exePath + resourcePackages[i]; if (fileSystem->FileExists(packageName)) { SharedPtr<PackageFile> package(new PackageFile(context_)); if (package->Open(packageName)) { cache->AddPackageFile(package); success = true; } } if (!success) { LOGERROR("Failed to add resource package " + resourcePackages[i]); return false; } } // Initialize graphics & audio output if (!headless_) { Graphics* graphics = GetSubsystem<Graphics>(); Renderer* renderer = GetSubsystem<Renderer>(); if (HasParameter(parameters, "ExternalWindow")) graphics->SetExternalWindow(GetParameter(parameters, "ExternalWindow").GetPtr()); graphics->SetForceSM2(GetParameter(parameters, "ForceSM2", false).GetBool()); graphics->SetWindowTitle(GetParameter(parameters, "WindowTitle", "Urho3D").GetString()); if (!graphics->SetMode( GetParameter(parameters, "WindowWidth", 0).GetInt(), GetParameter(parameters, "WindowHeight", 0).GetInt(), GetParameter(parameters, "FullScreen", true).GetBool(), GetParameter(parameters, "WindowResizable", false).GetBool(), GetParameter(parameters, "VSync", false).GetBool(), GetParameter(parameters, "TripleBuffer", false).GetBool(), GetParameter(parameters, "MultiSample", 1).GetInt() )) return false; if (HasParameter(parameters, "RenderPath")) renderer->SetDefaultRenderPath(cache->GetResource<XMLFile>(GetParameter(parameters, "RenderPath").GetString())); renderer->SetDrawShadows(GetParameter(parameters, "Shadows", true).GetBool()); if (renderer->GetDrawShadows() && GetParameter(parameters, "LowQualityShadows", false).GetBool()) renderer->SetShadowQuality(SHADOWQUALITY_LOW_16BIT); if (GetParameter(parameters, "Sound", true).GetBool()) { GetSubsystem<Audio>()->SetMode( GetParameter(parameters, "SoundBuffer", 100).GetInt(), GetParameter(parameters, "SoundMixRate", 44100).GetInt(), GetParameter(parameters, "SoundStereo", true).GetBool(), GetParameter(parameters, "SoundInterpolation", true).GetBool() ); } } // Init FPU state of main thread InitFPU(); frameTimer_.Reset(); initialized_ = true; return true; }
int main(int argc, char** argv) { #ifdef WIN32 const Vector<String>& arguments = ParseArguments(GetCommandLineW()); #else const Vector<String>& arguments = ParseArguments(argc, argv); #endif bool dumpApiMode = false; String outputFile; if (arguments.Size() < 1) ErrorExit("Usage: ScriptCompiler <input file> [resource path for includes]\n" " ScriptCompiler -dumpapi [output file]"); else { if (arguments[0] != "-dumpapi") outputFile = arguments[0]; else { dumpApiMode = true; if (arguments.Size() > 1) outputFile = arguments[1]; } } SharedPtr<Context> context(new Context()); // Note: creating the Engine registers most subsystems which don't require engine initialization SharedPtr<Engine> engine(new Engine(context)); context->RegisterSubsystem(new Script(context)); Log* log = context->GetSubsystem<Log>(); // Register Log subsystem manually if compiled without logging support if (!log) { context->RegisterSubsystem(new Log(context)); log = context->GetSubsystem<Log>(); } log->SetLevel(LOG_WARNING); log->SetTimeStamp(false); if (!dumpApiMode) { String path, file, extension; SplitPath(outputFile, path, file, extension); ResourceCache* cache = context->GetSubsystem<ResourceCache>(); // Add resource path to be able to resolve includes if (arguments.Size() > 1) cache->AddResourceDir(arguments[1]); else cache->AddResourceDir(cache->GetPreferredResourceDir(path)); if (!file.StartsWith("*")) CompileScript(context, outputFile); else { Vector<String> scriptFiles; context->GetSubsystem<FileSystem>()->ScanDir(scriptFiles, path, file + extension, SCAN_FILES, false); for (unsigned i = 0; i < scriptFiles.Size(); ++i) CompileScript(context, path + scriptFiles[i]); } } else { if (!outputFile.Empty()) { log->SetQuiet(true); log->Open(outputFile); } // If without output file, dump to stdout instead context->GetSubsystem<Script>()->DumpAPI(); } return EXIT_SUCCESS; }