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 DrawBuffer drawto, drawto_field, backbuffer, fieldbuffer;
40 char *sound_device_name = SOUND_DEVICE;
41 int joystick_device = 0;
42 char *joystick_device_name[MAX_PLAYERS] =
50 char *program_name = NULL;
52 int game_status = MAINMENU;
53 boolean level_editor_test_game = FALSE;
54 boolean network_playing = FALSE;
55 int button_status = MB_NOT_PRESSED;
56 boolean motion_status = FALSE;
57 int key_joystick_mapping = 0;
58 int global_joystick_status = JOYSTICK_STATUS;
59 int joystick_status = JOYSTICK_STATUS;
60 int sound_status = SOUND_STATUS;
61 boolean sound_loops_allowed = FALSE;
62 boolean fullscreen_available = FULLSCREEN_STATUS;
63 boolean fullscreen_enabled = FALSE;
65 boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
66 int redraw_x1 = 0, redraw_y1 = 0;
70 short Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
71 short Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
72 short MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
73 short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
74 short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
75 short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
76 short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
77 short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
78 short Frame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
79 boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
80 short JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
81 short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
82 short AmoebaCnt[MAX_NUM_AMOEBA], AmoebaCnt2[MAX_NUM_AMOEBA];
83 unsigned long Elementeigenschaften1[MAX_ELEMENTS];
84 unsigned long Elementeigenschaften2[MAX_ELEMENTS];
87 int lev_fieldx,lev_fieldy, scroll_x,scroll_y;
89 int FX = SX, FY = SY, ScrollStepSize;
90 int ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0;
92 int BorderElement = EL_BETON;
93 int GameFrameDelay = GAME_FRAME_DELAY;
94 int FfwdFrameDelay = FFWD_FRAME_DELAY;
95 int BX1 = 0, BY1 = 0, BX2 = SCR_FIELDX-1, BY2 = SCR_FIELDY-1;
96 int SBX_Left, SBX_Right;
97 int SBY_Upper, SBY_Lower;
98 int ZX,ZY, ExitX,ExitY;
100 int FrameCounter, TimeFrames, TimePlayed, TimeLeft;
102 boolean network_player_action_received = FALSE;
104 struct LevelDirInfo *leveldir_first = NULL, *leveldir_current = NULL;
105 struct LevelInfo level;
106 struct PlayerInfo stored_player[MAX_PLAYERS], *local_player = NULL;
107 struct HiScore highscore[MAX_SCORE_ENTRIES];
108 struct SoundInfo Sound[NUM_SOUNDS];
109 struct TapeInfo tape;
110 struct OptionInfo options;
111 struct SetupInfo setup;
112 struct GameInfo game;
113 struct GlobalInfo global;
115 /* data needed for playing sounds */
116 char *sound_name[NUM_SOUNDS] =
182 /* background music */
183 int background_loop[] =
193 int num_bg_loops = sizeof(background_loop)/sizeof(int);
195 char *element_info[] =
197 "empty space", /* 0 */
207 "spaceship", /* 10 */
214 "quicksand with rock",
217 "magic wall", /* 20 */
227 "magic wheel", /* 30 */
237 "gray door (opened by red key)", /* 40 */
238 "gray door (opened by yellow key)",
239 "gray door (opened by green key)",
240 "gray door (opened by blue key)",
243 "invisible normal wall",
245 "ligh bulb (glowing)",
247 "wall with diamond", /* 50 */
248 "amoeba with content",
253 "diamond (BD style)",
255 "wall with BD style diamond",
256 "wall with yellow emerald",
257 "dark yam yam", /* 60 */
258 "magic wall (BD style)",
259 "invisible steel wall",
261 "increases number of bombs",
262 "increases explosion size",
263 "increases power of explosion",
265 "sokoban empty field",
266 "sokoban field with object",
267 "butterfly (starts moving right)", /* 70 */
268 "butterfly (starts moving up)",
269 "butterfly (starts moving left)",
270 "butterfly (starts moving down)",
271 "firefly (starts moving right)",
272 "firefly (starts moving up)",
273 "firefly (starts moving left)",
274 "firefly (starts moving down)",
277 "yellow player", /* 80 */
281 "bug (starts moving right)",
282 "bug (starts moving up)",
283 "bug (starts moving left)",
284 "bug (starts moving down)",
285 "spaceship (starts moving right)",
286 "spaceship (starts moving up)",
287 "spaceship (starts moving left)", /* 90 */
288 "spaceship (starts moving down)",
289 "pac man (starts moving right)",
290 "pac man (starts moving up)",
291 "pac man (starts moving left)",
292 "pac man (starts moving down)",
295 "wall with red emerald",
296 "wall with violet emerald",
302 "normal wall (BD style)",
315 "fire breathing dragon",
317 "letter ' '", /* 120 */
327 "letter '*'", /* 130 */
337 "letter '4'", /* 140 */
347 "letter '>'", /* 150 */
357 "letter 'H'", /* 160 */
367 "letter 'R'", /* 170 */
377 "letter 'Ö'", /* 180 */
387 "letter ''", /* 190 */
397 "growing wall (horizontal)", /* 200 */
398 "growing wall (vertical)",
399 "growing wall (all directions)",
407 "empty space", /* 210 */
416 "port (leading right)",
417 "port (leading down)", /* 220 */
418 "port (leading left)",
420 "port (leading right)",
421 "port (leading down)",
422 "port (leading left)",
427 "red disk", /* 230 */
430 "port (all directions)",
437 "hardware", /* 240 */
460 "white door", /* 260 */
461 "gray door (opened by white key)",
465 "switch gate (open)",
466 "switch gate (closed)",
467 "switch for switch gate",
468 "switch for switch gate",
471 "red conveyor belt (left)",
472 "red conveyor belt (middle)",
473 "red conveyor belt (right)",
474 "switch for red conveyor belt (left)",
475 "switch for red conveyor belt (middle)",
476 "switch for red conveyor belt (right)",
477 "yellow conveyor belt (left)",
478 "yellow conveyor belt (middle)",
479 "yellow conveyor belt (right)",
480 "switch for yellow conveyor belt (left)", /* 280 */
481 "switch for yellow conveyor belt (middle)",
482 "switch for yellow conveyor belt (right)",
483 "green conveyor belt (left)",
484 "green conveyor belt (middle)",
485 "green conveyor belt (right)",
486 "switch for green conveyor belt (left)",
487 "switch for green conveyor belt (middle)",
488 "switch for green conveyor belt (right)",
489 "blue conveyor belt (left)",
490 "blue conveyor belt (middle)", /* 290 */
491 "blue conveyor belt (right)",
492 "switch for blue conveyor belt (left)",
493 "switch for blue conveyor belt (middle)",
494 "switch for blue conveyor belt (right)",
497 "light switch (off)",
499 "sign (exclamation)",
500 "sign (radio activity)", /* 300 */
502 "sign (wheel chair)",
510 "sign (other)", /* 310 */
511 "mole (starts moving left)",
512 "mole (starts moving right)",
513 "mole (starts moving up)",
514 "mole (starts moving down)",
515 "steel wall (slanted)",
521 "shield (active, kills enemies)",
523 "time gate (closed)",
524 "switch for time gate",
525 "switch for time gate",
527 "send balloon to the left",
528 "send balloon to the right",
530 "send balloon down", /* 330 */
531 "send balloon in any direction",
540 "normal wall", /* 340 */
544 "tube (all directions)",
547 "tube (vertical & left)",
548 "tube (vertical & right)",
549 "tube (horizontal & up)",
550 "tube (horizontal & down)", /* 350 */
552 "tube (left & down)",
554 "tube (right & down)",
557 "stable bomb (DX style)",
561 "-------------------------------",
564 int num_element_info = sizeof(element_info)/sizeof(char *);
568 /* +-----------------------------------------------------------------------+ */
569 /* | SDL TEST STUFF | */
570 /* +-----------------------------------------------------------------------+ */
572 #ifdef USE_SDL_JOYSTICK
574 SDL_Surface *sdl_screen, *sdl_image_tmp, *sdl_image, *sdl_image_masked;
575 SDL_Surface *sdl_image2_tmp, *sdl_image2, *sdl_image2_masked;
577 void TEST_SDL_BLIT_RECT(int x, int y)
579 SDL_Rect rect_src, rect_dst;
581 SDLCopyArea(pix_masked[PIX_HEROES], window,
582 8 * TILEX, 8 * TILEY, TILEX, TILEY, x, y);
585 rect_src.x = 8 * TILEX;
586 rect_src.y = 8 * TILEY;
595 SDL_BlitSurface(sdl_image2_masked, &rect_src, sdl_screen, &rect_dst);
596 SDL_UpdateRect(sdl_screen, x, y, TILEX, TILEY);
599 void TEST_SDL_INIT_DISPLAY()
601 SDL_Rect rect_src, rect_dst;
603 if (SDL_Init(SDL_INIT_VIDEO) < 0)
605 fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError());
609 /* automatically cleanup SDL stuff after exit() */
612 if ((sdl_screen = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, 16, SDL_HWSURFACE))
615 fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
619 SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING);
621 if ((sdl_image_tmp = IMG_Load("graphics/RocksScreen.pcx")) == NULL)
623 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
627 sdl_image = SDL_DisplayFormat(sdl_image_tmp);
629 SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY,
630 SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
631 sdl_image_masked = SDL_DisplayFormat(sdl_image_tmp);
633 SDL_FreeSurface(sdl_image_tmp);
635 if ((sdl_image2_tmp = IMG_Load("graphics/RocksHeroes.pcx")) == NULL)
637 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
641 sdl_image2 = SDL_DisplayFormat(sdl_image2_tmp);
642 SDL_FreeSurface(sdl_image2_tmp);
644 sdl_image2_masked = SDL_DisplayFormat(sdl_image2);
645 SDL_SetColorKey(sdl_image2_masked, SDL_SRCCOLORKEY,
646 SDL_MapRGB(sdl_image2_masked->format, 0x00, 0x00, 0x00));
650 rect_src.w = sdl_image->w;
651 rect_src.h = sdl_image->h;
655 rect_dst.w = sdl_image->w;
656 rect_dst.h = sdl_image->h;
658 SDL_BlitSurface(sdl_image, &rect_src, sdl_screen, &rect_dst);
661 SDL_UpdateRect(sdl_screen, 0, 0, WIN_XSIZE, WIN_YSIZE);
664 SDL_UpdateRect(sdl_screen, 0, 0, 0, 0);
666 SDL_Flip(sdl_screen);
673 void TEST_SDL_EVENT_LOOP()
677 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
680 while (!quit_loop && SDL_WaitEvent(&event) >=0)
687 if (SDL_PollEvent(&event))
689 /* hier werden die Ereignisse behandelt */
698 case SDL_MOUSEBUTTONDOWN:
700 int x = event.button.x;
701 int y = event.button.y;
703 SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
705 TEST_SDL_BLIT_RECT(x, y);
707 printf("SDL_MOUSEBUTTONDOWN(%d, %d)\n", x, y);
711 case SDL_MOUSEBUTTONUP:
713 int x = event.button.x;
714 int y = event.button.y;
716 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
718 printf("SDL_MOUSEBUTTONUP(%d, %d)\n", x, y);
722 case SDL_MOUSEMOTION:
724 int x = event.motion.x;
725 int y = event.motion.y;
727 TEST_SDL_BLIT_RECT(x, y);
729 printf("SDL_MOUSEMOTION(%d, %d)\n", x, y);
738 if (!SDL_PollEvent(NULL)) /* delay only if no pending events */
740 printf("waiting...\n");
745 SDL_FreeSurface(sdl_image);
749 #define SCREEN_WIDTH 640
750 #define SCREEN_HEIGHT 480
752 void WatchJoysticks()
759 SDL_Rect axis_area[2];
761 SDL_Joystick *joystick = Get_SDL_Joystick(joystick_nr);
763 /* Set a video mode to display joystick axis position */
764 screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16, 0);
765 if ( screen == NULL ) {
766 fprintf(stderr, "Couldn't set video mode: %s\n",SDL_GetError());
770 /* Print info about the joysticks we are watching */
773 joystick = Get_SDL_Joystick(i);
775 name = SDL_JoystickName(i);
776 printf("Watching joystick %d: (%s)\n", i,
777 name ? name : "Unknown Joystick");
778 printf("Joystick has %d axes, %d hats, %d balls, and %d buttons\n",
779 SDL_JoystickNumAxes(joystick),
780 SDL_JoystickNumHats(joystick),
781 SDL_JoystickNumBalls(joystick),
782 SDL_JoystickNumButtons(joystick));
785 /* Initialize drawing rectangles */
786 memset(axis_area, 0, (sizeof axis_area));
789 /* Loop, getting joystick events! */
792 while ( SDL_PollEvent(&event) ) {
793 switch (event.type) {
794 case SDL_JOYAXISMOTION:
795 joystick_nr = event.jaxis.which;
796 printf("Joystick %d axis %d value: %d\n",
801 case SDL_JOYHATMOTION:
802 joystick_nr = event.jaxis.which;
803 printf("Joystick %d hat %d value:",
806 if ( event.jhat.value == SDL_HAT_CENTERED )
808 if ( event.jhat.value & SDL_HAT_UP )
810 if ( event.jhat.value & SDL_HAT_RIGHT )
812 if ( event.jhat.value & SDL_HAT_DOWN )
814 if ( event.jhat.value & SDL_HAT_LEFT )
818 case SDL_JOYBALLMOTION:
819 joystick_nr = event.jaxis.which;
820 printf("Joystick %d ball %d delta: (%d,%d)\n",
826 case SDL_JOYBUTTONDOWN:
827 joystick_nr = event.jaxis.which;
828 printf("Joystick %d button %d down\n",
830 event.jbutton.button);
832 case SDL_JOYBUTTONUP:
833 joystick_nr = event.jaxis.which;
834 printf("Joystick %d button %d up\n",
836 event.jbutton.button);
839 if ( event.key.keysym.sym != SDLK_ESCAPE ) {
842 /* Fall through to signal quit */
851 joystick = Get_SDL_Joystick(joystick_nr);
853 /* Update visual joystick state */
854 for ( i=0; i<SDL_JoystickNumButtons(joystick); ++i ) {
858 area.y = SCREEN_HEIGHT-34;
861 if (SDL_JoystickGetButton(joystick, i) == SDL_PRESSED) {
862 SDL_FillRect(screen, &area, 0xFFFF);
864 SDL_FillRect(screen, &area, 0x0000);
866 SDL_UpdateRects(screen, 1, &area);
869 /* Erase previous axes */
870 SDL_FillRect(screen, &axis_area[draw], 0x0000);
872 /* Draw the X/Y axis */
874 x = (((int)SDL_JoystickGetAxis(joystick, 0))+32768);
880 if ( x > (SCREEN_WIDTH-16) ) {
883 y = (((int)SDL_JoystickGetAxis(joystick, 1))+32768);
889 if ( y > (SCREEN_HEIGHT-16) ) {
890 y = SCREEN_HEIGHT-16;
892 axis_area[draw].x = (Sint16)x;
893 axis_area[draw].y = (Sint16)y;
894 axis_area[draw].w = 16;
895 axis_area[draw].h = 16;
896 SDL_FillRect(screen, &axis_area[draw], 0xFFFF);
898 SDL_UpdateRects(screen, 2, axis_area);
902 void TEST_SDL_JOYSTICK()
907 /* Initialize SDL (Note: video is required to start event loop) */
908 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 )
910 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
914 /* Print information about the joysticks */
915 printf("There are %d joysticks attached\n", SDL_NumJoysticks());
916 for ( i=0; i<SDL_NumJoysticks(); ++i )
918 name = SDL_JoystickName(i);
919 printf("Joystick %d: %s\n",i,name ? name : "Unknown Joystick");
924 if (!Open_SDL_Joystick(i))
925 printf("Couldn't open joystick %d: %s\n", i, SDL_GetError());
931 Close_SDL_Joystick(i);
933 SDL_QuitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
936 #endif /* USE_SDL_JOYSTICK */
938 /* +-----------------------------------------------------------------------+ */
939 /* | SDL TEST STUFF | */
940 /* +-----------------------------------------------------------------------+ */
944 int main(int argc, char *argv[])
946 program_name = (strrchr(argv[0],'/') ? strrchr(argv[0],'/') + 1 : argv[0]);
958 #ifdef USE_SDL_JOYSTICK
960 TEST_SDL_BLIT_RECT((WIN_XSIZE - TILEX)/2, (WIN_YSIZE - TILEY)/2);
961 TEST_SDL_EVENT_LOOP();
970 exit(0); /* to keep compilers happy */