1 /*
2 * This file is part of the Colobot: Gold Edition source code
3 * Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam
4 * http://epsitec.ch; http://colobot.info; http://github.com/colobot
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see http://gnu.org/licenses
18 */
19
20 /**
21 * \file app/main.cpp
22 * \brief Entry point of application - main() function
23 */
24
25 #include "common/config.h"
26
27 #include "app/app.h"
28 #include "app/signal_handlers.h"
29
30 #include "common/logger.h"
31 #include "common/make_unique.h"
32 #include "common/profiler.h"
33 #include "common/restext.h"
34 #include "common/version.h"
35
36 #include "common/resources/resourcemanager.h"
37
38 #include "common/system/system.h"
39 #if PLATFORM_WINDOWS
40 #include "common/system/system_windows.h"
41 #endif
42
43 #if PLATFORM_WINDOWS
44 #include <windows.h>
45 #endif
46
47 #include <memory>
48 #include <vector>
49 #include <boost/filesystem.hpp>
50
51 /**
52 \mainpage
53
54 Doxygen documentation of Colobot: Gold Edition project.
55
56 <b>Colobot</b> <i>(COLOnize with BOTs)</i> is a game combining elements of real time strategy (RTS)
57 and educational game, aiming to teach programming through entertainment. You are playing as an astronaut
58 on a journey with robot helpers to find a planet for colonization. It features a C++ and Java-like,
59 object-oriented language, CBOT, which can be used to program the robots available in the game.
60
61 The original version of the game was developed by [Epsitec](http://www.epsitec.ch/) and released in 2001.
62 Later, in 2005 another version named Ceebot was released. In March 2012, through attempts
63 by Polish Colobot fans, Epsitec agreeed to release the source code of the game on GPLv3 license.
64 The license was given specifically to our community, <b>TerranovaTeam</b>,
65 part of <b>International Colobot Community (ICC)</b> (previously known as <i>Polish Portal of Colobot (PPC)</i>;
66 Polish: <i>Polski Portal Colobota</i>) with our website at http://colobot.info/.
67
68 \section Intro Introduction
69
70 The source code released by Epitec was sparsely documented. This documentation, written from scratch,
71 will aim to describe the various components of the code.
72
73 Currently, the only documented classes are the ones written from scratch or the old ones rewritten
74 to match the new code.
75 In time, the documentation will be extended to cover every major part of the code.
76
77 \section Structure Code structure
78
79 The source code was split from the original all-in-one directory to subdirectories,
80 each containing one major part of the project.
81 The current layout is the following:
82 - src/CBot - separate library with CBot language
83 - src/app - class CApplication and everything concerned with SDL
84 - src/common - shared structs, enums, defines, etc.; should not have any external dependencies
85 - src/common/resources - filesystem management using PHYSFS library
86 - src/common/system - system-dependent code such as displaying a message box, finding files, etc.
87 - src/common/thread - wrapper classes for SDL threads
88 - src/graphics/core - abstract interface of graphics device (abstract CDevice class)
89 - src/graphics/engine - main graphics engine based on abstract graphics device; is composed
90 of CEngine class and associated classes implementing the 3D engine
91 - src/graphics/model - code related to loading/saving model files
92 - src/graphics/opengl - concrete implementation of CDevice class in OpenGL: CGLDevice
93 - src/graphics/d3d - in (far) future - perhaps a newer implementation in DirectX (9? 10?)
94 - src/math - mathematical structures and functions
95 - src/object - non-grphical game object logic, that is robots, buildings, etc.
96 - src/level - main part of non-graphical game engine, that is loading levels etc.
97 - src/level/parser - parser for loading/saving level files from format known as <i>scene files</i>
98 - src/ui - 2D user interface (menu, buttons, check boxes, etc.)
99 - src/sound - sound and music engine written using fmod library
100 - src/physics - physics engine
101 - src/script - link with the CBot library
102 */
103
104 //! Entry point to the program
105 extern "C"
106 {
107
main(int argc,char * argv[])108 int main(int argc, char *argv[])
109 {
110 CLogger logger; // single instance of logger
111 logger.AddOutput(stderr);
112
113 auto systemUtils = CSystemUtils::Create(); // platform-specific utils
114 systemUtils->Init();
115
116 CProfiler::SetSystemUtils(systemUtils.get());
117
118 // Add file output to the logger
119 std::string logFileName;
120 #if DEV_BUILD
121 logFileName = "log.txt";
122 #else
123 boost::filesystem::create_directories(systemUtils->GetSaveDir());
124 logFileName = systemUtils->GetSaveDir() + "/log.txt";
125 #endif
126 FILE* logFile = fopen(logFileName.c_str(), "w");
127 if (logFile)
128 logger.AddOutput(logFile);
129 else
130 logger.Error("Failed to create log file, writing log to file disabled\n");
131
132
133 // Workaround for character encoding in argv on Windows
134 #if PLATFORM_WINDOWS
135 int wargc = 0;
136 wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &wargc);
137 if (wargv == nullptr)
138 {
139 logger.Error("CommandLineToArgvW failed\n");
140 return 1;
141 }
142
143 std::vector<std::vector<char>> windowsArgs;
144 for (int i = 0; i < wargc; i++)
145 {
146 std::wstring warg = wargv[i];
147 std::string arg = CSystemUtilsWindows::UTF8_Encode(warg);
148 std::vector<char> argVec(arg.begin(), arg.end());
149 argVec.push_back('\0');
150 windowsArgs.push_back(std::move(argVec));
151 }
152
153 auto windowsArgvPtrs = MakeUniqueArray<char*>(wargc);
154 for (int i = 0; i < wargc; i++)
155 windowsArgvPtrs[i] = windowsArgs[i].data();
156
157 argv = windowsArgvPtrs.get();
158
159 LocalFree(wargv);
160 #endif
161
162 logger.Info("%s starting\n", COLOBOT_FULLNAME);
163
164 CSignalHandlers::Init(systemUtils.get());
165
166 CResourceManager manager(argv[0]);
167
168 // Initialize static string arrays
169 InitializeRestext();
170 InitializeEventTypeTexts();
171
172 int code = 0;
173 CApplication app(systemUtils.get()); // single instance of the application
174
175 app.LoadEnvironmentVariables();
176
177 ParseArgsStatus status = app.ParseArguments(argc, argv);
178 if (status == PARSE_ARGS_FAIL)
179 {
180 systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", "Invalid commandline arguments!\n");
181 return app.GetExitCode();
182 }
183 else if (status == PARSE_ARGS_HELP)
184 {
185 return app.GetExitCode();
186 }
187
188 if (! app.Create())
189 {
190 code = app.GetExitCode();
191 if (code != 0 && !app.GetErrorMessage().empty())
192 {
193 systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", app.GetErrorMessage());
194 }
195 logger.Info("Didn't run main loop. Exiting with code %d\n", code);
196 return code;
197 }
198
199 code = app.Run();
200
201 logger.Info("Exiting with code %d\n", code);
202
203 return code;
204 }
205
206 } // extern "C"
207