1 /*
2 * This code is released under the GNU General Public License.  See COPYING for
3 * details.  Copyright 2003 John Spray: spray_john@users.sourceforge.net
4 */
5 
6 #include <SDL.h>
7 #include <SDL_main.h>
8 #include <SDL_ttf.h>
9 #include <physfs.h>
10 #include <string>
11 using namespace std;
12 #include "Game.h"
13 #include "Config.h"
14 
15 #include "Visual.h"
16 #include "SoundCore.h"
17 #include "Menu.h"
18 
19 #include "ScoreBoard.h"
20 
21 Config GLOB_conf;
22 ScoreBoard GLOB_scores;
23 
main(int argc,char * argv[])24 int main(int argc,char* argv[])
25 {
26 	int mainquit=0;
27 	string iconpath;
28 	string iconfile;
29 
30 	PHYSFS_init(argv[0]);
31 
32 	//set up all the filesystem stuff:
33 	#ifdef WIN32
34 	string homepath=getenv("USERPROFILE");
35 	#else
36 	string homepath=getenv("HOME");
37 	#endif
38 	string configpath=homepath+"/.excido";
39 //	string datapath="./data";
40 	string datapath=DATADIR;
41 
42 	if(!PHYSFS_addToSearchPath(homepath.c_str(),0))
43 					printf(	"main: PHYFS_addToSearchPath failed! %s\n",
44 									PHYSFS_getLastError());
45 	if(!PHYSFS_setWriteDir(homepath.c_str()))
46 					printf(	"main: PHYFS_setWriteDir failed! %s\n",
47 									PHYSFS_getLastError());
48 	if(!PHYSFS_exists(".excido")){
49 		printf("Creating .excido directory in %s\n",homepath.c_str());
50 		PHYSFS_mkdir(".excido");
51 	}
52 	if(!PHYSFS_removeFromSearchPath(homepath.c_str())) printf("main: PHYFS_removeFromSearchPath failed! %s\n",PHYSFS_getLastError());
53 
54 	if(!PHYSFS_setWriteDir(NULL))
55 					printf("main: PHYFS_setWriteDir failed! %s\n",PHYSFS_getLastError());
56 
57 	if(!PHYSFS_addToSearchPath(configpath.c_str(),0))
58 					printf(	"main: PHYFS_addToSearchPath failed on '%s'! %s\n",
59 									configpath.c_str(),PHYSFS_getLastError());
60 	/*append the data directory to the search list.  We want the contents
61 	 * of configpath to have precedence over the contents of the data directory*/
62 	if(!PHYSFS_addToSearchPath(datapath.c_str(),1)) printf("main: PHYFS_addToSearchPath failed on '%s'! %s\n",datapath.c_str(),PHYSFS_getLastError());
63 
64 	if(!PHYSFS_setWriteDir(configpath.c_str())) printf("main: PHYFS_setWriteDir failed! %s\n",PHYSFS_getLastError());
65 
66 	//load the configuration data
67 	GLOB_conf.Load("excido.conf");
68 	//override file-configuration with any command line options
69 	if(GLOB_conf.ParseArgs(argc,argv)){
70 		PHYSFS_deinit();
71 		return -1;
72 	}
73 
74 	//load the high-score table
75 	GLOB_scores.Load("excido.scores");
76 
77 
78 	if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)){
79 		printf("main: SDL initialisation failed with error %s\n",SDL_GetError());
80 		PHYSFS_deinit();
81 		return -1;
82 	}
83 
84 	SDL_WM_SetCaption("excido","excido");
85 	#ifdef RELEASE
86 	SDL_ShowCursor(SDL_DISABLE);
87 	#endif
88 	iconpath=DATADIR;
89 	iconfile="wmicon.bmp";
90 	iconfile=iconpath+iconfile;
91 	SDL_WM_SetIcon(SDL_LoadBMP(iconfile.c_str()), NULL);
92 
93 	//we'll setvideomode later, inside the menu loop, so that when it loops
94 	//after the user has been in the configuration menu, any changes to video
95 	//settings are properly reflected
96 	int sdlvidflags=SDL_OPENGL | SDL_RESIZABLE;
97 	SDL_Surface* screen;
98 
99 	//Initialise SDL_ttf
100 	if(TTF_Init()){
101 		printf("main: TTF_Init failed!\n");
102 		PHYSFS_deinit();
103 		SDL_Quit();
104 		return -1;
105 	}
106 
107 	alutInit(0,NULL);
108 	fprintf(stderr,"SoundCore::SoundCore: OpenAL initialised\n");fflush(stderr);
109 
110 	//for the menu system
111 	Game* menugame;
112 	Visual* menuvisual;
113 	SoundCore* menusound;
114 	Menu* menu;
115 	menufunc retval;
116 	Vector vzero; //For SoundCore's benefit
117 	vzero=0.0f;
118 
119 	//Hell, why not just use gotos and admit the filthyness of this next part?
120 	//I hope you follow illogic well, and can predict arcane return value systems
121 	while(!mainquit){
122 		while(!GLOB_conf.skipmenu){
123 			if(GLOB_conf.fullscreen)
124 				sdlvidflags |= SDL_FULLSCREEN;
125 			else if(sdlvidflags & SDL_FULLSCREEN)
126 				sdlvidflags ^= SDL_FULLSCREEN;
127 			screen=SDL_SetVideoMode(GLOB_conf.screenx,GLOB_conf.screeny,GLOB_conf.bpp,sdlvidflags);
128 
129 			menugame = new Game(screen);
130 			menuvisual = new Visual(menugame);
131 			menusound = new SoundCore();
132 			menuvisual->InitGL();
133 			menuvisual->LoadTexture("menuback.png");
134 			menuvisual->LoadTexture("menucursor.png");
135 			menusound->LoadSample("menuambient.wav");
136 			menusound->Play("menuambient.wav",-1,vzero,vzero);
137 
138 			char* labels[]={"Play","Configure","High Scores","Exit",NULL};
139 			menufunc functions[]={MENU_CONTINUE,MENU_SUB1,MENU_SUB2,MENU_QUITFULL};
140 			void* targets[]={NULL,NULL,NULL,NULL};
141 			menu=new Menu(labels,functions,targets,menuvisual);
142 			menu->solidbackground=1;
143 			retval=menu->Happen();
144 			delete menu;
145 
146 			if(retval==MENU_QUITFULL){
147 				delete menuvisual;
148 				delete menusound;
149 				delete menugame;
150 				GLOB_conf.Dump("excido.conf");
151 				GLOB_scores.Dump("excido.scores");
152 				PHYSFS_deinit();
153 				TTF_Quit();
154 				SDL_Quit();
155 				return 0;
156 			}
157 			else if(retval==MENU_SUB1){
158 				GLOB_conf.ConfigMenu(menuvisual,menusound);
159 			}
160 			else if(retval==MENU_SUB2){
161 				GLOB_scores.Display(menuvisual);
162 			}
163 			else if(retval==MENU_CONTINUE)
164 				GLOB_conf.skipmenu=1;
165 
166 			delete menusound;
167 			delete menuvisual;
168 			delete menugame;
169 		}
170 		GLOB_conf.skipmenu=0;
171 		//the whole skipmenu thing isn't too readable.  Basically, the user can set it using
172 		// "-s", but it's also used internally to handle the situation where this menu returns,
173 		//but we're launching the ConfigMenu, so we want to loop around again.  You get it.
174 
175 		if(GLOB_conf.fullscreen)
176 			sdlvidflags |= SDL_FULLSCREEN;
177 		else if(sdlvidflags & SDL_FULLSCREEN)
178 			sdlvidflags ^= SDL_FULLSCREEN;
179 		screen=SDL_SetVideoMode(GLOB_conf.screenx,GLOB_conf.screeny,GLOB_conf.bpp,sdlvidflags);
180 
181 		Game* game = new Game(screen);
182 		game->verbose=GLOB_conf.verbose;
183 		mainquit=game->Happen();
184 		delete game;
185 
186 
187 		if(mainquit==1) mainquit=0;
188 		//could use temp variable for extra clarity, but you get it
189 		//game::Happen has to return 2 to actually get out.  QUITFULL
190 
191 	} //mainquit
192 
193 	alutExit();
194 
195 	GLOB_conf.Dump("excido.conf");
196 	GLOB_scores.Dump("excido.scores");
197 	PHYSFS_deinit();
198 	TTF_Quit();
199 	SDL_Quit();
200 	return 0;
201 }
202