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 ***********************************************************/
14 #include "libgame/libgame.h"
22 #if defined(PLATFORM_MSDOS)
27 DrawWindow window = None;
28 DrawBuffer backbuffer;
33 GC clip_gc[NUM_BITMAPS];
36 Bitmap pix[NUM_BITMAPS];
38 Bitmap pix_masked[NUM_BITMAPS];
40 Bitmap tile_masked[NUM_TILES];
42 Pixmap clipmask[NUM_BITMAPS];
44 Pixmap tile_clipmask[NUM_TILES];
50 DrawBuffer drawto_field, fieldbuffer;
56 char *sound_device_name = AUDIO_DEVICE;
59 int joystick_device = 0;
60 char *joystick_device_name[MAX_PLAYERS] =
68 char *program_name = NULL;
70 int game_status = MAINMENU;
71 boolean level_editor_test_game = FALSE;
72 boolean network_playing = FALSE;
73 int button_status = MB_NOT_PRESSED;
74 boolean motion_status = FALSE;
75 int key_joystick_mapping = 0;
76 int global_joystick_status = JOYSTICK_STATUS;
77 int joystick_status = JOYSTICK_STATUS;
80 boolean fullscreen_available = FULLSCREEN_STATUS;
81 boolean fullscreen_enabled = FALSE;
84 boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
85 int redraw_x1 = 0, redraw_y1 = 0;
92 short Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
93 short Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
94 short MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
95 short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
96 short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
97 short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
98 short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
99 short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
100 short Frame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
101 boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
102 short JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
103 short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
104 short AmoebaCnt[MAX_NUM_AMOEBA], AmoebaCnt2[MAX_NUM_AMOEBA];
105 unsigned long Elementeigenschaften1[MAX_ELEMENTS];
106 unsigned long Elementeigenschaften2[MAX_ELEMENTS];
109 int lev_fieldx,lev_fieldy, scroll_x,scroll_y;
111 int FX = SX, FY = SY, ScrollStepSize;
112 int ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0;
113 int ScreenGfxPos = 0;
114 int BorderElement = EL_BETON;
115 int GameFrameDelay = GAME_FRAME_DELAY;
116 int FfwdFrameDelay = FFWD_FRAME_DELAY;
117 int BX1 = 0, BY1 = 0, BX2 = SCR_FIELDX-1, BY2 = SCR_FIELDY-1;
118 int SBX_Left, SBX_Right;
119 int SBY_Upper, SBY_Lower;
120 int ZX,ZY, ExitX,ExitY;
127 int TimeFrames, TimePlayed, TimeLeft;
129 boolean network_player_action_received = FALSE;
131 struct LevelDirInfo *leveldir_first = NULL, *leveldir_current = NULL;
132 struct LevelInfo level;
133 struct PlayerInfo stored_player[MAX_PLAYERS], *local_player = NULL;
134 struct HiScore highscore[MAX_SCORE_ENTRIES];
135 struct SampleInfo Sound[NUM_SOUNDS];
136 struct TapeInfo tape;
139 struct OptionInfo options;
142 struct SetupInfo setup;
143 struct GameInfo game;
146 struct VideoSystemInfo video;
147 struct AudioSystemInfo audio;
150 struct GlobalInfo global;
152 /* data needed for playing sounds */
153 char *sound_name[NUM_SOUNDS] =
219 /* background music */
220 int background_loop[] =
230 int num_bg_loops = sizeof(background_loop)/sizeof(int);
232 char *element_info[] =
234 "empty space", /* 0 */
244 "spaceship", /* 10 */
251 "quicksand with rock",
254 "magic wall", /* 20 */
264 "magic wheel", /* 30 */
274 "gray door (opened by red key)", /* 40 */
275 "gray door (opened by yellow key)",
276 "gray door (opened by green key)",
277 "gray door (opened by blue key)",
280 "invisible normal wall",
282 "ligh bulb (glowing)",
284 "wall with diamond", /* 50 */
285 "amoeba with content",
290 "diamond (BD style)",
292 "wall with BD style diamond",
293 "wall with yellow emerald",
294 "dark yam yam", /* 60 */
295 "magic wall (BD style)",
296 "invisible steel wall",
298 "increases number of bombs",
299 "increases explosion size",
300 "increases power of explosion",
302 "sokoban empty field",
303 "sokoban field with object",
304 "butterfly (starts moving right)", /* 70 */
305 "butterfly (starts moving up)",
306 "butterfly (starts moving left)",
307 "butterfly (starts moving down)",
308 "firefly (starts moving right)",
309 "firefly (starts moving up)",
310 "firefly (starts moving left)",
311 "firefly (starts moving down)",
314 "yellow player", /* 80 */
318 "bug (starts moving right)",
319 "bug (starts moving up)",
320 "bug (starts moving left)",
321 "bug (starts moving down)",
322 "spaceship (starts moving right)",
323 "spaceship (starts moving up)",
324 "spaceship (starts moving left)", /* 90 */
325 "spaceship (starts moving down)",
326 "pac man (starts moving right)",
327 "pac man (starts moving up)",
328 "pac man (starts moving left)",
329 "pac man (starts moving down)",
332 "wall with red emerald",
333 "wall with violet emerald",
339 "normal wall (BD style)",
352 "fire breathing dragon",
354 "letter ' '", /* 120 */
364 "letter '*'", /* 130 */
374 "letter '4'", /* 140 */
384 "letter '>'", /* 150 */
394 "letter 'H'", /* 160 */
404 "letter 'R'", /* 170 */
414 "letter 'Ö'", /* 180 */
424 "letter ''", /* 190 */
434 "growing wall (horizontal)", /* 200 */
435 "growing wall (vertical)",
436 "growing wall (all directions)",
444 "empty space", /* 210 */
453 "port (leading right)",
454 "port (leading down)", /* 220 */
455 "port (leading left)",
457 "port (leading right)",
458 "port (leading down)",
459 "port (leading left)",
464 "red disk", /* 230 */
467 "port (all directions)",
474 "hardware", /* 240 */
497 "white door", /* 260 */
498 "gray door (opened by white key)",
502 "switch gate (open)",
503 "switch gate (closed)",
504 "switch for switch gate",
505 "switch for switch gate",
508 "red conveyor belt (left)",
509 "red conveyor belt (middle)",
510 "red conveyor belt (right)",
511 "switch for red conveyor belt (left)",
512 "switch for red conveyor belt (middle)",
513 "switch for red conveyor belt (right)",
514 "yellow conveyor belt (left)",
515 "yellow conveyor belt (middle)",
516 "yellow conveyor belt (right)",
517 "switch for yellow conveyor belt (left)", /* 280 */
518 "switch for yellow conveyor belt (middle)",
519 "switch for yellow conveyor belt (right)",
520 "green conveyor belt (left)",
521 "green conveyor belt (middle)",
522 "green conveyor belt (right)",
523 "switch for green conveyor belt (left)",
524 "switch for green conveyor belt (middle)",
525 "switch for green conveyor belt (right)",
526 "blue conveyor belt (left)",
527 "blue conveyor belt (middle)", /* 290 */
528 "blue conveyor belt (right)",
529 "switch for blue conveyor belt (left)",
530 "switch for blue conveyor belt (middle)",
531 "switch for blue conveyor belt (right)",
534 "light switch (off)",
536 "sign (exclamation)",
537 "sign (radio activity)", /* 300 */
539 "sign (wheel chair)",
547 "sign (other)", /* 310 */
548 "mole (starts moving left)",
549 "mole (starts moving right)",
550 "mole (starts moving up)",
551 "mole (starts moving down)",
552 "steel wall (slanted)",
558 "shield (active, kills enemies)",
560 "time gate (closed)",
561 "switch for time gate",
562 "switch for time gate",
564 "send balloon to the left",
565 "send balloon to the right",
567 "send balloon down", /* 330 */
568 "send balloon in any direction",
577 "normal wall", /* 340 */
581 "tube (all directions)",
584 "tube (vertical & left)",
585 "tube (vertical & right)",
586 "tube (horizontal & up)",
587 "tube (horizontal & down)", /* 350 */
589 "tube (left & down)",
591 "tube (right & down)",
594 "stable bomb (DX style)",
598 "-------------------------------",
601 int num_element_info = sizeof(element_info)/sizeof(char *);
605 /* +-----------------------------------------------------------------------+ */
606 /* | SDL TEST STUFF | */
607 /* +-----------------------------------------------------------------------+ */
609 #if defined(TARGET_SDL)
611 SDL_Surface *sdl_screen, *sdl_image_tmp, *sdl_image, *sdl_image_masked;
612 SDL_Surface *sdl_image2_tmp, *sdl_image2, *sdl_image2_masked;
614 void TEST_SDL_BLIT_RECT(int x, int y)
616 SDL_Rect rect_src, rect_dst;
618 SDLCopyArea(pix_masked[PIX_HEROES], window,
619 8 * TILEX, 8 * TILEY, TILEX, TILEY, x, y);
622 rect_src.x = 8 * TILEX;
623 rect_src.y = 8 * TILEY;
632 SDL_BlitSurface(sdl_image2_masked, &rect_src, sdl_screen, &rect_dst);
633 SDL_UpdateRect(sdl_screen, x, y, TILEX, TILEY);
636 void TEST_SDL_INIT_DISPLAY()
638 SDL_Rect rect_src, rect_dst;
640 if (SDL_Init(SDL_INIT_VIDEO) < 0)
642 fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError());
646 /* automatically cleanup SDL stuff after exit() */
649 if ((sdl_screen = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, 16, SDL_HWSURFACE))
652 fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
656 SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING);
658 if ((sdl_image_tmp = IMG_Load("graphics/RocksScreen.pcx")) == NULL)
660 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
664 sdl_image = SDL_DisplayFormat(sdl_image_tmp);
666 SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY,
667 SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
668 sdl_image_masked = SDL_DisplayFormat(sdl_image_tmp);
670 SDL_FreeSurface(sdl_image_tmp);
672 if ((sdl_image2_tmp = IMG_Load("graphics/RocksHeroes.pcx")) == NULL)
674 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
678 sdl_image2 = SDL_DisplayFormat(sdl_image2_tmp);
679 SDL_FreeSurface(sdl_image2_tmp);
681 sdl_image2_masked = SDL_DisplayFormat(sdl_image2);
682 SDL_SetColorKey(sdl_image2_masked, SDL_SRCCOLORKEY,
683 SDL_MapRGB(sdl_image2_masked->format, 0x00, 0x00, 0x00));
687 rect_src.w = sdl_image->w;
688 rect_src.h = sdl_image->h;
692 rect_dst.w = sdl_image->w;
693 rect_dst.h = sdl_image->h;
695 SDL_BlitSurface(sdl_image, &rect_src, sdl_screen, &rect_dst);
698 SDL_UpdateRect(sdl_screen, 0, 0, WIN_XSIZE, WIN_YSIZE);
701 SDL_UpdateRect(sdl_screen, 0, 0, 0, 0);
703 SDL_Flip(sdl_screen);
710 void TEST_SDL_EVENT_LOOP()
714 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
717 while (!quit_loop && SDL_WaitEvent(&event) >=0)
724 if (SDL_PollEvent(&event))
726 /* hier werden die Ereignisse behandelt */
735 case SDL_MOUSEBUTTONDOWN:
737 int x = event.button.x;
738 int y = event.button.y;
740 SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
742 TEST_SDL_BLIT_RECT(x, y);
744 printf("SDL_MOUSEBUTTONDOWN(%d, %d)\n", x, y);
748 case SDL_MOUSEBUTTONUP:
750 int x = event.button.x;
751 int y = event.button.y;
753 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
755 printf("SDL_MOUSEBUTTONUP(%d, %d)\n", x, y);
759 case SDL_MOUSEMOTION:
761 int x = event.motion.x;
762 int y = event.motion.y;
764 TEST_SDL_BLIT_RECT(x, y);
766 printf("SDL_MOUSEMOTION(%d, %d)\n", x, y);
775 if (!SDL_PollEvent(NULL)) /* delay only if no pending events */
777 printf("waiting...\n");
782 SDL_FreeSurface(sdl_image);
786 #define SCREEN_WIDTH 640
787 #define SCREEN_HEIGHT 480
789 void WatchJoysticks()
796 SDL_Rect axis_area[2];
798 SDL_Joystick *joystick = Get_SDL_Joystick(joystick_nr);
800 /* Set a video mode to display joystick axis position */
801 screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16, 0);
802 if ( screen == NULL ) {
803 fprintf(stderr, "Couldn't set video mode: %s\n",SDL_GetError());
807 /* Print info about the joysticks we are watching */
810 joystick = Get_SDL_Joystick(i);
812 name = SDL_JoystickName(i);
813 printf("Watching joystick %d: (%s)\n", i,
814 name ? name : "Unknown Joystick");
815 printf("Joystick has %d axes, %d hats, %d balls, and %d buttons\n",
816 SDL_JoystickNumAxes(joystick),
817 SDL_JoystickNumHats(joystick),
818 SDL_JoystickNumBalls(joystick),
819 SDL_JoystickNumButtons(joystick));
822 /* Initialize drawing rectangles */
823 memset(axis_area, 0, (sizeof axis_area));
826 /* Loop, getting joystick events! */
829 while ( SDL_PollEvent(&event) ) {
830 switch (event.type) {
831 case SDL_JOYAXISMOTION:
832 joystick_nr = event.jaxis.which;
833 printf("Joystick %d axis %d value: %d\n",
838 case SDL_JOYHATMOTION:
839 joystick_nr = event.jaxis.which;
840 printf("Joystick %d hat %d value:",
843 if ( event.jhat.value == SDL_HAT_CENTERED )
845 if ( event.jhat.value & SDL_HAT_UP )
847 if ( event.jhat.value & SDL_HAT_RIGHT )
849 if ( event.jhat.value & SDL_HAT_DOWN )
851 if ( event.jhat.value & SDL_HAT_LEFT )
855 case SDL_JOYBALLMOTION:
856 joystick_nr = event.jaxis.which;
857 printf("Joystick %d ball %d delta: (%d,%d)\n",
863 case SDL_JOYBUTTONDOWN:
864 joystick_nr = event.jaxis.which;
865 printf("Joystick %d button %d down\n",
867 event.jbutton.button);
869 case SDL_JOYBUTTONUP:
870 joystick_nr = event.jaxis.which;
871 printf("Joystick %d button %d up\n",
873 event.jbutton.button);
876 if ( event.key.keysym.sym != SDLK_ESCAPE ) {
879 /* Fall through to signal quit */
888 joystick = Get_SDL_Joystick(joystick_nr);
890 /* Update visual joystick state */
891 for ( i=0; i<SDL_JoystickNumButtons(joystick); ++i ) {
895 area.y = SCREEN_HEIGHT-34;
898 if (SDL_JoystickGetButton(joystick, i) == SDL_PRESSED) {
899 SDL_FillRect(screen, &area, 0xFFFF);
901 SDL_FillRect(screen, &area, 0x0000);
903 SDL_UpdateRects(screen, 1, &area);
906 /* Erase previous axes */
907 SDL_FillRect(screen, &axis_area[draw], 0x0000);
909 /* Draw the X/Y axis */
911 x = (((int)SDL_JoystickGetAxis(joystick, 0))+32768);
917 if ( x > (SCREEN_WIDTH-16) ) {
920 y = (((int)SDL_JoystickGetAxis(joystick, 1))+32768);
926 if ( y > (SCREEN_HEIGHT-16) ) {
927 y = SCREEN_HEIGHT-16;
929 axis_area[draw].x = (Sint16)x;
930 axis_area[draw].y = (Sint16)y;
931 axis_area[draw].w = 16;
932 axis_area[draw].h = 16;
933 SDL_FillRect(screen, &axis_area[draw], 0xFFFF);
935 SDL_UpdateRects(screen, 2, axis_area);
939 void TEST_SDL_JOYSTICK()
944 /* Initialize SDL (Note: video is required to start event loop) */
945 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 )
947 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
951 /* Print information about the joysticks */
952 printf("There are %d joysticks attached\n", SDL_NumJoysticks());
953 for ( i=0; i<SDL_NumJoysticks(); ++i )
955 name = SDL_JoystickName(i);
956 printf("Joystick %d: %s\n",i,name ? name : "Unknown Joystick");
961 if (!Open_SDL_Joystick(i))
962 printf("Couldn't open joystick %d: %s\n", i, SDL_GetError());
968 Close_SDL_Joystick(i);
970 SDL_QuitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
973 #endif /* TARGET_SDL */
975 /* +-----------------------------------------------------------------------+ */
976 /* | SDL TEST STUFF | */
977 /* +-----------------------------------------------------------------------+ */
981 int main(int argc, char *argv[])
983 program_name = (strrchr(argv[0],'/') ? strrchr(argv[0],'/') + 1 : argv[0]);
985 #if defined(PLATFORM_MSDOS)
997 TEST_SDL_BLIT_RECT((WIN_XSIZE - TILEX)/2, (WIN_YSIZE - TILEY)/2);
998 TEST_SDL_EVENT_LOOP();
1000 TEST_SDL_JOYSTICK();
1007 exit(0); /* to keep compilers happy */