1 /*
2 * IceBreaker
3 * Copyright (c) 2000-2002 Matthew Miller <mattdm@mattdm.org>
4 *
5 * <http://www.mattdm.org/icebreaker/>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc., 59
19 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23 #include <SDL.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <time.h>
27 #include <unistd.h>
28 #ifndef __MINGW32__
29 #include <pwd.h>
30 #endif
31 #include <string.h>
32 #include <sys/types.h>
33
34
35 #include "icebreaker.h"
36 #include "penguin.h"
37 #include "line.h"
38 #include "sound.h"
39 #include "globals.h"
40 #include "grid.h"
41 #include "level.h"
42 #include "intro.h"
43 #include "text.h"
44 #include "transition.h"
45 #include "hiscore.h"
46 #include "dialog.h"
47 #include "options.h"
48 #include "fullscreen.h"
49 #include "cursor.h"
50 #include "themes.h"
51 #include "titlebar.h"
52 #include "benchmark.h"
53 #include "misc.h"
54
55 // global
56 SDL_Surface* screen;
57 SDL_Surface* fullscreen;
58
59 char username[50]; // FIX -- move this into the options struct?
60 char homedir[255];
61
62 SDL_Surface * penguinicon;
63
64 // functions
65
66 int setup(void);
67 void cleanup(void);
68
69 /************************************************************************/
70
setup(void)71 int setup(void)
72 {
73 struct passwd * userinfo;
74 int newuser=false;
75
76 srandom(time(NULL)+getpid());
77
78 //stupid buffers
79 setvbuf(stdout,(char *)NULL, _IOLBF, 0);
80
81 userinfo = getpwuid(getuid()); // FIX -- make this part of the options struct; and maybe save in options file
82 snprintf(username,50,userinfo->pw_name); // not like it's gonna be fifty characters. but y'know. note: gets chopped to fit in gethighusername().
83 snprintf(homedir,255,userinfo->pw_dir); // fix - use OS define for length
84
85 inithiscores();
86 newuser=readoptions();
87
88 if (commandline.fullscreen==FULLSCREENOFF)
89 options.fullscreen=FULLSCREENOFF;
90 else if (commandline.fullscreen==FULLSCREENON && options.fullscreen==FULLSCREENOFF)
91 options.fullscreen=FULLSCREENON;
92
93
94 if (SDL_Init(SDL_INIT_VIDEO))
95 {
96 fprintf(stderr, "Hey. We're gonna need some graphics.\n"
97 "SDL error: "
98 "%s\n\n", SDL_GetError());
99 exit(1);
100 }
101
102
103 atexit(cleanup);
104
105
106 penguinicon = SDL_LoadBMP(DATAPREFIX "/" PENGUINICONFILE);
107 if (penguinicon==NULL) fprintf(stderr, "Icon not loaded!\n\n*** IceBreaker probably wasn't installed properly. ***\n\n");
108 SDL_WM_SetIcon(penguinicon,NULL);
109
110 if (options.fullscreen==FULLSCREENOFF)
111 {
112 // gotta do this right away or else we risk getting an ugly "SDL_App"
113 // in the titlebar for a few milliseconds -- can't have that!
114 SDL_WM_SetCaption("IceBreaker","IceBreaker");
115 screen = SDL_SetVideoMode(WIDTH, HEIGHT, VIDEODEPTH, SDL_SWSURFACE);
116
117 }
118 else
119 {
120 screen = NULL;
121 makefullscreen();
122 }
123
124 if (screen == NULL)
125 {
126 fprintf(stderr, "Help! Couldn't get a window.\n"
127 "SDL error: "
128 "%s\n\n", SDL_GetError());
129 exit(1);
130 }
131
132 initsound();
133
134 inittext();
135
136 initgrid();
137
138 initcursors();
139
140 if (strlen(commandline.theme)>0)
141 settheme(commandline.theme);
142 else
143 settheme(options.theme);
144
145 return newuser;
146 }
147
cleanup()148 void cleanup()
149 {
150 quitgrid();
151 quitsound();
152 quitcursors();
153 SDL_Quit();
154 writeoptions();
155 writedelayedhiscores();
156 }
157
158
159
main(int argc,char ** argv)160 int main(int argc,char** argv)
161 {
162 int done = false;
163 int level=0;
164 ScoreSheet levelscore;
165 long totalscore=0;
166 char windowtitle[35];
167 LevelExitType levelresult;
168 int newuser=false;
169 int rc=0;
170
171 #ifdef NEEDCHANGETOARGV0PATH
172 changetoargv0path(argv[0]);
173 #endif
174
175 rc=parsecommandline(argc,argv);
176 if (rc) return rc;
177
178 newuser=setup();
179
180 drawtitlebar("IceBreaker");
181
182 #if DEVELRELEASE
183 if (gameflags.benchmarkmode)
184 {
185 drawtitlebar("IceBreaker -- Benchmark mode");
186 rc=benchmark();
187 return rc;
188 }
189 #endif /* DEVELRELEASE */
190
191 done=intro();
192
193 if (!done && newuser)
194 { // no options file; using the default
195 setcursor(CURSORCLICK);
196 if (popuphelp()==POPUPQUITGAME) done=true;
197 setcursor(CURSORARROW);
198 }
199
200
201 while(!done)
202 {
203 level++;
204 if (level>=MAXPENGUINS) level=MAXPENGUINS-1;
205
206 switch (options.difficulty)
207 {
208 case NORMAL:
209 snprintf(windowtitle,35,"IceBreaker -- Level %d",level);
210 break;
211 case HARD:
212 snprintf(windowtitle,35,"IceBreaker -- Level %d (Hard)",level);
213 break;
214 case EASY:
215 snprintf(windowtitle,35,"IceBreaker -- Level %d (Easy)",level);
216 break;
217 }
218 drawtitlebar(windowtitle);
219
220 if (!strcmp(commandline.theme,"random") || (strlen(commandline.theme)==0 && !strcmp(options.theme,"random")))
221 settheme("random");
222
223 levelresult=playlevel(level,totalscore,&levelscore);
224
225 drawtitlebar("IceBreaker");
226
227 totalscore+= levelscore.basescore + levelscore.clearbonus + levelscore.lifebonus;
228
229 switch (levelresult)
230 {
231 case QUIT:
232 done=true;
233 break;
234 case DEAD:
235 done=gameover(totalscore);
236 // falls through
237 case ZERO:
238 // hooray! modifying the index variable in the loop!
239 // good coding practice at its finest!
240 level=0;
241 totalscore=0;
242 break;
243 case ERROR:
244 fprintf(stderr,"Level error -- this should never happen.\n");
245 break;
246 case PASS:
247 // level completed successfully
248 done=intermission(&levelscore,level+1);
249 break;
250 }
251
252 }
253
254 return rc;
255 }
256