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"
23 #if defined(PLATFORM_MSDOS)
29 DrawWindow window = None;
30 DrawBuffer backbuffer;
35 GC clip_gc[NUM_BITMAPS];
38 Bitmap pix[NUM_BITMAPS];
40 Bitmap pix_masked[NUM_BITMAPS];
42 Bitmap tile_masked[NUM_TILES];
44 Pixmap clipmask[NUM_BITMAPS];
46 Pixmap tile_clipmask[NUM_TILES];
52 DrawBuffer drawto_field, fieldbuffer;
58 char *sound_device_name = AUDIO_DEVICE;
61 int joystick_device = 0;
62 char *joystick_device_name[MAX_PLAYERS] =
71 char *program_name = NULL;
74 int game_status = MAINMENU;
75 boolean level_editor_test_game = FALSE;
76 boolean network_playing = FALSE;
79 int button_status = MB_NOT_PRESSED;
80 boolean motion_status = FALSE;
83 int key_joystick_mapping = 0;
84 int global_joystick_status = JOYSTICK_STATUS;
85 int joystick_status = JOYSTICK_STATUS;
88 boolean fullscreen_available = FULLSCREEN_STATUS;
89 boolean fullscreen_enabled = FALSE;
92 boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
93 int redraw_x1 = 0, redraw_y1 = 0;
100 short Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
101 short Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
102 short MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
103 short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
104 short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
105 short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
106 short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
107 short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
108 short Frame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
109 boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
110 short JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
111 short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
112 short AmoebaCnt[MAX_NUM_AMOEBA], AmoebaCnt2[MAX_NUM_AMOEBA];
113 unsigned long Elementeigenschaften1[MAX_ELEMENTS];
114 unsigned long Elementeigenschaften2[MAX_ELEMENTS];
117 int lev_fieldx,lev_fieldy, scroll_x,scroll_y;
119 int FX = SX, FY = SY, ScrollStepSize;
120 int ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0;
121 int ScreenGfxPos = 0;
122 int BorderElement = EL_BETON;
123 int GameFrameDelay = GAME_FRAME_DELAY;
124 int FfwdFrameDelay = FFWD_FRAME_DELAY;
125 int BX1 = 0, BY1 = 0, BX2 = SCR_FIELDX-1, BY2 = SCR_FIELDY-1;
126 int SBX_Left, SBX_Right;
127 int SBY_Upper, SBY_Lower;
128 int ZX,ZY, ExitX,ExitY;
135 int TimeFrames, TimePlayed, TimeLeft;
137 boolean network_player_action_received = FALSE;
140 struct LevelDirInfo *leveldir_first = NULL, *leveldir_current = NULL;
142 struct LevelInfo level;
143 struct PlayerInfo stored_player[MAX_PLAYERS], *local_player = NULL;
144 struct HiScore highscore[MAX_SCORE_ENTRIES];
146 struct SampleInfo Sound[NUM_SOUNDS];
148 struct TapeInfo tape;
151 struct OptionInfo options;
154 struct SetupInfo setup;
155 struct GameInfo game;
158 struct VideoSystemInfo video;
159 struct AudioSystemInfo audio;
162 struct GlobalInfo global;
164 /* data needed for playing sounds */
165 char *sound_name[NUM_SOUNDS] =
231 /* background music */
232 int background_loop[] =
242 int num_bg_loops = sizeof(background_loop)/sizeof(int);
244 char *element_info[] =
246 "empty space", /* 0 */
256 "spaceship", /* 10 */
263 "quicksand with rock",
266 "magic wall", /* 20 */
276 "magic wheel", /* 30 */
286 "gray door (opened by red key)", /* 40 */
287 "gray door (opened by yellow key)",
288 "gray door (opened by green key)",
289 "gray door (opened by blue key)",
292 "invisible normal wall",
294 "ligh bulb (glowing)",
296 "wall with diamond", /* 50 */
297 "amoeba with content",
302 "diamond (BD style)",
304 "wall with BD style diamond",
305 "wall with yellow emerald",
306 "dark yam yam", /* 60 */
307 "magic wall (BD style)",
308 "invisible steel wall",
310 "increases number of bombs",
311 "increases explosion size",
312 "increases power of explosion",
314 "sokoban empty field",
315 "sokoban field with object",
316 "butterfly (starts moving right)", /* 70 */
317 "butterfly (starts moving up)",
318 "butterfly (starts moving left)",
319 "butterfly (starts moving down)",
320 "firefly (starts moving right)",
321 "firefly (starts moving up)",
322 "firefly (starts moving left)",
323 "firefly (starts moving down)",
326 "yellow player", /* 80 */
330 "bug (starts moving right)",
331 "bug (starts moving up)",
332 "bug (starts moving left)",
333 "bug (starts moving down)",
334 "spaceship (starts moving right)",
335 "spaceship (starts moving up)",
336 "spaceship (starts moving left)", /* 90 */
337 "spaceship (starts moving down)",
338 "pac man (starts moving right)",
339 "pac man (starts moving up)",
340 "pac man (starts moving left)",
341 "pac man (starts moving down)",
344 "wall with red emerald",
345 "wall with violet emerald",
351 "normal wall (BD style)",
364 "fire breathing dragon",
366 "letter ' '", /* 120 */
376 "letter '*'", /* 130 */
386 "letter '4'", /* 140 */
396 "letter '>'", /* 150 */
406 "letter 'H'", /* 160 */
416 "letter 'R'", /* 170 */
426 "letter 'Ö'", /* 180 */
436 "letter ''", /* 190 */
446 "growing wall (horizontal)", /* 200 */
447 "growing wall (vertical)",
448 "growing wall (all directions)",
456 "empty space", /* 210 */
465 "port (leading right)",
466 "port (leading down)", /* 220 */
467 "port (leading left)",
469 "port (leading right)",
470 "port (leading down)",
471 "port (leading left)",
476 "red disk", /* 230 */
479 "port (all directions)",
486 "hardware", /* 240 */
509 "white door", /* 260 */
510 "gray door (opened by white key)",
514 "switch gate (open)",
515 "switch gate (closed)",
516 "switch for switch gate",
517 "switch for switch gate",
520 "red conveyor belt (left)",
521 "red conveyor belt (middle)",
522 "red conveyor belt (right)",
523 "switch for red conveyor belt (left)",
524 "switch for red conveyor belt (middle)",
525 "switch for red conveyor belt (right)",
526 "yellow conveyor belt (left)",
527 "yellow conveyor belt (middle)",
528 "yellow conveyor belt (right)",
529 "switch for yellow conveyor belt (left)", /* 280 */
530 "switch for yellow conveyor belt (middle)",
531 "switch for yellow conveyor belt (right)",
532 "green conveyor belt (left)",
533 "green conveyor belt (middle)",
534 "green conveyor belt (right)",
535 "switch for green conveyor belt (left)",
536 "switch for green conveyor belt (middle)",
537 "switch for green conveyor belt (right)",
538 "blue conveyor belt (left)",
539 "blue conveyor belt (middle)", /* 290 */
540 "blue conveyor belt (right)",
541 "switch for blue conveyor belt (left)",
542 "switch for blue conveyor belt (middle)",
543 "switch for blue conveyor belt (right)",
546 "light switch (off)",
548 "sign (exclamation)",
549 "sign (radio activity)", /* 300 */
551 "sign (wheel chair)",
559 "sign (other)", /* 310 */
560 "mole (starts moving left)",
561 "mole (starts moving right)",
562 "mole (starts moving up)",
563 "mole (starts moving down)",
564 "steel wall (slanted)",
570 "shield (active, kills enemies)",
572 "time gate (closed)",
573 "switch for time gate",
574 "switch for time gate",
576 "send balloon to the left",
577 "send balloon to the right",
579 "send balloon down", /* 330 */
580 "send balloon in any direction",
589 "normal wall", /* 340 */
593 "tube (all directions)",
596 "tube (vertical & left)",
597 "tube (vertical & right)",
598 "tube (horizontal & up)",
599 "tube (horizontal & down)", /* 350 */
601 "tube (left & down)",
603 "tube (right & down)",
606 "stable bomb (DX style)",
610 "-------------------------------",
613 int num_element_info = sizeof(element_info)/sizeof(char *);
619 /* +-----------------------------------------------------------------------+ */
620 /* | SDL TEST STUFF | */
621 /* +-----------------------------------------------------------------------+ */
623 #if defined(TARGET_SDL)
625 SDL_Surface *sdl_screen, *sdl_image_tmp, *sdl_image, *sdl_image_masked;
626 SDL_Surface *sdl_image2_tmp, *sdl_image2, *sdl_image2_masked;
628 void TEST_SDL_BLIT_RECT(int x, int y)
630 SDL_Rect rect_src, rect_dst;
632 SDLCopyArea(pix_masked[PIX_HEROES], window,
633 8 * TILEX, 8 * TILEY, TILEX, TILEY, x, y);
636 rect_src.x = 8 * TILEX;
637 rect_src.y = 8 * TILEY;
646 SDL_BlitSurface(sdl_image2_masked, &rect_src, sdl_screen, &rect_dst);
647 SDL_UpdateRect(sdl_screen, x, y, TILEX, TILEY);
650 void TEST_SDL_INIT_DISPLAY()
652 SDL_Rect rect_src, rect_dst;
654 if (SDL_Init(SDL_INIT_VIDEO) < 0)
656 fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError());
660 /* automatically cleanup SDL stuff after exit() */
663 if ((sdl_screen = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, 16, SDL_HWSURFACE))
666 fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
670 SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING);
672 if ((sdl_image_tmp = IMG_Load("graphics/RocksScreen.pcx")) == NULL)
674 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
678 sdl_image = SDL_DisplayFormat(sdl_image_tmp);
680 SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY,
681 SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
682 sdl_image_masked = SDL_DisplayFormat(sdl_image_tmp);
684 SDL_FreeSurface(sdl_image_tmp);
686 if ((sdl_image2_tmp = IMG_Load("graphics/RocksHeroes.pcx")) == NULL)
688 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
692 sdl_image2 = SDL_DisplayFormat(sdl_image2_tmp);
693 SDL_FreeSurface(sdl_image2_tmp);
695 sdl_image2_masked = SDL_DisplayFormat(sdl_image2);
696 SDL_SetColorKey(sdl_image2_masked, SDL_SRCCOLORKEY,
697 SDL_MapRGB(sdl_image2_masked->format, 0x00, 0x00, 0x00));
701 rect_src.w = sdl_image->w;
702 rect_src.h = sdl_image->h;
706 rect_dst.w = sdl_image->w;
707 rect_dst.h = sdl_image->h;
709 SDL_BlitSurface(sdl_image, &rect_src, sdl_screen, &rect_dst);
712 SDL_UpdateRect(sdl_screen, 0, 0, WIN_XSIZE, WIN_YSIZE);
715 SDL_UpdateRect(sdl_screen, 0, 0, 0, 0);
717 SDL_Flip(sdl_screen);
724 void TEST_SDL_EVENT_LOOP()
728 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
731 while (!quit_loop && SDL_WaitEvent(&event) >=0)
738 if (SDL_PollEvent(&event))
740 /* hier werden die Ereignisse behandelt */
749 case SDL_MOUSEBUTTONDOWN:
751 int x = event.button.x;
752 int y = event.button.y;
754 SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
756 TEST_SDL_BLIT_RECT(x, y);
758 printf("SDL_MOUSEBUTTONDOWN(%d, %d)\n", x, y);
762 case SDL_MOUSEBUTTONUP:
764 int x = event.button.x;
765 int y = event.button.y;
767 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
769 printf("SDL_MOUSEBUTTONUP(%d, %d)\n", x, y);
773 case SDL_MOUSEMOTION:
775 int x = event.motion.x;
776 int y = event.motion.y;
778 TEST_SDL_BLIT_RECT(x, y);
780 printf("SDL_MOUSEMOTION(%d, %d)\n", x, y);
789 if (!SDL_PollEvent(NULL)) /* delay only if no pending events */
791 printf("waiting...\n");
796 SDL_FreeSurface(sdl_image);
800 #define SCREEN_WIDTH 640
801 #define SCREEN_HEIGHT 480
803 void WatchJoysticks()
810 SDL_Rect axis_area[2];
812 SDL_Joystick *joystick = Get_SDL_Joystick(joystick_nr);
814 /* Set a video mode to display joystick axis position */
815 screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16, 0);
816 if ( screen == NULL ) {
817 fprintf(stderr, "Couldn't set video mode: %s\n",SDL_GetError());
821 /* Print info about the joysticks we are watching */
824 joystick = Get_SDL_Joystick(i);
826 name = SDL_JoystickName(i);
827 printf("Watching joystick %d: (%s)\n", i,
828 name ? name : "Unknown Joystick");
829 printf("Joystick has %d axes, %d hats, %d balls, and %d buttons\n",
830 SDL_JoystickNumAxes(joystick),
831 SDL_JoystickNumHats(joystick),
832 SDL_JoystickNumBalls(joystick),
833 SDL_JoystickNumButtons(joystick));
836 /* Initialize drawing rectangles */
837 memset(axis_area, 0, (sizeof axis_area));
840 /* Loop, getting joystick events! */
843 while ( SDL_PollEvent(&event) ) {
844 switch (event.type) {
845 case SDL_JOYAXISMOTION:
846 joystick_nr = event.jaxis.which;
847 printf("Joystick %d axis %d value: %d\n",
852 case SDL_JOYHATMOTION:
853 joystick_nr = event.jaxis.which;
854 printf("Joystick %d hat %d value:",
857 if ( event.jhat.value == SDL_HAT_CENTERED )
859 if ( event.jhat.value & SDL_HAT_UP )
861 if ( event.jhat.value & SDL_HAT_RIGHT )
863 if ( event.jhat.value & SDL_HAT_DOWN )
865 if ( event.jhat.value & SDL_HAT_LEFT )
869 case SDL_JOYBALLMOTION:
870 joystick_nr = event.jaxis.which;
871 printf("Joystick %d ball %d delta: (%d,%d)\n",
877 case SDL_JOYBUTTONDOWN:
878 joystick_nr = event.jaxis.which;
879 printf("Joystick %d button %d down\n",
881 event.jbutton.button);
883 case SDL_JOYBUTTONUP:
884 joystick_nr = event.jaxis.which;
885 printf("Joystick %d button %d up\n",
887 event.jbutton.button);
890 if ( event.key.keysym.sym != SDLK_ESCAPE ) {
893 /* Fall through to signal quit */
902 joystick = Get_SDL_Joystick(joystick_nr);
904 /* Update visual joystick state */
905 for ( i=0; i<SDL_JoystickNumButtons(joystick); ++i ) {
909 area.y = SCREEN_HEIGHT-34;
912 if (SDL_JoystickGetButton(joystick, i) == SDL_PRESSED) {
913 SDL_FillRect(screen, &area, 0xFFFF);
915 SDL_FillRect(screen, &area, 0x0000);
917 SDL_UpdateRects(screen, 1, &area);
920 /* Erase previous axes */
921 SDL_FillRect(screen, &axis_area[draw], 0x0000);
923 /* Draw the X/Y axis */
925 x = (((int)SDL_JoystickGetAxis(joystick, 0))+32768);
931 if ( x > (SCREEN_WIDTH-16) ) {
934 y = (((int)SDL_JoystickGetAxis(joystick, 1))+32768);
940 if ( y > (SCREEN_HEIGHT-16) ) {
941 y = SCREEN_HEIGHT-16;
943 axis_area[draw].x = (Sint16)x;
944 axis_area[draw].y = (Sint16)y;
945 axis_area[draw].w = 16;
946 axis_area[draw].h = 16;
947 SDL_FillRect(screen, &axis_area[draw], 0xFFFF);
949 SDL_UpdateRects(screen, 2, axis_area);
953 void TEST_SDL_JOYSTICK()
958 /* Initialize SDL (Note: video is required to start event loop) */
959 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 )
961 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
965 /* Print information about the joysticks */
966 printf("There are %d joysticks attached\n", SDL_NumJoysticks());
967 for ( i=0; i<SDL_NumJoysticks(); ++i )
969 name = SDL_JoystickName(i);
970 printf("Joystick %d: %s\n",i,name ? name : "Unknown Joystick");
975 if (!Open_SDL_Joystick(i))
976 printf("Couldn't open joystick %d: %s\n", i, SDL_GetError());
982 Close_SDL_Joystick(i);
984 SDL_QuitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
987 #endif /* TARGET_SDL */
989 /* +-----------------------------------------------------------------------+ */
990 /* | SDL TEST STUFF | */
991 /* +-----------------------------------------------------------------------+ */
997 int main(int argc, char *argv[])
1000 program_name = (strrchr(argv[0],'/') ? strrchr(argv[0],'/') + 1 : argv[0]);
1003 InitCommandName(argv[0]);
1004 InitExitFunction(CloseAllAndExit);
1005 InitPlatformDependantStuff();
1008 #if defined(PLATFORM_MSDOS)
1021 TEST_SDL_BLIT_RECT((WIN_XSIZE - TILEX)/2, (WIN_YSIZE - TILEY)/2);
1022 TEST_SDL_EVENT_LOOP();
1024 TEST_SDL_JOYSTICK();
1031 exit(0); /* to keep compilers happy */