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 *);
607 /* +-----------------------------------------------------------------------+ */
608 /* | SDL TEST STUFF | */
609 /* +-----------------------------------------------------------------------+ */
611 #if defined(TARGET_SDL)
613 SDL_Surface *sdl_screen, *sdl_image_tmp, *sdl_image, *sdl_image_masked;
614 SDL_Surface *sdl_image2_tmp, *sdl_image2, *sdl_image2_masked;
616 void TEST_SDL_BLIT_RECT(int x, int y)
618 SDL_Rect rect_src, rect_dst;
620 SDLCopyArea(pix_masked[PIX_HEROES], window,
621 8 * TILEX, 8 * TILEY, TILEX, TILEY, x, y);
624 rect_src.x = 8 * TILEX;
625 rect_src.y = 8 * TILEY;
634 SDL_BlitSurface(sdl_image2_masked, &rect_src, sdl_screen, &rect_dst);
635 SDL_UpdateRect(sdl_screen, x, y, TILEX, TILEY);
638 void TEST_SDL_INIT_DISPLAY()
640 SDL_Rect rect_src, rect_dst;
642 if (SDL_Init(SDL_INIT_VIDEO) < 0)
644 fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError());
648 /* automatically cleanup SDL stuff after exit() */
651 if ((sdl_screen = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, 16, SDL_HWSURFACE))
654 fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
658 SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING);
660 if ((sdl_image_tmp = IMG_Load("graphics/RocksScreen.pcx")) == NULL)
662 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
666 sdl_image = SDL_DisplayFormat(sdl_image_tmp);
668 SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY,
669 SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
670 sdl_image_masked = SDL_DisplayFormat(sdl_image_tmp);
672 SDL_FreeSurface(sdl_image_tmp);
674 if ((sdl_image2_tmp = IMG_Load("graphics/RocksHeroes.pcx")) == NULL)
676 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
680 sdl_image2 = SDL_DisplayFormat(sdl_image2_tmp);
681 SDL_FreeSurface(sdl_image2_tmp);
683 sdl_image2_masked = SDL_DisplayFormat(sdl_image2);
684 SDL_SetColorKey(sdl_image2_masked, SDL_SRCCOLORKEY,
685 SDL_MapRGB(sdl_image2_masked->format, 0x00, 0x00, 0x00));
689 rect_src.w = sdl_image->w;
690 rect_src.h = sdl_image->h;
694 rect_dst.w = sdl_image->w;
695 rect_dst.h = sdl_image->h;
697 SDL_BlitSurface(sdl_image, &rect_src, sdl_screen, &rect_dst);
700 SDL_UpdateRect(sdl_screen, 0, 0, WIN_XSIZE, WIN_YSIZE);
703 SDL_UpdateRect(sdl_screen, 0, 0, 0, 0);
705 SDL_Flip(sdl_screen);
712 void TEST_SDL_EVENT_LOOP()
716 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
719 while (!quit_loop && SDL_WaitEvent(&event) >=0)
726 if (SDL_PollEvent(&event))
728 /* hier werden die Ereignisse behandelt */
737 case SDL_MOUSEBUTTONDOWN:
739 int x = event.button.x;
740 int y = event.button.y;
742 SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
744 TEST_SDL_BLIT_RECT(x, y);
746 printf("SDL_MOUSEBUTTONDOWN(%d, %d)\n", x, y);
750 case SDL_MOUSEBUTTONUP:
752 int x = event.button.x;
753 int y = event.button.y;
755 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
757 printf("SDL_MOUSEBUTTONUP(%d, %d)\n", x, y);
761 case SDL_MOUSEMOTION:
763 int x = event.motion.x;
764 int y = event.motion.y;
766 TEST_SDL_BLIT_RECT(x, y);
768 printf("SDL_MOUSEMOTION(%d, %d)\n", x, y);
777 if (!SDL_PollEvent(NULL)) /* delay only if no pending events */
779 printf("waiting...\n");
784 SDL_FreeSurface(sdl_image);
788 #define SCREEN_WIDTH 640
789 #define SCREEN_HEIGHT 480
791 void WatchJoysticks()
798 SDL_Rect axis_area[2];
800 SDL_Joystick *joystick = Get_SDL_Joystick(joystick_nr);
802 /* Set a video mode to display joystick axis position */
803 screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16, 0);
804 if ( screen == NULL ) {
805 fprintf(stderr, "Couldn't set video mode: %s\n",SDL_GetError());
809 /* Print info about the joysticks we are watching */
812 joystick = Get_SDL_Joystick(i);
814 name = SDL_JoystickName(i);
815 printf("Watching joystick %d: (%s)\n", i,
816 name ? name : "Unknown Joystick");
817 printf("Joystick has %d axes, %d hats, %d balls, and %d buttons\n",
818 SDL_JoystickNumAxes(joystick),
819 SDL_JoystickNumHats(joystick),
820 SDL_JoystickNumBalls(joystick),
821 SDL_JoystickNumButtons(joystick));
824 /* Initialize drawing rectangles */
825 memset(axis_area, 0, (sizeof axis_area));
828 /* Loop, getting joystick events! */
831 while ( SDL_PollEvent(&event) ) {
832 switch (event.type) {
833 case SDL_JOYAXISMOTION:
834 joystick_nr = event.jaxis.which;
835 printf("Joystick %d axis %d value: %d\n",
840 case SDL_JOYHATMOTION:
841 joystick_nr = event.jaxis.which;
842 printf("Joystick %d hat %d value:",
845 if ( event.jhat.value == SDL_HAT_CENTERED )
847 if ( event.jhat.value & SDL_HAT_UP )
849 if ( event.jhat.value & SDL_HAT_RIGHT )
851 if ( event.jhat.value & SDL_HAT_DOWN )
853 if ( event.jhat.value & SDL_HAT_LEFT )
857 case SDL_JOYBALLMOTION:
858 joystick_nr = event.jaxis.which;
859 printf("Joystick %d ball %d delta: (%d,%d)\n",
865 case SDL_JOYBUTTONDOWN:
866 joystick_nr = event.jaxis.which;
867 printf("Joystick %d button %d down\n",
869 event.jbutton.button);
871 case SDL_JOYBUTTONUP:
872 joystick_nr = event.jaxis.which;
873 printf("Joystick %d button %d up\n",
875 event.jbutton.button);
878 if ( event.key.keysym.sym != SDLK_ESCAPE ) {
881 /* Fall through to signal quit */
890 joystick = Get_SDL_Joystick(joystick_nr);
892 /* Update visual joystick state */
893 for ( i=0; i<SDL_JoystickNumButtons(joystick); ++i ) {
897 area.y = SCREEN_HEIGHT-34;
900 if (SDL_JoystickGetButton(joystick, i) == SDL_PRESSED) {
901 SDL_FillRect(screen, &area, 0xFFFF);
903 SDL_FillRect(screen, &area, 0x0000);
905 SDL_UpdateRects(screen, 1, &area);
908 /* Erase previous axes */
909 SDL_FillRect(screen, &axis_area[draw], 0x0000);
911 /* Draw the X/Y axis */
913 x = (((int)SDL_JoystickGetAxis(joystick, 0))+32768);
919 if ( x > (SCREEN_WIDTH-16) ) {
922 y = (((int)SDL_JoystickGetAxis(joystick, 1))+32768);
928 if ( y > (SCREEN_HEIGHT-16) ) {
929 y = SCREEN_HEIGHT-16;
931 axis_area[draw].x = (Sint16)x;
932 axis_area[draw].y = (Sint16)y;
933 axis_area[draw].w = 16;
934 axis_area[draw].h = 16;
935 SDL_FillRect(screen, &axis_area[draw], 0xFFFF);
937 SDL_UpdateRects(screen, 2, axis_area);
941 void TEST_SDL_JOYSTICK()
946 /* Initialize SDL (Note: video is required to start event loop) */
947 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 )
949 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
953 /* Print information about the joysticks */
954 printf("There are %d joysticks attached\n", SDL_NumJoysticks());
955 for ( i=0; i<SDL_NumJoysticks(); ++i )
957 name = SDL_JoystickName(i);
958 printf("Joystick %d: %s\n",i,name ? name : "Unknown Joystick");
963 if (!Open_SDL_Joystick(i))
964 printf("Couldn't open joystick %d: %s\n", i, SDL_GetError());
970 Close_SDL_Joystick(i);
972 SDL_QuitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
975 #endif /* TARGET_SDL */
977 /* +-----------------------------------------------------------------------+ */
978 /* | SDL TEST STUFF | */
979 /* +-----------------------------------------------------------------------+ */
985 int main(int argc, char *argv[])
987 program_name = (strrchr(argv[0],'/') ? strrchr(argv[0],'/') + 1 : argv[0]);
989 #if defined(PLATFORM_MSDOS)
1001 TEST_SDL_BLIT_RECT((WIN_XSIZE - TILEX)/2, (WIN_YSIZE - TILEY)/2);
1002 TEST_SDL_EVENT_LOOP();
1004 TEST_SDL_JOYSTICK();
1011 exit(0); /* to keep compilers happy */