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