rnd-20001203-5-src
[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 "libgame/libgame.h"
15
16 #include "main.h"
17 #include "init.h"
18 #include "game.h"
19 #include "events.h"
20 #include "joystick.h"
21
22 #if 0
23 #if defined(PLATFORM_MSDOS)
24 #include <fcntl.h>
25 #endif
26 #endif
27
28 #if 0
29 DrawWindow      window = None;
30 DrawBuffer      backbuffer;
31 GC              gc;
32 #endif
33
34 #if 0
35 GC              clip_gc[NUM_BITMAPS];
36 #endif
37 GC              tile_clip_gc;
38 Bitmap          pix[NUM_BITMAPS];
39 #if 0
40 Bitmap          pix_masked[NUM_BITMAPS];
41
42 Bitmap          tile_masked[NUM_TILES];
43
44 Pixmap          clipmask[NUM_BITMAPS];
45 #endif
46 Pixmap          tile_clipmask[NUM_TILES];
47
48 #if 0
49 DrawBuffer      drawto;
50 #endif
51
52 DrawBuffer      drawto_field, fieldbuffer;
53 #if 0
54 Colormap        cmap;
55 #endif
56
57 #if 0
58 char           *sound_device_name = AUDIO_DEVICE;
59 #endif
60
61 int             joystick_device = 0;
62 char           *joystick_device_name[MAX_PLAYERS] =
63 {
64   DEV_JOYSTICK_0,
65   DEV_JOYSTICK_1,
66   DEV_JOYSTICK_2,
67   DEV_JOYSTICK_3
68 };
69
70 #if 0
71 char           *program_name = NULL;
72 #endif
73
74 int             game_status = MAINMENU;
75 boolean         level_editor_test_game = FALSE;
76 boolean         network_playing = FALSE;
77
78 #if 0
79 int             button_status = MB_NOT_PRESSED;
80 boolean         motion_status = FALSE;
81 #endif
82
83 int             key_joystick_mapping = 0;
84 int             global_joystick_status = JOYSTICK_STATUS;
85 int             joystick_status = JOYSTICK_STATUS;
86
87 #if 0
88 boolean         fullscreen_available = FULLSCREEN_STATUS;
89 boolean         fullscreen_enabled = FALSE;
90 #endif
91
92 boolean         redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
93 int             redraw_x1 = 0, redraw_y1 = 0;
94
95 #if 0
96 int             redraw_mask;
97 int             redraw_tiles;
98 #endif
99
100 short           Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
101 short           Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
102 short           MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
103 short           MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
104 short           MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
105 short           Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
106 short           Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
107 short           StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
108 short           Frame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
109 boolean         Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
110 short           JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
111 short           AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
112 short           AmoebaCnt[MAX_NUM_AMOEBA], AmoebaCnt2[MAX_NUM_AMOEBA];
113 unsigned long   Elementeigenschaften1[MAX_ELEMENTS];
114 unsigned long   Elementeigenschaften2[MAX_ELEMENTS];
115
116 int             level_nr;
117 int             lev_fieldx,lev_fieldy, scroll_x,scroll_y;
118
119 int             FX = SX, FY = SY, ScrollStepSize;
120 int             ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0;
121 int             ScreenGfxPos = 0;
122 int             BorderElement = EL_BETON;
123 int             GameFrameDelay = GAME_FRAME_DELAY;
124 int             FfwdFrameDelay = FFWD_FRAME_DELAY;
125 int             BX1 = 0, BY1 = 0, BX2 = SCR_FIELDX-1, BY2 = SCR_FIELDY-1;
126 int             SBX_Left, SBX_Right;
127 int             SBY_Upper, SBY_Lower;
128 int             ZX,ZY, ExitX,ExitY;
129 int             AllPlayersGone;
130
131 #if 0
132 int             FrameCounter;
133 #endif
134
135 int             TimeFrames, TimePlayed, TimeLeft;
136
137 boolean         network_player_action_received = FALSE;
138
139 #if 0
140 struct LevelDirInfo    *leveldir_first = NULL, *leveldir_current = NULL;
141 #endif
142 struct LevelInfo        level;
143 struct PlayerInfo       stored_player[MAX_PLAYERS], *local_player = NULL;
144 struct HiScore          highscore[MAX_SCORE_ENTRIES];
145 #if 0
146 struct SampleInfo       Sound[NUM_SOUNDS];
147 #endif
148 struct TapeInfo         tape;
149
150 #if 0
151 struct OptionInfo       options;
152 #endif
153
154 struct SetupInfo        setup;
155 struct GameInfo         game;
156
157 #if 0
158 struct VideoSystemInfo  video;
159 struct AudioSystemInfo  audio;
160 #endif
161
162 struct GlobalInfo       global;
163
164 /* data needed for playing sounds */
165 char *sound_name[NUM_SOUNDS] =
166 {
167   "alchemy",
168   "amoebe",
169   "antigrav",
170   "autsch",
171   "blurb",
172   "bong",
173   "buing",
174   "chase",
175   "czardasz",
176   "deng",
177   "fuel",
178   "gong",
179   "halloffame",
180   "holz",
181   "hui",
182   "kabumm",
183   "kink",
184   "klapper",
185   "kling",
186   "klopf",
187   "klumpf",
188   "knack",
189   "knurk",
190   "krach",
191   "lachen",
192   "laser",
193   "miep",
194   "network",
195   "njam",
196   "oeffnen",
197   "pling",
198   "pong",
199   "pusch",
200   "quiek",
201   "quirk",
202   "rhythmloop",
203   "roaaar",
204   "roehr",
205   "rumms",
206   "schlopp",
207   "schlurf",
208   "schrff",
209   "schwirr",
210   "sirr",
211   "slurp",
212   "sproing",
213   "twilight",
214   "tyger",
215   "voyager",
216   "warnton",
217   "whoosh",
218   "zisch",
219   "base",
220   "infotron",
221   "zonkdown",
222   "zonkpush",
223   "bug",
224   "boom",
225   "booom",
226   "exit",
227   "empty",
228   "gate"
229 };
230
231 /* background music */
232 int background_loop[] =
233 {
234   SND_ALCHEMY,
235   SND_CHASE,
236   SND_NETWORK,
237   SND_CZARDASZ,
238   SND_TYGER,
239   SND_VOYAGER,
240   SND_TWILIGHT
241 };
242 int num_bg_loops = sizeof(background_loop)/sizeof(int);
243
244 char *element_info[] =
245 {
246   "empty space",                                /* 0 */
247   "sand",
248   "normal wall",
249   "round wall",
250   "rock",
251   "key",
252   "emerald",
253   "closed exit",
254   "player",
255   "bug",
256   "spaceship",                                  /* 10 */
257   "yam yam",
258   "robot",
259   "steel wall",
260   "diamond",
261   "dead amoeba",
262   "empty quicksand",
263   "quicksand with rock",
264   "amoeba drop",
265   "bomb",
266   "magic wall",                                 /* 20 */
267   "speed ball",
268   "acid pool",
269   "dropping amoeba",
270   "normal amoeba",
271   "nut with emerald",
272   "life wall",
273   "biomaze",
274   "burning dynamite",
275   "unknown",
276   "magic wheel",                                /* 30 */
277   "running wire",
278   "red key",
279   "yellow key",
280   "green key",
281   "blue key",
282   "red door",
283   "yellow door",
284   "green door",
285   "blue door",
286   "gray door (opened by red key)",              /* 40 */
287   "gray door (opened by yellow key)",
288   "gray door (opened by green key)",
289   "gray door (opened by blue key)",
290   "dynamite",
291   "pac man",
292   "invisible normal wall",
293   "light bulb (dark)",
294   "ligh bulb (glowing)",
295   "wall with emerald",
296   "wall with diamond",                          /* 50 */
297   "amoeba with content",
298   "amoeba (BD style)",
299   "time orb (full)",
300   "time orb (empty)",
301   "growing wall",
302   "diamond (BD style)",
303   "yellow emerald",
304   "wall with BD style diamond",
305   "wall with yellow emerald",
306   "dark yam yam",                               /* 60 */
307   "magic wall (BD style)",
308   "invisible steel wall",
309   "-",
310   "increases number of bombs",
311   "increases explosion size",
312   "increases power of explosion",
313   "sokoban object",
314   "sokoban empty field",
315   "sokoban field with object",
316   "butterfly (starts moving right)",            /* 70 */
317   "butterfly (starts moving up)",
318   "butterfly (starts moving left)",
319   "butterfly (starts moving down)",
320   "firefly (starts moving right)",
321   "firefly (starts moving up)",
322   "firefly (starts moving left)",
323   "firefly (starts moving down)",
324   "butterfly",
325   "firefly",
326   "yellow player",                              /* 80 */
327   "red player",
328   "green player",
329   "blue player",
330   "bug (starts moving right)",
331   "bug (starts moving up)",
332   "bug (starts moving left)",
333   "bug (starts moving down)",
334   "spaceship (starts moving right)",
335   "spaceship (starts moving up)",
336   "spaceship (starts moving left)",             /* 90 */
337   "spaceship (starts moving down)",
338   "pac man (starts moving right)",
339   "pac man (starts moving up)",
340   "pac man (starts moving left)",
341   "pac man (starts moving down)",
342   "red emerald",
343   "violet emerald",
344   "wall with red emerald",
345   "wall with violet emerald",
346   "unknown",                                    /* 100 */
347   "unknown",
348   "unknown",
349   "unknown",
350   "unknown",
351   "normal wall (BD style)",
352   "rock (BD style)",
353   "open exit",
354   "unknown",
355   "amoeba",
356   "mole",                                       /* 110 */
357   "penguin",
358   "satellite",
359   "arrow left",
360   "arrow right",
361   "arrow up",
362   "arrow down",
363   "pig",
364   "fire breathing dragon",
365   "unknown",
366   "letter ' '",                                 /* 120 */
367   "letter '!'",
368   "letter '\"'",
369   "letter '#'",
370   "letter '$'",
371   "letter '%'",
372   "letter '&'",
373   "letter '''",
374   "letter '('",
375   "letter ')'",
376   "letter '*'",                                 /* 130 */
377   "letter '+'",
378   "letter ','",
379   "letter '-'",
380   "letter '.'",
381   "letter '/'",
382   "letter '0'",
383   "letter '1'",
384   "letter '2'",
385   "letter '3'",
386   "letter '4'",                                 /* 140 */
387   "letter '5'",
388   "letter '6'",
389   "letter '7'",
390   "letter '8'",
391   "letter '9'",
392   "letter ':'",
393   "letter ';'",
394   "letter '<'",
395   "letter '='",
396   "letter '>'",                                 /* 150 */
397   "letter '?'",
398   "letter '@'",
399   "letter 'A'",
400   "letter 'B'",
401   "letter 'C'",
402   "letter 'D'",
403   "letter 'E'",
404   "letter 'F'",
405   "letter 'G'",
406   "letter 'H'",                                 /* 160 */
407   "letter 'I'",
408   "letter 'J'",
409   "letter 'K'",
410   "letter 'L'",
411   "letter 'M'",
412   "letter 'N'",
413   "letter 'O'",
414   "letter 'P'",
415   "letter 'Q'",
416   "letter 'R'",                                 /* 170 */
417   "letter 'S'",
418   "letter 'T'",
419   "letter 'U'",
420   "letter 'V'",
421   "letter 'W'",
422   "letter 'X'",
423   "letter 'Y'",
424   "letter 'Z'",
425   "letter 'Ä'",
426   "letter 'Ö'",                                 /* 180 */
427   "letter 'Ãœ'",
428   "letter '^'",
429   "letter ''",
430   "letter ''",
431   "letter ''",
432   "letter ''",
433   "letter ''",
434   "letter ''",
435   "letter ''",
436   "letter ''",                                  /* 190 */
437   "letter ''",
438   "letter ''",
439   "letter ''",
440   "letter ''",
441   "letter ''",
442   "letter ''",
443   "letter ''",
444   "letter ''",
445   "letter ''",
446   "growing wall (horizontal)",                  /* 200 */
447   "growing wall (vertical)",
448   "growing wall (all directions)",
449   "unused",
450   "unused",
451   "unused",
452   "unused",
453   "unused",
454   "unused",
455   "unused",
456   "empty space",                                /* 210 */
457   "zonk",
458   "base",
459   "murphy",
460   "infotron",
461   "chip (single)",
462   "hardware",
463   "exit",
464   "orange disk",
465   "port (leading right)",
466   "port (leading down)",                        /* 220 */
467   "port (leading left)",
468   "port (leading up)",
469   "port (leading right)",
470   "port (leading down)",
471   "port (leading left)",
472   "port (leading up)",
473   "snik snak",
474   "yellow disk",
475   "terminal",
476   "red disk",                                   /* 230 */
477   "port (vertical)",
478   "port (horizontal)",
479   "port (all directions)",
480   "electron",
481   "buggy base",
482   "chip (left half)",
483   "chip (right half)",
484   "hardware",
485   "hardware",
486   "hardware",                                   /* 240 */
487   "hardware",
488   "hardware",
489   "hardware",
490   "hardware",
491   "hardware",
492   "hardware",
493   "hardware",
494   "chip (upper half)",
495   "chip (lower half)",
496   "unknown",                                    /* 250 */
497   "unknown",
498   "unknown",
499   "unknown",
500   "unknown",
501   "unknown",
502
503   /* 256 */
504
505   "pearl",                                      /* (256) */
506   "crystal",
507   "wall with pearl",
508   "wall with crystal",
509   "white door",                                 /* 260 */
510   "gray door (opened by white key)",
511   "white key",
512   "shield (passive)",
513   "extra time",
514   "switch gate (open)",
515   "switch gate (closed)",
516   "switch for switch gate",
517   "switch for switch gate",
518   "-",
519   "-",                                          /* 270 */
520   "red conveyor belt (left)",
521   "red conveyor belt (middle)",
522   "red conveyor belt (right)",
523   "switch for red conveyor belt (left)",
524   "switch for red conveyor belt (middle)",
525   "switch for red conveyor belt (right)",
526   "yellow conveyor belt (left)",
527   "yellow conveyor belt (middle)",
528   "yellow conveyor belt (right)",
529   "switch for yellow conveyor belt (left)",     /* 280 */
530   "switch for yellow conveyor belt (middle)",
531   "switch for yellow conveyor belt (right)",
532   "green conveyor belt (left)",
533   "green conveyor belt (middle)",
534   "green conveyor belt (right)",
535   "switch for green conveyor belt (left)",
536   "switch for green conveyor belt (middle)",
537   "switch for green conveyor belt (right)",
538   "blue conveyor belt (left)",
539   "blue conveyor belt (middle)",                /* 290 */
540   "blue conveyor belt (right)",
541   "switch for blue conveyor belt (left)",
542   "switch for blue conveyor belt (middle)",
543   "switch for blue conveyor belt (right)",
544   "land mine",
545   "mail envelope",
546   "light switch (off)",
547   "light switch (on)",
548   "sign (exclamation)",
549   "sign (radio activity)",                      /* 300 */
550   "sign (stop)",
551   "sign (wheel chair)",
552   "sign (parking)",
553   "sign (one way)",
554   "sign (heart)",
555   "sign (triangle)",
556   "sign (round)",
557   "sign (exit)",
558   "sign (yin yang)",
559   "sign (other)",                               /* 310 */
560   "mole (starts moving left)",
561   "mole (starts moving right)",
562   "mole (starts moving up)",
563   "mole (starts moving down)",
564   "steel wall (slanted)",
565   "invisible sand",
566   "dx unknown 15",
567   "dx unknown 42",
568   "-",
569   "-",                                          /* 320 */
570   "shield (active, kills enemies)",
571   "time gate (open)",
572   "time gate (closed)",
573   "switch for time gate",
574   "switch for time gate",
575   "balloon",
576   "send balloon to the left",
577   "send balloon to the right",
578   "send balloon up",
579   "send balloon down",                          /* 330 */
580   "send balloon in any direction",
581   "steel wall",
582   "steel wall",
583   "steel wall",
584   "steel wall",
585   "normal wall",
586   "normal wall",
587   "normal wall",
588   "normal wall",
589   "normal wall",                                /* 340 */
590   "normal wall",
591   "normal wall",
592   "normal wall",
593   "tube (all directions)",
594   "tube (vertical)",
595   "tube (horizontal)",
596   "tube (vertical & left)",
597   "tube (vertical & right)",
598   "tube (horizontal & up)",
599   "tube (horizontal & down)",                   /* 350 */
600   "tube (left & up)",
601   "tube (left & down)",
602   "tube (right & up)",
603   "tube (right & down)",
604   "spring",
605   "trap",
606   "stable bomb (DX style)",
607   "-"
608
609   /*
610   "-------------------------------",
611   */
612 };
613 int num_element_info = sizeof(element_info)/sizeof(char *);
614
615
616
617 #if 0
618
619 /* +-----------------------------------------------------------------------+ */
620 /* | SDL TEST STUFF                                                        | */
621 /* +-----------------------------------------------------------------------+ */
622
623 #if defined(TARGET_SDL)
624
625 SDL_Surface *sdl_screen, *sdl_image_tmp, *sdl_image, *sdl_image_masked;
626 SDL_Surface *sdl_image2_tmp, *sdl_image2, *sdl_image2_masked;
627
628 void TEST_SDL_BLIT_RECT(int x, int y)
629 {
630   SDL_Rect rect_src, rect_dst;
631
632   SDLCopyArea(pix_masked[PIX_HEROES], window,
633               8 * TILEX, 8 * TILEY, TILEX, TILEY, x, y);
634   return;
635
636   rect_src.x = 8 * TILEX;
637   rect_src.y = 8 * TILEY;
638   rect_src.w = TILEX;
639   rect_src.h = TILEY;
640
641   rect_dst.x = x;
642   rect_dst.y = y;
643   rect_dst.w = TILEX;
644   rect_dst.h = TILEY;
645
646   SDL_BlitSurface(sdl_image2_masked, &rect_src, sdl_screen, &rect_dst);
647   SDL_UpdateRect(sdl_screen, x, y, TILEX, TILEY);
648 }
649
650 void TEST_SDL_INIT_DISPLAY()
651 {
652   SDL_Rect rect_src, rect_dst;
653
654   if (SDL_Init(SDL_INIT_VIDEO) < 0)
655   {
656     fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError());
657     exit(1);
658   }
659
660   /* automatically cleanup SDL stuff after exit() */
661   atexit(SDL_Quit);
662
663   if ((sdl_screen = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, 16, SDL_HWSURFACE))
664       == NULL)
665   {
666     fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
667     exit(1);
668   }
669
670   SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING);
671
672   if ((sdl_image_tmp = IMG_Load("graphics/RocksScreen.pcx")) == NULL)
673   {
674     fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
675     exit(1);
676   }
677
678   sdl_image = SDL_DisplayFormat(sdl_image_tmp);
679
680   SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY,
681                   SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
682   sdl_image_masked = SDL_DisplayFormat(sdl_image_tmp);
683
684   SDL_FreeSurface(sdl_image_tmp);
685
686   if ((sdl_image2_tmp = IMG_Load("graphics/RocksHeroes.pcx")) == NULL)
687   {
688     fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
689     exit(1);
690   }
691
692   sdl_image2 = SDL_DisplayFormat(sdl_image2_tmp);
693   SDL_FreeSurface(sdl_image2_tmp);
694
695   sdl_image2_masked = SDL_DisplayFormat(sdl_image2);
696   SDL_SetColorKey(sdl_image2_masked, SDL_SRCCOLORKEY,
697                   SDL_MapRGB(sdl_image2_masked->format, 0x00, 0x00, 0x00));
698
699   rect_src.x = 0;
700   rect_src.y = 0;
701   rect_src.w = sdl_image->w;
702   rect_src.h = sdl_image->h;
703
704   rect_dst.x = 0;
705   rect_dst.y = 0;
706   rect_dst.w = sdl_image->w;
707   rect_dst.h = sdl_image->h;
708                                            
709   SDL_BlitSurface(sdl_image, &rect_src, sdl_screen, &rect_dst);
710
711   /*
712   SDL_UpdateRect(sdl_screen, 0, 0, WIN_XSIZE, WIN_YSIZE);
713   */
714   /*
715   SDL_UpdateRect(sdl_screen, 0, 0, 0, 0);
716   */
717   SDL_Flip(sdl_screen);
718
719   /*
720   SDL_Delay(5000);
721   */
722 }
723
724 void TEST_SDL_EVENT_LOOP()
725 {
726   int quit_loop = 0;
727
728   SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
729
730   /*
731   while (!quit_loop && SDL_WaitEvent(&event) >=0)
732   */
733
734   while (!quit_loop)
735   {
736     SDL_Event event;
737
738     if (SDL_PollEvent(&event))
739     {
740       /* hier werden die Ereignisse behandelt */
741       switch(event.type)
742       {
743         case SDL_QUIT:
744         {
745           quit_loop = 1;
746           break;
747         }
748
749         case SDL_MOUSEBUTTONDOWN:
750         {
751           int x = event.button.x;
752           int y = event.button.y;
753
754           SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
755
756           TEST_SDL_BLIT_RECT(x, y);
757
758           printf("SDL_MOUSEBUTTONDOWN(%d, %d)\n", x, y);
759           break;
760         }
761
762         case SDL_MOUSEBUTTONUP:
763         {
764           int x = event.button.x;
765           int y = event.button.y;
766
767           SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
768
769           printf("SDL_MOUSEBUTTONUP(%d, %d)\n", x, y);
770           break;
771         }
772
773         case SDL_MOUSEMOTION:
774         {
775           int x = event.motion.x;
776           int y = event.motion.y;
777
778           TEST_SDL_BLIT_RECT(x, y);
779
780           printf("SDL_MOUSEMOTION(%d, %d)\n", x, y);
781           break;
782         }
783
784         default:
785           break;
786       }
787     }
788
789     if (!SDL_PollEvent(NULL))   /* delay only if no pending events */
790     {
791       printf("waiting...\n");
792       Delay(100);
793     }
794   }
795
796   SDL_FreeSurface(sdl_image);
797   SDL_Quit();
798 }
799
800 #define SCREEN_WIDTH    640
801 #define SCREEN_HEIGHT   480
802
803 void WatchJoysticks()
804 {
805         SDL_Surface *screen;
806         const char *name;
807         int i, done;
808         SDL_Event event;
809         int x, y, draw;
810         SDL_Rect axis_area[2];
811         int joystick_nr = 0;
812         SDL_Joystick *joystick = Get_SDL_Joystick(joystick_nr);
813
814         /* Set a video mode to display joystick axis position */
815         screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16, 0);
816         if ( screen == NULL ) {
817                 fprintf(stderr, "Couldn't set video mode: %s\n",SDL_GetError());
818                 return;
819         }
820
821         /* Print info about the joysticks we are watching */
822         for (i=0; i<2; i++)
823         {
824           joystick = Get_SDL_Joystick(i);
825
826           name = SDL_JoystickName(i);
827           printf("Watching joystick %d: (%s)\n", i,
828                  name ? name : "Unknown Joystick");
829           printf("Joystick has %d axes, %d hats, %d balls, and %d buttons\n",
830                  SDL_JoystickNumAxes(joystick),
831                  SDL_JoystickNumHats(joystick),
832                  SDL_JoystickNumBalls(joystick),
833                  SDL_JoystickNumButtons(joystick));
834         }
835
836         /* Initialize drawing rectangles */
837         memset(axis_area, 0, (sizeof axis_area));
838         draw = 0;
839
840         /* Loop, getting joystick events! */
841         done = 0;
842         while ( ! done ) {
843                 while ( SDL_PollEvent(&event) ) {
844                         switch (event.type) {
845                             case SDL_JOYAXISMOTION:
846                               joystick_nr = event.jaxis.which;
847                                 printf("Joystick %d axis %d value: %d\n",
848                                        event.jaxis.which,
849                                        event.jaxis.axis,
850                                        event.jaxis.value);
851                                 break;
852                             case SDL_JOYHATMOTION:
853                               joystick_nr = event.jaxis.which;
854                                 printf("Joystick %d hat %d value:",
855                                        event.jhat.which,
856                                        event.jhat.hat);
857                                 if ( event.jhat.value == SDL_HAT_CENTERED )
858                                         printf(" centered");
859                                 if ( event.jhat.value & SDL_HAT_UP )
860                                         printf(" up");
861                                 if ( event.jhat.value & SDL_HAT_RIGHT )
862                                         printf(" right");
863                                 if ( event.jhat.value & SDL_HAT_DOWN )
864                                         printf(" down");
865                                 if ( event.jhat.value & SDL_HAT_LEFT )
866                                         printf(" left");
867                                 printf("\n");
868                                 break;
869                             case SDL_JOYBALLMOTION:
870                               joystick_nr = event.jaxis.which;
871                                 printf("Joystick %d ball %d delta: (%d,%d)\n",
872                                        event.jball.which,
873                                        event.jball.ball,
874                                        event.jball.xrel,
875                                        event.jball.yrel);
876                                 break;
877                             case SDL_JOYBUTTONDOWN:
878                               joystick_nr = event.jaxis.which;
879                                 printf("Joystick %d button %d down\n",
880                                        event.jbutton.which,
881                                        event.jbutton.button);
882                                 break;
883                             case SDL_JOYBUTTONUP:
884                               joystick_nr = event.jaxis.which;
885                                 printf("Joystick %d button %d up\n",
886                                        event.jbutton.which,
887                                        event.jbutton.button);
888                                 break;
889                             case SDL_KEYDOWN:
890                                 if ( event.key.keysym.sym != SDLK_ESCAPE ) {
891                                         break;
892                                 }
893                                 /* Fall through to signal quit */
894                             case SDL_QUIT:
895                                 done = 1;
896                                 break;
897                             default:
898                                 break;
899                         }
900                 }
901
902                 joystick = Get_SDL_Joystick(joystick_nr);               
903
904                 /* Update visual joystick state */
905                 for ( i=0; i<SDL_JoystickNumButtons(joystick); ++i ) {
906                         SDL_Rect area;
907
908                         area.x = i*34;
909                         area.y = SCREEN_HEIGHT-34;
910                         area.w = 32;
911                         area.h = 32;
912                         if (SDL_JoystickGetButton(joystick, i) == SDL_PRESSED) {
913                                 SDL_FillRect(screen, &area, 0xFFFF);
914                         } else {
915                                 SDL_FillRect(screen, &area, 0x0000);
916                         }
917                         SDL_UpdateRects(screen, 1, &area);
918                 }
919
920                 /* Erase previous axes */
921                 SDL_FillRect(screen, &axis_area[draw], 0x0000);
922
923                 /* Draw the X/Y axis */
924                 draw = !draw;
925                 x = (((int)SDL_JoystickGetAxis(joystick, 0))+32768);
926                 x *= SCREEN_WIDTH;
927                 x /= 65535;
928                 if ( x < 0 ) {
929                         x = 0;
930                 } else
931                 if ( x > (SCREEN_WIDTH-16) ) {
932                         x = SCREEN_WIDTH-16;
933                 }
934                 y = (((int)SDL_JoystickGetAxis(joystick, 1))+32768);
935                 y *= SCREEN_HEIGHT;
936                 y /= 65535;
937                 if ( y < 0 ) {
938                         y = 0;
939                 } else
940                 if ( y > (SCREEN_HEIGHT-16) ) {
941                         y = SCREEN_HEIGHT-16;
942                 }
943                 axis_area[draw].x = (Sint16)x;
944                 axis_area[draw].y = (Sint16)y;
945                 axis_area[draw].w = 16;
946                 axis_area[draw].h = 16;
947                 SDL_FillRect(screen, &axis_area[draw], 0xFFFF);
948
949                 SDL_UpdateRects(screen, 2, axis_area);
950         }
951 }
952
953 void TEST_SDL_JOYSTICK()
954 {
955   const char *name;
956   int i;
957
958   /* Initialize SDL (Note: video is required to start event loop) */
959   if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 )
960   {
961     fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
962     exit(1);
963   }
964
965   /* Print information about the joysticks */
966   printf("There are %d joysticks attached\n", SDL_NumJoysticks());
967   for ( i=0; i<SDL_NumJoysticks(); ++i )
968   {
969     name = SDL_JoystickName(i);
970     printf("Joystick %d: %s\n",i,name ? name : "Unknown Joystick");
971   }
972
973   for (i=0; i<2; i++)
974   {
975     if (!Open_SDL_Joystick(i))
976       printf("Couldn't open joystick %d: %s\n", i, SDL_GetError());
977   }
978
979   WatchJoysticks();
980
981   for (i=0; i<2; i++)
982     Close_SDL_Joystick(i);
983
984   SDL_QuitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
985 }
986
987 #endif  /* TARGET_SDL */
988
989 /* +-----------------------------------------------------------------------+ */
990 /* | SDL TEST STUFF                                                        | */
991 /* +-----------------------------------------------------------------------+ */
992
993 #endif
994
995
996
997 int main(int argc, char *argv[])
998 {
999 #if 0
1000   program_name = (strrchr(argv[0],'/') ? strrchr(argv[0],'/') + 1 : argv[0]);
1001 #endif
1002
1003   InitCommandName(argv[0]);
1004   InitExitFunction(CloseAllAndExit);
1005   InitPlatformDependantStuff();
1006
1007 #if 0
1008 #if defined(PLATFORM_MSDOS)
1009   _fmode = O_BINARY;
1010 #endif
1011 #endif
1012
1013 #if 1
1014   GetOptions(argv);
1015   OpenAll();
1016 #endif
1017
1018 #if 0
1019 #ifdef TARGET_SDL
1020   /*
1021   TEST_SDL_BLIT_RECT((WIN_XSIZE - TILEX)/2, (WIN_YSIZE - TILEY)/2);
1022   TEST_SDL_EVENT_LOOP();
1023   */
1024   TEST_SDL_JOYSTICK();
1025   exit(0);
1026 #endif
1027 #endif
1028
1029   EventLoop();
1030   CloseAllAndExit(0);
1031   exit(0);      /* to keep compilers happy */
1032 }