1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-98 Artsoft Entertainment *
8 * phone: ++49 +521 290471 *
9 * email: aeglos@valinor.owl.de *
10 *----------------------------------------------------------*
12 ***********************************************************/
29 DrawWindow window = None;
30 GC gc, clip_gc[NUM_BITMAPS], tile_clip_gc;
31 Bitmap pix[NUM_BITMAPS];
32 Bitmap pix_masked[NUM_BITMAPS], tile_masked[NUM_TILES];
33 Pixmap clipmask[NUM_BITMAPS], tile_clipmask[NUM_TILES];
35 #ifdef USE_XPM_LIBRARY
36 XpmAttributes xpm_att[NUM_PICTURES];
39 DrawBuffer drawto, drawto_field, backbuffer, fieldbuffer;
44 char *sound_device_name = SOUND_DEVICE;
45 int joystick_device = 0;
46 char *joystick_device_name[MAX_PLAYERS] =
54 char *program_name = NULL;
56 int game_status = MAINMENU;
57 boolean level_editor_test_game = FALSE;
58 boolean network_playing = FALSE;
59 int button_status = MB_NOT_PRESSED;
60 boolean motion_status = FALSE;
61 int key_joystick_mapping = 0;
62 int global_joystick_status = JOYSTICK_STATUS;
63 int joystick_status = JOYSTICK_STATUS;
64 int sound_status = SOUND_STATUS;
65 boolean sound_loops_allowed = FALSE;
66 boolean fullscreen_available = FULLSCREEN_STATUS;
67 boolean fullscreen_enabled = FALSE;
69 boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
70 int redraw_x1 = 0, redraw_y1 = 0;
74 short Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
75 short Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
76 short MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
77 short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
78 short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
79 short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
80 short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
81 short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
82 short Frame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
83 boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
84 short JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
85 short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
86 short AmoebaCnt[MAX_NUM_AMOEBA], AmoebaCnt2[MAX_NUM_AMOEBA];
87 unsigned long Elementeigenschaften1[MAX_ELEMENTS];
88 unsigned long Elementeigenschaften2[MAX_ELEMENTS];
91 int lev_fieldx,lev_fieldy, scroll_x,scroll_y;
93 int FX = SX, FY = SY, ScrollStepSize;
94 int ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0;
96 int BorderElement = EL_BETON;
97 int GameFrameDelay = GAME_FRAME_DELAY;
98 int FfwdFrameDelay = FFWD_FRAME_DELAY;
99 int BX1 = 0, BY1 = 0, BX2 = SCR_FIELDX-1, BY2 = SCR_FIELDY-1;
100 int SBX_Left, SBX_Right;
101 int SBY_Upper, SBY_Lower;
102 int ZX,ZY, ExitX,ExitY;
104 int FrameCounter, TimeFrames, TimePlayed, TimeLeft;
106 boolean network_player_action_received = FALSE;
108 struct LevelDirInfo *leveldir_first = NULL, *leveldir_current = NULL;
109 struct LevelInfo level;
110 struct PlayerInfo stored_player[MAX_PLAYERS], *local_player = NULL;
111 struct HiScore highscore[MAX_SCORE_ENTRIES];
112 struct SoundInfo Sound[NUM_SOUNDS];
113 struct TapeInfo tape;
114 struct OptionInfo options;
115 struct SetupInfo setup;
116 struct GameInfo game;
117 struct GlobalInfo global;
119 /* data needed for playing sounds */
120 char *sound_name[NUM_SOUNDS] =
186 /* background music */
187 int background_loop[] =
197 int num_bg_loops = sizeof(background_loop)/sizeof(int);
199 char *element_info[] =
201 "empty space", /* 0 */
211 "spaceship", /* 10 */
218 "quicksand with rock",
221 "magic wall", /* 20 */
231 "magic wheel", /* 30 */
241 "gray door (opened by red key)", /* 40 */
242 "gray door (opened by yellow key)",
243 "gray door (opened by green key)",
244 "gray door (opened by blue key)",
247 "invisible normal wall",
249 "ligh bulb (glowing)",
251 "wall with diamond", /* 50 */
252 "amoeba with content",
257 "diamond (BD style)",
259 "wall with BD style diamond",
260 "wall with yellow emerald",
261 "dark yam yam", /* 60 */
262 "magic wall (BD style)",
263 "invisible steel wall",
265 "increases number of bombs",
266 "increases explosion size",
267 "increases power of explosion",
269 "sokoban empty field",
270 "sokoban field with object",
271 "butterfly (starts moving right)", /* 70 */
272 "butterfly (starts moving up)",
273 "butterfly (starts moving left)",
274 "butterfly (starts moving down)",
275 "firefly (starts moving right)",
276 "firefly (starts moving up)",
277 "firefly (starts moving left)",
278 "firefly (starts moving down)",
281 "yellow player", /* 80 */
285 "bug (starts moving right)",
286 "bug (starts moving up)",
287 "bug (starts moving left)",
288 "bug (starts moving down)",
289 "spaceship (starts moving right)",
290 "spaceship (starts moving up)",
291 "spaceship (starts moving left)", /* 90 */
292 "spaceship (starts moving down)",
293 "pac man (starts moving right)",
294 "pac man (starts moving up)",
295 "pac man (starts moving left)",
296 "pac man (starts moving down)",
299 "wall with red emerald",
300 "wall with violet emerald",
306 "normal wall (BD style)",
319 "fire breathing dragon",
321 "letter ' '", /* 120 */
331 "letter '*'", /* 130 */
341 "letter '4'", /* 140 */
351 "letter '>'", /* 150 */
361 "letter 'H'", /* 160 */
371 "letter 'R'", /* 170 */
381 "letter 'Ö'", /* 180 */
391 "letter ''", /* 190 */
401 "growing wall (horizontal)", /* 200 */
402 "growing wall (vertical)",
403 "growing wall (all directions)",
411 "empty space", /* 210 */
420 "port (leading right)",
421 "port (leading down)", /* 220 */
422 "port (leading left)",
424 "port (leading right)",
425 "port (leading down)",
426 "port (leading left)",
431 "red disk", /* 230 */
434 "port (all directions)",
441 "hardware", /* 240 */
464 "white door", /* 260 */
465 "gray door (opened by white key)",
469 "switch gate (open)",
470 "switch gate (closed)",
471 "switch for switch gate",
472 "switch for switch gate",
475 "red conveyor belt (left)",
476 "red conveyor belt (middle)",
477 "red conveyor belt (right)",
478 "switch for red conveyor belt (left)",
479 "switch for red conveyor belt (middle)",
480 "switch for red conveyor belt (right)",
481 "yellow conveyor belt (left)",
482 "yellow conveyor belt (middle)",
483 "yellow conveyor belt (right)",
484 "switch for yellow conveyor belt (left)", /* 280 */
485 "switch for yellow conveyor belt (middle)",
486 "switch for yellow conveyor belt (right)",
487 "green conveyor belt (left)",
488 "green conveyor belt (middle)",
489 "green conveyor belt (right)",
490 "switch for green conveyor belt (left)",
491 "switch for green conveyor belt (middle)",
492 "switch for green conveyor belt (right)",
493 "blue conveyor belt (left)",
494 "blue conveyor belt (middle)", /* 290 */
495 "blue conveyor belt (right)",
496 "switch for blue conveyor belt (left)",
497 "switch for blue conveyor belt (middle)",
498 "switch for blue conveyor belt (right)",
501 "light switch (off)",
503 "sign (exclamation)",
504 "sign (radio activity)", /* 300 */
506 "sign (wheel chair)",
514 "sign (other)", /* 310 */
515 "mole (starts moving left)",
516 "mole (starts moving right)",
517 "mole (starts moving up)",
518 "mole (starts moving down)",
519 "steel wall (slanted)",
525 "shield (active, kills enemies)",
527 "time gate (closed)",
528 "switch for time gate",
529 "switch for time gate",
531 "send balloon to the left",
532 "send balloon to the right",
534 "send balloon down", /* 330 */
535 "send balloon in any direction",
544 "normal wall", /* 340 */
548 "tube (all directions)",
551 "tube (vertical & left)",
552 "tube (vertical & right)",
553 "tube (horizontal & up)",
554 "tube (horizontal & down)", /* 350 */
556 "tube (left & down)",
558 "tube (right & down)",
561 "stable bomb (DX style)",
565 "-------------------------------",
568 int num_element_info = sizeof(element_info)/sizeof(char *);
572 /* +-----------------------------------------------------------------------+ */
573 /* | SDL TEST STUFF | */
574 /* +-----------------------------------------------------------------------+ */
576 #ifdef USE_SDL_JOYSTICK
578 SDL_Surface *sdl_screen, *sdl_image_tmp, *sdl_image, *sdl_image_masked;
579 SDL_Surface *sdl_image2_tmp, *sdl_image2, *sdl_image2_masked;
581 void TEST_SDL_BLIT_RECT(int x, int y)
583 SDL_Rect rect_src, rect_dst;
585 SDLCopyArea(pix_masked[PIX_HEROES], window,
586 8 * TILEX, 8 * TILEY, TILEX, TILEY, x, y);
589 rect_src.x = 8 * TILEX;
590 rect_src.y = 8 * TILEY;
599 SDL_BlitSurface(sdl_image2_masked, &rect_src, sdl_screen, &rect_dst);
600 SDL_UpdateRect(sdl_screen, x, y, TILEX, TILEY);
603 void TEST_SDL_INIT_DISPLAY()
605 SDL_Rect rect_src, rect_dst;
607 if (SDL_Init(SDL_INIT_VIDEO) < 0)
609 fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError());
613 /* automatically cleanup SDL stuff after exit() */
616 if ((sdl_screen = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, 16, SDL_HWSURFACE))
619 fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
623 SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING);
625 if ((sdl_image_tmp = IMG_Load("graphics/RocksScreen.pcx")) == NULL)
627 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
631 sdl_image = SDL_DisplayFormat(sdl_image_tmp);
633 SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY,
634 SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
635 sdl_image_masked = SDL_DisplayFormat(sdl_image_tmp);
637 SDL_FreeSurface(sdl_image_tmp);
639 if ((sdl_image2_tmp = IMG_Load("graphics/RocksHeroes.pcx")) == NULL)
641 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
645 sdl_image2 = SDL_DisplayFormat(sdl_image2_tmp);
646 SDL_FreeSurface(sdl_image2_tmp);
648 sdl_image2_masked = SDL_DisplayFormat(sdl_image2);
649 SDL_SetColorKey(sdl_image2_masked, SDL_SRCCOLORKEY,
650 SDL_MapRGB(sdl_image2_masked->format, 0x00, 0x00, 0x00));
654 rect_src.w = sdl_image->w;
655 rect_src.h = sdl_image->h;
659 rect_dst.w = sdl_image->w;
660 rect_dst.h = sdl_image->h;
662 SDL_BlitSurface(sdl_image, &rect_src, sdl_screen, &rect_dst);
665 SDL_UpdateRect(sdl_screen, 0, 0, WIN_XSIZE, WIN_YSIZE);
668 SDL_UpdateRect(sdl_screen, 0, 0, 0, 0);
670 SDL_Flip(sdl_screen);
677 void TEST_SDL_EVENT_LOOP()
681 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
684 while (!quit_loop && SDL_WaitEvent(&event) >=0)
691 if (SDL_PollEvent(&event))
693 /* hier werden die Ereignisse behandelt */
702 case SDL_MOUSEBUTTONDOWN:
704 int x = event.button.x;
705 int y = event.button.y;
707 SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
709 TEST_SDL_BLIT_RECT(x, y);
711 printf("SDL_MOUSEBUTTONDOWN(%d, %d)\n", x, y);
715 case SDL_MOUSEBUTTONUP:
717 int x = event.button.x;
718 int y = event.button.y;
720 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
722 printf("SDL_MOUSEBUTTONUP(%d, %d)\n", x, y);
726 case SDL_MOUSEMOTION:
728 int x = event.motion.x;
729 int y = event.motion.y;
731 TEST_SDL_BLIT_RECT(x, y);
733 printf("SDL_MOUSEMOTION(%d, %d)\n", x, y);
742 if (!SDL_PollEvent(NULL)) /* delay only if no pending events */
744 printf("waiting...\n");
749 SDL_FreeSurface(sdl_image);
753 #define SCREEN_WIDTH 640
754 #define SCREEN_HEIGHT 480
756 void WatchJoysticks()
763 SDL_Rect axis_area[2];
765 SDL_Joystick *joystick = Get_SDL_Joystick(joystick_nr);
767 /* Set a video mode to display joystick axis position */
768 screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16, 0);
769 if ( screen == NULL ) {
770 fprintf(stderr, "Couldn't set video mode: %s\n",SDL_GetError());
774 /* Print info about the joysticks we are watching */
777 joystick = Get_SDL_Joystick(i);
779 name = SDL_JoystickName(i);
780 printf("Watching joystick %d: (%s)\n", i,
781 name ? name : "Unknown Joystick");
782 printf("Joystick has %d axes, %d hats, %d balls, and %d buttons\n",
783 SDL_JoystickNumAxes(joystick),
784 SDL_JoystickNumHats(joystick),
785 SDL_JoystickNumBalls(joystick),
786 SDL_JoystickNumButtons(joystick));
789 /* Initialize drawing rectangles */
790 memset(axis_area, 0, (sizeof axis_area));
793 /* Loop, getting joystick events! */
796 while ( SDL_PollEvent(&event) ) {
797 switch (event.type) {
798 case SDL_JOYAXISMOTION:
799 joystick_nr = event.jaxis.which;
800 printf("Joystick %d axis %d value: %d\n",
805 case SDL_JOYHATMOTION:
806 joystick_nr = event.jaxis.which;
807 printf("Joystick %d hat %d value:",
810 if ( event.jhat.value == SDL_HAT_CENTERED )
812 if ( event.jhat.value & SDL_HAT_UP )
814 if ( event.jhat.value & SDL_HAT_RIGHT )
816 if ( event.jhat.value & SDL_HAT_DOWN )
818 if ( event.jhat.value & SDL_HAT_LEFT )
822 case SDL_JOYBALLMOTION:
823 joystick_nr = event.jaxis.which;
824 printf("Joystick %d ball %d delta: (%d,%d)\n",
830 case SDL_JOYBUTTONDOWN:
831 joystick_nr = event.jaxis.which;
832 printf("Joystick %d button %d down\n",
834 event.jbutton.button);
836 case SDL_JOYBUTTONUP:
837 joystick_nr = event.jaxis.which;
838 printf("Joystick %d button %d up\n",
840 event.jbutton.button);
843 if ( event.key.keysym.sym != SDLK_ESCAPE ) {
846 /* Fall through to signal quit */
855 joystick = Get_SDL_Joystick(joystick_nr);
857 /* Update visual joystick state */
858 for ( i=0; i<SDL_JoystickNumButtons(joystick); ++i ) {
862 area.y = SCREEN_HEIGHT-34;
865 if (SDL_JoystickGetButton(joystick, i) == SDL_PRESSED) {
866 SDL_FillRect(screen, &area, 0xFFFF);
868 SDL_FillRect(screen, &area, 0x0000);
870 SDL_UpdateRects(screen, 1, &area);
873 /* Erase previous axes */
874 SDL_FillRect(screen, &axis_area[draw], 0x0000);
876 /* Draw the X/Y axis */
878 x = (((int)SDL_JoystickGetAxis(joystick, 0))+32768);
884 if ( x > (SCREEN_WIDTH-16) ) {
887 y = (((int)SDL_JoystickGetAxis(joystick, 1))+32768);
893 if ( y > (SCREEN_HEIGHT-16) ) {
894 y = SCREEN_HEIGHT-16;
896 axis_area[draw].x = (Sint16)x;
897 axis_area[draw].y = (Sint16)y;
898 axis_area[draw].w = 16;
899 axis_area[draw].h = 16;
900 SDL_FillRect(screen, &axis_area[draw], 0xFFFF);
902 SDL_UpdateRects(screen, 2, axis_area);
906 void TEST_SDL_JOYSTICK()
911 /* Initialize SDL (Note: video is required to start event loop) */
912 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 )
914 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
918 /* Print information about the joysticks */
919 printf("There are %d joysticks attached\n", SDL_NumJoysticks());
920 for ( i=0; i<SDL_NumJoysticks(); ++i )
922 name = SDL_JoystickName(i);
923 printf("Joystick %d: %s\n",i,name ? name : "Unknown Joystick");
928 if (!Open_SDL_Joystick(i))
929 printf("Couldn't open joystick %d: %s\n", i, SDL_GetError());
935 Close_SDL_Joystick(i);
937 SDL_QuitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
940 #endif /* USE_SDL_JOYSTICK */
942 /* +-----------------------------------------------------------------------+ */
943 /* | SDL TEST STUFF | */
944 /* +-----------------------------------------------------------------------+ */
948 int main(int argc, char *argv[])
950 program_name = (strrchr(argv[0],'/') ? strrchr(argv[0],'/') + 1 : argv[0]);
962 #ifdef USE_SDL_JOYSTICK
964 TEST_SDL_BLIT_RECT((WIN_XSIZE - TILEX)/2, (WIN_YSIZE - TILEY)/2);
965 TEST_SDL_EVENT_LOOP();
974 exit(0); /* to keep compilers happy */