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 "-------------------------------",
571 /* +-----------------------------------------------------------------------+ */
572 /* | SDL TEST STUFF | */
573 /* +-----------------------------------------------------------------------+ */
575 #ifdef USE_SDL_JOYSTICK
577 SDL_Surface *sdl_screen, *sdl_image_tmp, *sdl_image, *sdl_image_masked;
578 SDL_Surface *sdl_image2_tmp, *sdl_image2, *sdl_image2_masked;
580 void TEST_SDL_BLIT_RECT(int x, int y)
582 SDL_Rect rect_src, rect_dst;
584 SDLCopyArea(pix_masked[PIX_HEROES], window,
585 8 * TILEX, 8 * TILEY, TILEX, TILEY, x, y);
588 rect_src.x = 8 * TILEX;
589 rect_src.y = 8 * TILEY;
598 SDL_BlitSurface(sdl_image2_masked, &rect_src, sdl_screen, &rect_dst);
599 SDL_UpdateRect(sdl_screen, x, y, TILEX, TILEY);
602 void TEST_SDL_INIT_DISPLAY()
604 SDL_Rect rect_src, rect_dst;
606 if (SDL_Init(SDL_INIT_VIDEO) < 0)
608 fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError());
612 /* automatically cleanup SDL stuff after exit() */
615 if ((sdl_screen = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, 16, SDL_HWSURFACE))
618 fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
622 SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING);
624 if ((sdl_image_tmp = IMG_Load("graphics/RocksScreen.pcx")) == NULL)
626 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
630 sdl_image = SDL_DisplayFormat(sdl_image_tmp);
632 SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY,
633 SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
634 sdl_image_masked = SDL_DisplayFormat(sdl_image_tmp);
636 SDL_FreeSurface(sdl_image_tmp);
638 if ((sdl_image2_tmp = IMG_Load("graphics/RocksHeroes.pcx")) == NULL)
640 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
644 sdl_image2 = SDL_DisplayFormat(sdl_image2_tmp);
645 SDL_FreeSurface(sdl_image2_tmp);
647 sdl_image2_masked = SDL_DisplayFormat(sdl_image2);
648 SDL_SetColorKey(sdl_image2_masked, SDL_SRCCOLORKEY,
649 SDL_MapRGB(sdl_image2_masked->format, 0x00, 0x00, 0x00));
653 rect_src.w = sdl_image->w;
654 rect_src.h = sdl_image->h;
658 rect_dst.w = sdl_image->w;
659 rect_dst.h = sdl_image->h;
661 SDL_BlitSurface(sdl_image, &rect_src, sdl_screen, &rect_dst);
664 SDL_UpdateRect(sdl_screen, 0, 0, WIN_XSIZE, WIN_YSIZE);
667 SDL_UpdateRect(sdl_screen, 0, 0, 0, 0);
669 SDL_Flip(sdl_screen);
676 void TEST_SDL_EVENT_LOOP()
680 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
683 while (!quit_loop && SDL_WaitEvent(&event) >=0)
690 if (SDL_PollEvent(&event))
692 /* hier werden die Ereignisse behandelt */
701 case SDL_MOUSEBUTTONDOWN:
703 int x = event.button.x;
704 int y = event.button.y;
706 SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
708 TEST_SDL_BLIT_RECT(x, y);
710 printf("SDL_MOUSEBUTTONDOWN(%d, %d)\n", x, y);
714 case SDL_MOUSEBUTTONUP:
716 int x = event.button.x;
717 int y = event.button.y;
719 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
721 printf("SDL_MOUSEBUTTONUP(%d, %d)\n", x, y);
725 case SDL_MOUSEMOTION:
727 int x = event.motion.x;
728 int y = event.motion.y;
730 TEST_SDL_BLIT_RECT(x, y);
732 printf("SDL_MOUSEMOTION(%d, %d)\n", x, y);
741 if (!SDL_PollEvent(NULL)) /* delay only if no pending events */
743 printf("waiting...\n");
748 SDL_FreeSurface(sdl_image);
752 #define SCREEN_WIDTH 640
753 #define SCREEN_HEIGHT 480
755 void WatchJoysticks()
762 SDL_Rect axis_area[2];
764 SDL_Joystick *joystick = Get_SDL_Joystick(joystick_nr);
766 /* Set a video mode to display joystick axis position */
767 screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16, 0);
768 if ( screen == NULL ) {
769 fprintf(stderr, "Couldn't set video mode: %s\n",SDL_GetError());
773 /* Print info about the joysticks we are watching */
776 joystick = Get_SDL_Joystick(i);
778 name = SDL_JoystickName(i);
779 printf("Watching joystick %d: (%s)\n", i,
780 name ? name : "Unknown Joystick");
781 printf("Joystick has %d axes, %d hats, %d balls, and %d buttons\n",
782 SDL_JoystickNumAxes(joystick),
783 SDL_JoystickNumHats(joystick),
784 SDL_JoystickNumBalls(joystick),
785 SDL_JoystickNumButtons(joystick));
788 /* Initialize drawing rectangles */
789 memset(axis_area, 0, (sizeof axis_area));
792 /* Loop, getting joystick events! */
795 while ( SDL_PollEvent(&event) ) {
796 switch (event.type) {
797 case SDL_JOYAXISMOTION:
798 joystick_nr = event.jaxis.which;
799 printf("Joystick %d axis %d value: %d\n",
804 case SDL_JOYHATMOTION:
805 joystick_nr = event.jaxis.which;
806 printf("Joystick %d hat %d value:",
809 if ( event.jhat.value == SDL_HAT_CENTERED )
811 if ( event.jhat.value & SDL_HAT_UP )
813 if ( event.jhat.value & SDL_HAT_RIGHT )
815 if ( event.jhat.value & SDL_HAT_DOWN )
817 if ( event.jhat.value & SDL_HAT_LEFT )
821 case SDL_JOYBALLMOTION:
822 joystick_nr = event.jaxis.which;
823 printf("Joystick %d ball %d delta: (%d,%d)\n",
829 case SDL_JOYBUTTONDOWN:
830 joystick_nr = event.jaxis.which;
831 printf("Joystick %d button %d down\n",
833 event.jbutton.button);
835 case SDL_JOYBUTTONUP:
836 joystick_nr = event.jaxis.which;
837 printf("Joystick %d button %d up\n",
839 event.jbutton.button);
842 if ( event.key.keysym.sym != SDLK_ESCAPE ) {
845 /* Fall through to signal quit */
854 joystick = Get_SDL_Joystick(joystick_nr);
856 /* Update visual joystick state */
857 for ( i=0; i<SDL_JoystickNumButtons(joystick); ++i ) {
861 area.y = SCREEN_HEIGHT-34;
864 if (SDL_JoystickGetButton(joystick, i) == SDL_PRESSED) {
865 SDL_FillRect(screen, &area, 0xFFFF);
867 SDL_FillRect(screen, &area, 0x0000);
869 SDL_UpdateRects(screen, 1, &area);
872 /* Erase previous axes */
873 SDL_FillRect(screen, &axis_area[draw], 0x0000);
875 /* Draw the X/Y axis */
877 x = (((int)SDL_JoystickGetAxis(joystick, 0))+32768);
883 if ( x > (SCREEN_WIDTH-16) ) {
886 y = (((int)SDL_JoystickGetAxis(joystick, 1))+32768);
892 if ( y > (SCREEN_HEIGHT-16) ) {
893 y = SCREEN_HEIGHT-16;
895 axis_area[draw].x = (Sint16)x;
896 axis_area[draw].y = (Sint16)y;
897 axis_area[draw].w = 16;
898 axis_area[draw].h = 16;
899 SDL_FillRect(screen, &axis_area[draw], 0xFFFF);
901 SDL_UpdateRects(screen, 2, axis_area);
905 void TEST_SDL_JOYSTICK()
910 /* Initialize SDL (Note: video is required to start event loop) */
911 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 )
913 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
917 /* Print information about the joysticks */
918 printf("There are %d joysticks attached\n", SDL_NumJoysticks());
919 for ( i=0; i<SDL_NumJoysticks(); ++i )
921 name = SDL_JoystickName(i);
922 printf("Joystick %d: %s\n",i,name ? name : "Unknown Joystick");
927 if (!Open_SDL_Joystick(i))
928 printf("Couldn't open joystick %d: %s\n", i, SDL_GetError());
934 Close_SDL_Joystick(i);
936 SDL_QuitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
939 #endif /* USE_SDL_JOYSTICK */
941 /* +-----------------------------------------------------------------------+ */
942 /* | SDL TEST STUFF | */
943 /* +-----------------------------------------------------------------------+ */
947 int main(int argc, char *argv[])
949 program_name = (strrchr(argv[0],'/') ? strrchr(argv[0],'/') + 1 : argv[0]);
961 #ifdef USE_SDL_JOYSTICK
963 TEST_SDL_BLIT_RECT((WIN_XSIZE - TILEX)/2, (WIN_YSIZE - TILEY)/2);
964 TEST_SDL_EVENT_LOOP();
973 exit(0); /* to keep compilers happy */