1 /*
2     Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
3 
4     This program is free software; you can redistribute it and/or
5     modify it under the terms of the GNU General Public License
6     as published by the Free Software Foundation; either version
7     3 of the License, or (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #include "main.h"
19 
main(int argc,char * argv[])20 int main(int argc, char *argv[]) {
21 
22     std::string exepath;
23 #ifndef _WIN32
24     if(argc > 0) {
25         exepath = std::string(argv[0]);
26     }
27 #endif
28 
29     SDLAppInit("Gource", "gource", exepath);
30 
31 #ifdef _WIN32
32         SDLApp::initConsole();
33 #endif
34 
35     ConfFile conf;
36     std::vector<std::string> files;
37 
38     //convert args to a conf file
39     //read the conf file
40     //apply the conf file to settings
41 
42     try {
43         gGourceSettings.parseArgs(argc, argv, conf, &files);
44 
45         if(gGourceSettings.load_config.empty() && !files.empty()) {
46             //see if file looks like a config file
47             for(std::vector<std::string>::iterator fit = files.begin(); fit != files.end(); fit++) {
48                 std::string file = *fit;
49 
50                 int file_length = file.size();
51 
52                 if(   (file.rfind(".conf") == (file_length-5) && file_length > 5)
53                    || (file.rfind(".cfg")  == (file_length-4) && file_length > 4)
54                    || (file.rfind(".ini")  == (file_length-4) && file_length > 4) ) {
55 
56                     bool is_conf=true;
57 
58                     try {
59                         ConfFile conftest;
60                         conftest.load(file);
61                     } catch(ConfFileException& exception) {
62                         is_conf = false;
63                     }
64 
65                     if(is_conf) {
66                         gGourceSettings.load_config = file;
67                         files.erase(fit);
68                         break;
69                     }
70                 }
71             }
72         }
73 
74         //set log level
75         Logger::getDefault()->setLevel(gGourceSettings.log_level);
76 
77 #ifdef _WIN32
78         // hide console if not needed
79         if(gGourceSettings.log_level == LOG_LEVEL_OFF && !SDLApp::existing_console) {
80             SDLApp::showConsole(false);
81         }
82 #endif
83 
84         //load config
85         if(!gGourceSettings.load_config.empty()) {
86             conf.clear();
87             conf.load(gGourceSettings.load_config);
88 
89             //apply args to loaded conf file
90             gGourceSettings.parseArgs(argc, argv, conf);
91         }
92 
93         //set path
94         if(!files.empty()) {
95             std::string path = files[files.size()-1];
96 
97             ConfSectionList* sectionlist = conf.getSections("gource");
98 
99             if(sectionlist!=0) {
100                 for(ConfSectionList::iterator sit = sectionlist->begin(); sit != sectionlist->end(); sit++) {
101                     (*sit)->setEntry("path", path);
102                 }
103             } else {
104                 conf.setEntry("gource", "path", path);
105             }
106         }
107 
108         //apply the config / see if its valid
109         gGourceSettings.importDisplaySettings(conf);
110         gGourceSettings.importGourceSettings(conf);
111 
112         //save config
113         if(!gGourceSettings.save_config.empty()) {
114             conf.save(gGourceSettings.save_config);
115             exit(0);
116         }
117 
118         //write custom log file
119         if(!gGourceSettings.output_custom_filename.empty() && !gGourceSettings.path.empty()) {
120 
121             Gource::writeCustomLog(gGourceSettings.path, gGourceSettings.output_custom_filename);
122             exit(0);
123         }
124 
125     } catch(ConfFileException& exception) {
126 
127         SDLAppQuit(exception.what());
128     }
129 
130     //enable frameless
131     display.enableFrameless(gGourceSettings.frameless);
132 
133     // this causes corruption on some video drivers
134     if(gGourceSettings.multisample) {
135         display.multiSample(4);
136     }
137 
138     //background needs alpha channel
139     if(gGourceSettings.transparent) {
140         display.enableAlpha(true);
141     }
142 
143     //enable vsync
144     display.enableVsync(gGourceSettings.vsync);
145 
146     //allow resizing window if we are not recording
147     if(gGourceSettings.resizable && gGourceSettings.output_ppm_filename.empty()) {
148         display.enableResize(true);
149     }
150 
151     try {
152 
153         display.init("Gource", gGourceSettings.display_width, gGourceSettings.display_height, gGourceSettings.fullscreen, gGourceSettings.screen);
154 
155 #if SDL_VERSION_ATLEAST(2,0,0)
156         if(!display.isFullscreen() && gGourceSettings.window_x >= 0 && gGourceSettings.window_y >= 0) {
157             SDL_SetWindowPosition(display.sdl_window, gGourceSettings.window_x, gGourceSettings.window_y);
158         }
159 
160         SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
161 #endif
162 
163     } catch(SDLInitException& exception) {
164 
165         char errormsg[1024];
166         snprintf(errormsg, 1024, "SDL initialization failed - %s", exception.what());
167 
168         SDLAppQuit(errormsg);
169     }
170 
171     //init frame exporter
172     FrameExporter* exporter = 0;
173 
174     if(gGourceSettings.output_ppm_filename.size() > 0) {
175 
176         try {
177 
178             exporter = new PPMExporter(gGourceSettings.output_ppm_filename);
179 
180         } catch(PPMExporterException& exception) {
181 
182             char errormsg[1024];
183             snprintf(errormsg, 1024, "could not write to '%s'", exception.what());
184 
185             SDLAppQuit(errormsg);
186         }
187     }
188 
189     if(display.multiSamplingEnabled()) {
190         glEnable(GL_MULTISAMPLE_ARB);
191     }
192 
193     GourceShell* gourcesh = 0;
194 
195     try {
196         gourcesh = gGourceShell = new GourceShell(&conf, exporter);
197         gourcesh->run();
198 
199     } catch(ResourceException& exception) {
200 
201         char errormsg[1024];
202         snprintf(errormsg, 1024, "failed to load resource '%s'", exception.what());
203 
204         SDLAppQuit(errormsg);
205 
206     } catch(SDLAppException& exception) {
207 
208         if(exception.showHelp()) {
209             gGourceSettings.help();
210         } else {
211             SDLAppQuit(exception.what());
212         }
213     }
214 
215     gGourceShell = 0;
216 
217     if(gourcesh != 0) delete gourcesh;
218     if(exporter != 0) delete exporter;
219 
220     //free resources
221     display.quit();
222 
223     return 0;
224 }
225