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