1 // Description:
2 //   main. Ready, set, go!
3 //
4 // Copyright (C) 2010 Frank Becker
5 //
6 // This program is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free Software
8 // Foundation;  either version 2 of the License,  or (at your option) any  later
9 // version.
10 //
11 // This program is distributed in the hope that it will be useful,  but  WITHOUT
12 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
14 //
15 #include "SDL/SDL.h" //needed for SDL_main
16 
17 #include "Trace.hpp"
18 #include "Constants.hpp"
19 #include "Config.hpp"
20 #include "Input.hpp"
21 #include "Game.hpp"
22 #include "GameState.hpp"
23 #include "Endian.hpp"
24 #include "ResourceManager.hpp"
25 #include "GetDataPath.hpp"
26 #include "OnlineUpdate.hpp"
27 
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 
31 using namespace std;
32 
migrateConfig(void)33 void migrateConfig( void)
34 {
35     //if onlineCheck is not set, default it to true
36     bool dummy;
37     if( ! ConfigS::instance()->getBoolean( "onlineCheck", dummy))
38     {
39 	ConfigS::instance()->updateKeyword( "onlineCheck", "1");
40     }
41 
42 #ifdef WIN32
43     rename( "config.txt-scores" , "leaderboard");
44 #else
45     struct stat statInfo;
46 
47     string configFileName = ConfigS::instance()->getConfigFileName();
48 
49     if( (stat( configFileName.c_str(), &statInfo) != -1) )
50     {
51 	LOG_INFO << "Found config file - no need to migrate\n";
52 	return;
53     }
54 
55     string::size_type start = configFileName.find_last_of( '/');
56     if( start > 0)
57     {
58 	string fileName = configFileName.substr(start+1);
59 //	LOG_INFO << "filename = " << fileName << endl;
60 	string path = configFileName.substr( 0, start);
61 //	LOG_INFO << "path = " << path << endl;
62 	if( (stat( path.c_str(), &statInfo) != -1) )
63 	{
64 	    if( S_ISDIR(statInfo.st_mode))
65 	    {
66 		LOG_INFO << "New config dir found - OK\n";
67 		return;
68 	    }
69 	    else
70 	    {
71 		//ok, we got some work to do
72 		string bak = path + ".bak";
73 		if( rename( path.c_str(), bak.c_str()) == 0)
74 		{
75 		    mkdir( path.c_str(), 0777);
76 		    if( rename( bak.c_str(), configFileName.c_str()) != 0)
77 		    {
78 			LOG_ERROR << "Unable to rename: " << bak << " to " << configFileName << endl;
79 			return;
80 		    }
81 		    string leaderboard = path + "/leaderboard";
82 		    string oldleaderboard = path + "-scores";
83 		    if( rename( oldleaderboard.c_str(), leaderboard.c_str()) != 0)
84 		    {
85 			LOG_WARNING << "Unable to rename: " << oldleaderboard << " to " << leaderboard << endl;
86 			return;
87 		    }
88 		    LOG_INFO << "config file migration OK\n";
89 		}
90 	    }
91 	}
92 	else
93 	{
94 	    //.critter subdir doesn't exists at all, create it
95 	    mkdir( path.c_str(), 0777);
96 	}
97     }
98 #endif
99 }
100 
addOtherResourcePacks()101 void addOtherResourcePacks()
102 {
103     string configDir = ConfigS::instance()->getConfigDirectory();
104 
105     int i=0;
106     char num[10];
107     bool done = false;
108     while( ! done)
109     {
110 	sprintf( num, "%03d", i);
111 	string filename = string("resource") + num + string(".dat");
112 	string fullPath = configDir + filename;
113 	struct stat statInfo;
114 	LOG_INFO  << "Looking for " << fullPath << endl;
115 	if( stat( fullPath.c_str(), &statInfo) == -1)
116 	{
117 	    done = true;
118 	}
119 	else
120 	{
121 	    ResourceManagerS::instance()->addResourcePack(filename, configDir);
122 	}
123 	i++;
124     }
125 }
126 
checkEndian(void)127 void checkEndian( void)
128 {
129     if( ::isLittleEndian())
130     {
131 	LOG_INFO << "Setting up for little endian." << endl;
132     }
133     else
134     {
135 	LOG_INFO << "Setting up for big endian." << endl;
136     }
137 }
138 
showInfo()139 void showInfo()
140 {
141     LOG_INFO << "----------------------------------" << endl;
142     LOG_INFO << GAMETITLE << " " << GAMEVERSION << endl;
143     LOG_INFO << "Copyright (C) 2001-2010 by Frank Becker" << endl;
144     LOG_INFO << "Visit http://criticalmass.sourceforge.net" << endl;
145     LOG_INFO << "----------------------------------" << endl;
146 }
147 
148 #include <SDL/SDL_image.h>
149 #include <SDL/SDL_mixer.h>
150 #include <png.h>
151 #include <OSName.hpp>
showVersions(void)152 void showVersions( void)
153 {
154     LOG_INFO << "OS: " << OSNAME() << endl;
155 
156     const SDL_version *vsdl = SDL_Linked_Version();
157     LOG_INFO << "SDL Version "
158              << (int)vsdl->major  << "."
159              << (int)vsdl->minor  << "."
160              << (int)vsdl->patch  << endl;
161     const SDL_version *isdl = IMG_Linked_Version();
162     LOG_INFO << "SDL_image Version "
163              << (int)isdl->major  << "."
164              << (int)isdl->minor  << "."
165              << (int)isdl->patch  << endl;
166     const SDL_version *msdl = Mix_Linked_Version();
167     LOG_INFO << "SDL_mixer Version "
168              << (int)msdl->major  << "."
169              << (int)msdl->minor  << "."
170              << (int)msdl->patch  << endl;
171     LOG_INFO << "PNG Version " << png_get_header_version(NULL) << endl;
172 }
173 
main(int argc,char * argv[])174 int main( int argc, char *argv[])
175 {
176     XTRACE();
177 
178     showInfo();
179     showVersions();
180 
181     checkEndian();
182 
183     string resourceFilePath = "resource.dat";
184     if( !ResourceManagerS::instance()->
185 	addResourcePack(resourceFilePath, getDataPath()))
186     {
187 	LOG_WARNING << "resource.dat not found. Trying data directory." << endl;
188 #ifdef VCPP
189 	ResourceManagerS::instance()->addResourceDirectory( "../../data");
190 #else
191 	ResourceManagerS::instance()->addResourceDirectory( "data");
192 #endif
193 	if( ResourceManagerS::instance()->getResourceSize("system/config.txt") < 0)
194 	{
195 	    LOG_ERROR << "Sorry, unable to find game data!" << endl;
196 	    return -1;
197 	}
198     }
199 
200     Config *cfg = ConfigS::instance();
201 
202 #ifdef __APPLE__
203     cfg->setSubdirectory( "Critter");
204 #elif defined(WIN32)
205     cfg->setSubdirectory( "Critter");
206 #else
207     cfg->setSubdirectory( ".critter");
208 #endif
209     migrateConfig();
210 
211     addOtherResourcePacks();
212 
213     // register config handler(s)
214     cfg->registerConfigHandler( InputS::instance());
215 
216     // read config file...
217     cfg->updateFromFile();
218 
219     // process command line arguments...
220     cfg->updateFromCommandLine( argc, argv);
221 
222     // to dump or not to dump...
223     cfg->getBoolean( "developer", GameState::isDeveloper);
224     if( GameState::isDeveloper)
225     {
226 	cfg->dump();
227     }
228 #ifdef USE_ONLINE_UPDATE
229     OnlineUpdateS::instance()->init("http://criticalmass.sourceforge.net/update.php");
230     OnlineUpdateS::instance()->getUpdate();
231 #endif
232     // get ready!
233     if( GameS::instance()->init())
234     {
235         // let's go!
236 	GameS::instance()->run();
237     }
238 
239     // Fun is over. Cleanup time...
240     GameS::cleanup();
241 
242 #ifdef USE_ONLINE_UPDATE
243     OnlineUpdateS::cleanup();
244 #endif
245 
246     ConfigS::cleanup();
247     ResourceManagerS::cleanup();
248 
249     LOG_INFO << "Cleanup complete. Ready to Exit." << endl;
250 
251     showInfo();
252 
253     // See ya!
254     return 0;
255 }
256