1 /* xsoldier, a shoot 'em up game with "not shooting" bonus
2  * Copyright (C) 1997 Yuusuke HASHIMOTO <s945750@educ.info.kanagawa-u.ac.jp>
3  * Copyright (C) 2002 Oohara Yuuma  <oohara@libra.interq.or.jp>
4  *
5  * This is a copyleft program.  See the file LICENSE for details.
6  */
7 /* $Id: main.c,v 1.31 2006/09/16 09:20:54 oohara Exp $ */
8 
9 /* DEBUG and JSTK are defined in config.h */
10 #include <config.h>
11 /* time */
12 #include <time.h>
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <unistd.h>
18 #include <signal.h>
19 #include <sys/time.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <X11/Xlib.h>
24 #include <X11/Xutil.h>
25 #include <X11/keysym.h>
26 
27 #include "xsoldier.h"
28 #include "manage.h"
29 #include "opening.h"
30 #include "game.h"
31 #include "ending.h"
32 #include "player.h"
33 /* DeleteAllStar */
34 #include "star.h"
35 #include "score.h"
36 #include "graphic.h"
37 #include "input.h"
38 
39 /* define all "extern" here */
40 #define EXTERN_DEF
41 #include "extern.h"
42 
43 /* local functions */
44 static void arginit(int argc, char *argv[]);
45 static void usage(void);
46 
47 static void init(void);
48 static void clean(void);
49 static void sig_handle(int arg);
50 
51 /* file-global variables */
52 static char command[32];
53 static int scoreOK = True;
54 static int putscore = False;
55 static int w_time = -1;
56 
57 static int maxlevel_temp = False;
58 static int start_stage = 1;
59 static int start_loop = 1;
60 static int start_ship = 5;
61 static int maxpower_temp = False;
62 static int nopausemessage_temp = False;
63 
main(int argc,char * argv[])64 int main(int argc, char *argv[])
65 {
66   display[0] = '\0';
67   manage = NULL;
68 
69     arginit(argc,argv);
70 
71     player = NewPlayerData();
72     if (putscore == True)
73     {
74 	int i;
75 	printf("      --- top 10 soldiers ---\n");
76 	printf("Name                 Stage Score\n");
77 	for (i=1; i<=10; i++)
78 	    printf("%-20.20s %2d-%2d %8d\n",
79 		   player->Rec[i].name,
80 		   player->Rec[i].loop,player->Rec[i].stage,
81 		   player->Rec[i].score);
82 
83 	exit(0);
84     }
85     if (scoreOK == False)
86 	fprintf(stderr,"caution: no ranking mode!\n");
87 
88     init();
89     manage = NewManage(256,256);
90     if (maxlevel_temp == True)
91       manage->flag_maxlevel = True;
92     if (maxpower_temp == True)
93       manage->start_power = 30;
94     else
95       manage->start_power = 0;
96 
97     if (nopausemessage_temp == True)
98       manage->flag_nopausemessage = True;
99 
100 #ifndef HAVE_LIBSDL
101     XMapWindow(dpy,win);
102     XMapWindow(dpy,root);
103 
104     XFlush(dpy);
105 #endif /* not HAVE_LIBSDL */
106 
107     while (!(manage->program_should_quit))
108     {
109 	keymask = 0;
110 
111 	player->Rec[0].score = 0;
112 	player->Ships = start_ship;
113 	player->Next = FIRST1UP;
114 	manage->Loop = start_loop;
115         manage->Stage = start_stage;
116 
117 	if (Opening() == -1)
118 	    break;
119 
120 	while (1)
121 	{
122 	    keymask = 0;
123 	    ResetManage(manage);
124 
125 	    if (mainLoop() == 0)
126               /* game over */
127 		break;
128 	    Ending();
129 	    manage->Loop++;
130             manage->Stage = 1;
131             if (manage->Loop >3)
132               break;
133 	}
134 
135 	if (scoreOK == True)
136 	{
137 	    if (MergeHiscore(player) > 0)
138 		WriteHiscore(player);
139 	}
140     }
141 
142     DeleteManage(manage);
143     free(player);
144     clean();
145     return 0;
146 }
147 
arginit(int argc,char * argv[])148 static void arginit(int argc, char *argv[])
149 {
150     char *argv0;
151     int i;
152     int a;
153 #ifdef DEBUG
154     int b;
155 #endif /* DEBUG */
156 
157     if ((argv0=strrchr(argv[0],'/')) != NULL)
158         argv0++;
159     else
160         argv0 = argv[0];
161     /* copy command name */
162     strncpy(command,argv0, sizeof(command)-1);
163 
164     for (i=1; i<argc; i++)
165     {
166 	if ((strcmp(argv[i],"-display")==0) || (strcmp(argv[i],"-d")==0))
167 	{
168 	    if (i < argc-1)
169             {
170               strncpy(display,argv[i + 1],sizeof(display));
171               if (display[sizeof(display) - 1] != '\0')
172               {
173                 fprintf(stderr, "warning: display name (arg %d) is too long, ",
174                         i + 1);
175                 display[sizeof(display) - 1] = '\0';
176                 fprintf(stderr, "truncated to %d chars\n",
177                         (int)sizeof(display) - 1);
178               }
179               i++;
180             }
181             else
182             {
183               fprintf(stderr, "no display specified for -display (arg %d)\n",
184                       i);
185               exit(1);
186             }
187 	}
188         else if ((strcmp(argv[i],"-wait")==0) || (strcmp(argv[i],"-w")==0))
189 	{
190 	    if (i < argc-1)
191 	    {
192               if ((sscanf(argv[i+1], "%d", &a) == 1) && (a >= 1))
193               {
194                 w_time = a;
195                 if (w_time > WAIT)
196                   scoreOK = False;
197                 i++;
198               }
199               else
200               {
201                 fprintf(stderr, "wait (arg %d) must be a positive integer.\n",
202                         i + 1);
203                 exit(1);
204               }
205             }
206             else
207             {
208               fprintf(stderr, "no wait specified for -wait (arg %d)\n", i);
209               exit(1);
210             }
211 	}
212         else if ((strcmp(argv[i],"-cmap")==0) || (strcmp(argv[i],"-c")==0))
213         {
214           /* ignore */
215           ;
216 	}
217         else if ((strcmp(argv[i],"-score")==0) || (strcmp(argv[i],"-s")==0))
218 	    putscore = True;
219         else if ((strcmp(argv[i],"-help")==0) || (strcmp(argv[i],"-h")==0))
220             usage();
221         else if (strcmp(argv[i],"-maxlevel")==0)
222 	    maxlevel_temp = True;
223         else if (strcmp(argv[i],"-nopausemessage")==0)
224 	    nopausemessage_temp = True;
225 #ifdef DEBUG
226         else if (strcmp(argv[i],"-stage") == 0)
227         {
228           if (i + 1 < argc)
229           {
230             if (sscanf(argv[i+1], "%d-%d", &a, &b) == 2)
231             {
232               if ((a < 1) || (a > 3))
233               {
234                 fprintf(stderr, "the loop number (arg %d) must be between "
235                         "1 and 3\n", i + 1);
236                 exit(1);
237               }
238               else if ((b < 1) || (b > 8))
239               {
240                 fprintf(stderr, "the stage number (arg %d) must be between "
241                         "1 and 8\n", i + 1);
242                 exit(1);
243               }
244               else
245               {
246                 scoreOK = False;
247                 start_loop = a;
248                 start_stage = b;
249                 i++;
250               }
251             }
252             else if (sscanf(argv[i+1], "%d", &b) == 1)
253             {
254               if ((b >= 1) && (b <= 8))
255               {
256                 scoreOK = False;
257                 start_stage = b;
258                 i++;
259               }
260               else
261               {
262                 fprintf(stderr, "the stage number (arg %d) must be between "
263                         "1 and 8\n", i + 1);
264                 exit(1);
265               }
266             }
267             else
268             {
269               fprintf(stderr, "strange stage number (arg %d) for -stage\n",
270                       i + 1);
271               exit(1);
272             }
273           }
274           else
275           {
276             fprintf(stderr, "missing stage number for -stage (arg %d)\n", i);
277             exit(1);
278           }
279         }
280         else if (strcmp(argv[i],"-loop") == 0)
281         {
282           if (i + 1 < argc)
283           {
284             if (sscanf(argv[i+1], "%d", &a) == 1)
285             {
286               if ((a >= 1) && (a <= 3))
287               {
288                 scoreOK = False;
289                 start_loop = a;
290                 i++;
291               }
292               else
293               {
294                 fprintf(stderr, "loop number (arg %d) must be between "
295                         "1 and 3\n", i + 1);
296                 exit(1);
297               }
298             }
299             else
300             {
301               fprintf(stderr, "strange loop number (arg %d) for -loop\n",
302                       i + 1);
303               exit(1);
304             }
305           }
306           else
307           {
308             fprintf(stderr, "missing loop number for -loop (arg %d)\n", i);
309             exit(1);
310           }
311         }
312         else if (strcmp(argv[i],"-ship") == 0)
313         {
314           if (i + 1 < argc)
315           {
316             if (sscanf(argv[i+1], "%d", &a) == 1)
317             {
318               if ((a >= 0) && (a <= 99))
319               {
320                 scoreOK = False;
321                 start_ship = a;
322                 i++;
323               }
324               else
325               {
326                 fprintf(stderr, "ship number (arg %d) must be between "
327                         "0 and 99\n", i + 1);
328                 exit(1);
329               }
330             }
331             else
332             {
333               fprintf(stderr, "strange ship number (arg %d) for -ship\n",
334                       i + 1);
335               exit(1);
336             }
337           }
338           else
339           {
340             fprintf(stderr, "missing ship number for -ship (arg %d)\n", i);
341             exit(1);
342           }
343         }
344         else if (strcmp(argv[i],"-maxpower")==0)
345         {
346           scoreOK = False;
347           maxpower_temp = True;
348         }
349 #endif /* DEBUG */
350         else
351         {
352           fprintf(stderr, "strange option (arg %d)\n", i);
353           exit(1);
354         }
355     }
356 }
357 
usage(void)358 static void usage(void)
359 {
360     fprintf(stderr,"Usage: %s [-display <name>] [-wait <n>] [-score] [-help] [-maxlevel]",command);
361 #ifdef DEBUG
362     fprintf(stderr, "[-stage <L-S>] [-stage <S>] [-loop <L>] [-ship <N>] [maxpower]");
363 #endif /* DEBUG*/
364     fprintf(stderr, "\n");
365 
366     fprintf(stderr,"\t display <name>   ... name of the X server to play game.\n");
367     fprintf(stderr,"\t wait <n>         ... set wait time. (no ranking) <default is %d>\n",WAIT);
368     fprintf(stderr,"\t score            ... print top 10 soldiers.\n");
369     fprintf(stderr,"\t help             ... this message.\n");
370     fprintf(stderr,"\t maxlevel         ... force max level enemy attack.\n");
371 #ifdef DEBUG
372     fprintf(stderr,"debug-only options\n");
373     fprintf(stderr,"\t stage <L-S>      ... start stage S [1-8] of loop L [1-3]. (no ranking)\n");
374     fprintf(stderr,"\t stage <S>        ... start stage S [1-8]. (no ranking)\n");
375     fprintf(stderr,"\t loop <L>         ... start loop L [1-3]. (no ranking)\n");
376     fprintf(stderr,"\t ship <n>         ... start with n [0-99] ships. (no ranking)\n");
377     fprintf(stderr,"\t maxpower         ... start with max power. (no ranking)\n");
378 #endif /* DEBUG */
379     exit(0);
380 }
381 
init(void)382 static void init(void)
383 {
384     struct itimerval value, ovalue;
385     struct sigaction sig_act;
386 
387     /* set wait */
388     signal_delivered = 1;
389     if (w_time < 0)
390 	waittime = WAIT;
391     else
392 	waittime = w_time;
393 
394     memset(&sig_act, 0, sizeof(sig_act));
395     sig_act.sa_handler = sig_handle;
396     sigaction(SIGALRM, &sig_act, 0);
397     value.it_interval.tv_sec = 0;
398     value.it_interval.tv_usec = waittime;
399     value.it_value.tv_sec = 0;
400     value.it_value.tv_usec = waittime;
401     setitimer(ITIMER_REAL, &value, &ovalue);
402 
403     FieldW  = 500;
404     FieldH  = 650;
405 
406     /* you must call graphic_init() first because it calls SDL_Init */
407     graphic_init();
408     input_init();
409 
410     srand((unsigned)time(NULL));
411 }
412 
clean(void)413 static void clean(void)
414 {
415     graphic_finish();
416 }
417 
sig_handle(int arg)418 static void sig_handle(int arg)
419 {
420     signal_delivered = 1;
421 }
422