rnd-19981002-1
[rocksndiamonds.git] / src / main.c
1 /***********************************************************
2 *  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
3 *----------------------------------------------------------*
4 *  (c) 1995-98 Artsoft Entertainment                       *
5 *              Holger Schemel                              *
6 *              Oststrasse 11a                              *
7 *              33604 Bielefeld                             *
8 *              phone: ++49 +521 290471                     *
9 *              email: aeglos@valinor.owl.de                *
10 *----------------------------------------------------------*
11 *  main.c                                                  *
12 ***********************************************************/
13
14 #include "main.h"
15 #include "init.h"
16 #include "game.h"
17 #include "events.h"
18 #include "sound.h"
19 #include "joystick.h"
20 #include "misc.h"
21
22 #ifdef MSDOS
23 #include <fcntl.h>
24 #endif
25
26 Display        *display;
27 Visual         *visual;
28 int             screen;
29 Window          window;
30 GC              gc, clip_gc[NUM_PIXMAPS], tile_clip_gc;
31 Pixmap          pix[NUM_PIXMAPS];
32 Pixmap          clipmask[NUM_PIXMAPS], tile_clipmask[NUM_TILES];
33
34 #ifdef XPM_INCLUDE_FILE
35 XpmAttributes   xpm_att[NUM_PICTURES];
36 #endif
37
38 Drawable        drawto, drawto_field, backbuffer, fieldbuffer;
39 Colormap        cmap;
40
41 int             sound_pipe[2];
42 int             sound_device;
43 char           *sound_device_name = SOUND_DEVICE;
44 int             joystick_device = 0;
45 char           *joystick_device_name[2] = { DEV_JOYSTICK_0, DEV_JOYSTICK_1 };
46 char           *level_directory = LEVEL_PATH;
47 int             width, height;
48
49 char           *display_name = NULL;
50 char           *server_host = NULL;
51 int             server_port = 0;
52 int             networking = FALSE;
53 int             standalone = TRUE;
54 int             verbose = FALSE;
55
56 int             game_status = MAINMENU;
57 int             game_emulation = EMU_NONE;
58 int             button_status = MB_NOT_PRESSED, motion_status = FALSE;
59 int             key_joystick_mapping = 0;
60 int             global_joystick_status = JOYSTICK_STATUS;
61 int             joystick_status = JOYSTICK_STATUS;
62 int             sound_status = SOUND_STATUS, sound_on = TRUE;
63 int             sound_loops_allowed = FALSE, sound_loops_on = FALSE;
64 int             sound_music_on = FALSE;
65 int             sound_simple_on = FALSE;
66 int             toons_on = TRUE;
67 int             direct_draw_on = FALSE;
68 int             scroll_delay_on = FALSE;
69 int             soft_scrolling_on = TRUE;
70 int             fading_on = FALSE;
71 int             autorecord_on = FALSE;
72 int             joystick_nr = 0;
73 int             quick_doors = FALSE;
74
75 BOOL            redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
76 int             redraw_x1 = 0, redraw_y1 = 0;
77 int             redraw_mask;
78 int             redraw_tiles;
79
80 int             Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
81 int             Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
82 int             MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
83 int             MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
84 int             MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
85 int             Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
86 int             Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
87 int             StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
88 int             Frame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
89 int             Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
90 int             JustHit[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
91 int             AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
92 int             AmoebaCnt[MAX_NUM_AMOEBA], AmoebaCnt2[MAX_NUM_AMOEBA];
93 long            Elementeigenschaften[MAX_ELEMENTS];
94
95 int             level_nr, leveldir_nr, num_leveldirs;
96 int             lev_fieldx,lev_fieldy, scroll_x,scroll_y;
97
98 int             FX = SX, FY = SY, ScrollStepSize = TILEX/8;
99 int             ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0;
100 int             ScreenGfxPos = 0;
101 int             GameFrameDelay = GAME_FRAME_DELAY, MoveSpeed = 8;
102 int             BX1 = 0, BY1 = 0, BX2 = SCR_FIELDX-1, BY2 = SCR_FIELDY-1;
103 int             ZX,ZY, ExitX,ExitY;
104 int             AllPlayersGone;
105 int             FrameCounter, TimeFrames, TimeLeft;
106 int             MampferNr, SiebAktiv;
107
108 int             TestPlayer = 0;
109
110 struct LevelDirInfo     leveldir[MAX_LEVDIR_ENTRIES];
111 struct LevelInfo        level;
112 struct PlayerInfo       stored_player[MAX_PLAYERS+1];
113 struct PlayerInfo      *local_player;
114 struct HiScore          highscore[MAX_SCORE_ENTRIES];
115 struct SoundInfo        Sound[NUM_SOUNDS];
116 struct RecordingInfo    tape;
117
118 struct JoystickInfo joystick[2] =
119 {
120   { JOYSTICK_XLEFT, JOYSTICK_XRIGHT, JOYSTICK_XMIDDLE,
121     JOYSTICK_YUPPER, JOYSTICK_YLOWER, JOYSTICK_YMIDDLE },
122   { JOYSTICK_XLEFT, JOYSTICK_XRIGHT, JOYSTICK_XMIDDLE,
123     JOYSTICK_YUPPER, JOYSTICK_YLOWER, JOYSTICK_YMIDDLE }
124 };
125
126 /* data needed for playing sounds */
127 char *sound_name[NUM_SOUNDS] =
128 {
129   "alchemy",
130   "amoebe",
131   "antigrav",
132   "autsch",
133   "blurb",
134   "bong",
135   "buing",
136   "chase",
137   "czardasz",
138   "deng",
139   "fuel",
140   "gong",
141   "halloffame",
142   "holz",
143   "hui",
144   "kabumm",
145   "kink",
146   "klapper",
147   "kling",
148   "klopf",
149   "klumpf",
150   "knack",
151   "knurk",
152   "krach",
153   "lachen",
154   "laser",
155   "miep",
156   "network",
157   "njam",
158   "oeffnen",
159   "pling",
160   "pong",
161   "pusch",
162   "quiek",
163   "quirk",
164   "rhythmloop",
165   "roaaar",
166   "roehr",
167   "rumms",
168   "schlopp",
169   "schlurf",
170   "schrff",
171   "schwirr",
172   "sirr",
173   "slurp",
174   "sproing",
175   "twilight",
176   "tyger",
177   "voyager",
178   "warnton",
179   "whoosh",
180   "zisch"
181 };
182
183 /* background music */
184 int background_loop[] =
185 {
186   SND_ALCHEMY,
187   SND_CHASE,
188   SND_NETWORK,
189   SND_CZARDASZ,
190   SND_TYGER,
191   SND_VOYAGER,
192   SND_TWILIGHT
193 };
194 int num_bg_loops = sizeof(background_loop)/sizeof(int);
195
196 char            *program_name;
197
198 #define MAX_OPTION_LEN  1024
199
200 static void fatal_option()
201 {
202   fprintf(stderr,"Try '%s --help' for more information.\n",
203           program_name);
204   exit(1);
205 }
206
207 static void fatal_unrecognized_option(char *option)
208 {
209   fprintf(stderr,"%s: unrecognized option '%s'\n",
210           program_name, option);
211   fatal_option();
212 }
213
214 static void fatal_option_requires_argument(char *option)
215 {
216   fprintf(stderr,"%s: option '%s' requires an argument\n",
217           program_name, option);
218   fatal_option();
219 }
220
221 static void fatal_invalid_option_argument(char *option)
222 {
223   fprintf(stderr,"%s: option '%s' has invalid argument\n",
224           program_name, option);
225   fatal_option();
226 }
227
228 static void fatal_too_many_arguments()
229 {
230   fprintf(stderr,"%s: too many arguments\n",
231           program_name);
232   fatal_option();
233 }
234
235 extern void fatal(char *);
236
237 int main(int argc, char *argv[])
238 {
239   char **options_left = &argv[1];
240
241   program_name = (strrchr(argv[0],'/') ? strrchr(argv[0],'/') + 1 : argv[0]);
242
243   while (*options_left)
244   {
245     char option_str[MAX_OPTION_LEN];
246     char *option = options_left[0];
247     char *next_option = options_left[1];
248     char *option_arg = NULL;
249     int option_len = strlen(option);
250
251     strcpy(option_str, option);                 /* copy argument into buffer */
252     option = option_str;
253
254     if (strcmp(option, "--") == 0)              /* stop scanning arguments */
255       break;
256
257     if (option_len >= MAX_OPTION_LEN)
258       fatal_unrecognized_option(option);
259
260     if (strncmp(option, "--", 2) == 0)          /* treat '--' like '-' */
261       option++;
262
263     option_arg = strchr(option, '=');
264     if (option_arg == NULL)                     /* no '=' in option */
265       option_arg = next_option;
266     else
267     {
268       *option_arg++ = '\0';                     /* cut argument from option */
269       if (*option_arg == '\0')                  /* no argument after '=' */
270         fatal_invalid_option_argument(option);
271     }
272
273     option_len = strlen(option);
274
275     if (strcmp(option, "-") == 0)
276       fatal_unrecognized_option(option);
277     else if (strncmp(option, "-help", option_len) == 0)
278     {
279       printf("Usage: %s [options] [server.name [port]]\n"
280              "Options:\n"
281              "  -d, --display machine:0       X server display\n"
282              "  -l, --levels directory        alternative level directory\n"
283              "  -v, --verbose                 verbose mode\n",
284              program_name);
285       exit(0);
286     }
287     else if (strncmp(option, "-display", option_len) == 0)
288     {
289       if (option_arg == NULL)
290         fatal_option_requires_argument(option_str);
291
292       display_name = option_arg;
293       if (option_arg == next_option)
294         options_left++;
295
296       printf("--display == '%s'\n", display_name);
297     }
298     else if (strncmp(option, "-levels", option_len) == 0)
299     {
300       if (option_arg == NULL)
301         fatal_option_requires_argument(option_str);
302
303       level_directory = option_arg;
304       if (option_arg == next_option)
305         options_left++;
306
307       printf("--levels == '%s'\n", level_directory);
308     }
309     else if (strncmp(option, "-verbose", option_len) == 0)
310     {
311       printf("--verbose\n");
312
313       verbose = TRUE;
314     }
315     else if (*option == '-')
316       fatal_unrecognized_option(option_str);
317     else if (server_host == NULL)
318     {
319       server_host = *options_left;
320
321       printf("server.name == '%s'\n", server_host);
322     }
323     else if (server_port == 0)
324     {
325       server_port = atoi(*options_left);
326       if (server_port < 1024)
327         fatal("Bad port number");
328
329       printf("port == %d\n", server_port);
330     }
331     else
332       fatal_too_many_arguments();
333
334     options_left++;
335   }
336
337   /*
338   printf("All went fine -- exiting\n");
339   exit(0);
340   */
341
342   /*
343   if (argc>1)
344     level_directory = argv[1];
345     */
346
347
348     /*
349   if (argc > 1)
350     server_host = argv[1];
351
352   if (argc > 2)
353     server_port = atoi(argv[2]);
354     */
355
356
357 #ifdef MSDOS
358   _fmode = O_BINARY;
359 #endif
360
361   OpenAll(argc,argv);
362   EventLoop();
363   CloseAll();
364
365   exit(0);
366 }