1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2 
3 /**
4 	\mainpage
5 	This is the documentation of the Spring RTS Engine.
6 	http://springrts.com/
7 */
8 
9 
10 #include "System/SpringApp.h"
11 
12 #include "System/Exceptions.h"
13 #include "System/FileSystem/FileSystem.h"
14 #include "System/Platform/errorhandler.h"
15 #include "System/Platform/Threading.h"
16 #include "System/Platform/Misc.h"
17 #include "System/Log/ILog.h"
18 
19 #ifdef WIN32
20 	#include "lib/SOP/SOP.hpp" // NvOptimus
21 
22 	#include <stdlib.h>
23 	#include <process.h>
24 	#define setenv(k,v,o) SetEnvironmentVariable(k,v)
25 #endif
26 
27 
28 
Run(int argc,char * argv[])29 int Run(int argc, char* argv[])
30 {
31 	int ret = -1;
32 
33 #ifdef __MINGW32__
34 	// For the MinGW backtrace() implementation we need to know the stack end.
35 	{
36 		extern void* stack_end;
37 		char here;
38 		stack_end = (void*) &here;
39 	}
40 #endif
41 
42 	Threading::DetectCores();
43 	Threading::SetMainThread();
44 
45 	// run
46 	try {
47 		SpringApp app(argc, argv);
48 		ret = app.Run();
49 	} CATCH_SPRING_ERRORS
50 
51 	// check if (a thread in) Spring crashed, if so display an error message
52 	Threading::Error* err = Threading::GetThreadError();
53 
54 	if (err != NULL) {
55 		ErrorMessageBox(" error: " + err->message, err->caption, err->flags, true);
56 	}
57 
58 	return ret;
59 }
60 
61 
62 /**
63  * Always run on dedicated GPU
64  * @return true when restart is required with new env vars
65  */
SetNvOptimusProfile(const std::string & processFileName)66 static bool SetNvOptimusProfile(const std::string& processFileName)
67 {
68 #ifdef WIN32
69 	if (SOP_CheckProfile("Spring"))
70 		return false;
71 
72 	const bool profileChanged = (SOP_SetProfile("Spring", processFileName) == SOP_RESULT_CHANGE);
73 
74 	// on Windows execvp breaks lobbies (new process: new PID)
75 	return (false && profileChanged);
76 #endif
77 	return false;
78 }
79 
80 
81 
82 /**
83  * @brief main
84  * @return exit code
85  * @param argc argument count
86  * @param argv array of argument strings
87  *
88  * Main entry point function
89  */
main(int argc,char * argv[])90 int main(int argc, char* argv[])
91 {
92 // PROFILE builds exit on execv ...
93 // HEADLESS run mostly in parallel for testing purposes, 100% omp threads wouldn't help then
94 #if !defined(PROFILE) && !defined(HEADLESS)
95 	if (SetNvOptimusProfile(FileSystem::GetFilename(argv[0]))) {
96 		// prepare for restart
97 		std::vector<std::string> args(argc - 1);
98 
99 		for (int i = 1; i < argc; i++)
100 			args[i - 1] = argv[i];
101 
102 		// ExecProc normally does not return; if it does the retval is an error-string
103 		ErrorMessageBox(Platform::ExecuteProcess(argv[0], args), "Execv error:", MBF_OK | MBF_EXCL);
104 	}
105 #endif
106 
107 	return (Run(argc, argv));
108 }
109 
110 
111 
112 #ifdef WIN32
WinMain(HINSTANCE hInstanceIn,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)113 int WINAPI WinMain(HINSTANCE hInstanceIn, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
114 {
115 	return main(__argc, __argv);
116 }
117 #endif
118 
119