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;
75 int button_status = MB_NOT_PRESSED;
76 boolean motion_status = FALSE;
79 int key_joystick_mapping = 0;
80 int global_joystick_status = JOYSTICK_STATUS;
81 int joystick_status = JOYSTICK_STATUS;
84 boolean fullscreen_available = FULLSCREEN_STATUS;
85 boolean fullscreen_enabled = FALSE;
88 boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
89 int redraw_x1 = 0, redraw_y1 = 0;
96 short Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
97 short Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
98 short MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
99 short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
100 short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
101 short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
102 short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
103 short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
104 short Frame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
105 boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
106 short JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
107 short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
108 short AmoebaCnt[MAX_NUM_AMOEBA], AmoebaCnt2[MAX_NUM_AMOEBA];
109 unsigned long Elementeigenschaften1[MAX_ELEMENTS];
110 unsigned long Elementeigenschaften2[MAX_ELEMENTS];
113 int lev_fieldx,lev_fieldy, scroll_x,scroll_y;
115 int FX = SX, FY = SY, ScrollStepSize;
116 int ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0;
117 int ScreenGfxPos = 0;
118 int BorderElement = EL_BETON;
119 int GameFrameDelay = GAME_FRAME_DELAY;
120 int FfwdFrameDelay = FFWD_FRAME_DELAY;
121 int BX1 = 0, BY1 = 0, BX2 = SCR_FIELDX-1, BY2 = SCR_FIELDY-1;
122 int SBX_Left, SBX_Right;
123 int SBY_Upper, SBY_Lower;
124 int ZX,ZY, ExitX,ExitY;
131 int TimeFrames, TimePlayed, TimeLeft;
133 boolean network_player_action_received = FALSE;
135 struct LevelDirInfo *leveldir_first = NULL, *leveldir_current = NULL;
136 struct LevelInfo level;
137 struct PlayerInfo stored_player[MAX_PLAYERS], *local_player = NULL;
138 struct HiScore highscore[MAX_SCORE_ENTRIES];
139 struct SampleInfo Sound[NUM_SOUNDS];
140 struct TapeInfo tape;
143 struct OptionInfo options;
146 struct SetupInfo setup;
147 struct GameInfo game;
150 struct VideoSystemInfo video;
151 struct AudioSystemInfo audio;
154 struct GlobalInfo global;
156 /* data needed for playing sounds */
157 char *sound_name[NUM_SOUNDS] =
223 /* background music */
224 int background_loop[] =
234 int num_bg_loops = sizeof(background_loop)/sizeof(int);
236 char *element_info[] =
238 "empty space", /* 0 */
248 "spaceship", /* 10 */
255 "quicksand with rock",
258 "magic wall", /* 20 */
268 "magic wheel", /* 30 */
278 "gray door (opened by red key)", /* 40 */
279 "gray door (opened by yellow key)",
280 "gray door (opened by green key)",
281 "gray door (opened by blue key)",
284 "invisible normal wall",
286 "ligh bulb (glowing)",
288 "wall with diamond", /* 50 */
289 "amoeba with content",
294 "diamond (BD style)",
296 "wall with BD style diamond",
297 "wall with yellow emerald",
298 "dark yam yam", /* 60 */
299 "magic wall (BD style)",
300 "invisible steel wall",
302 "increases number of bombs",
303 "increases explosion size",
304 "increases power of explosion",
306 "sokoban empty field",
307 "sokoban field with object",
308 "butterfly (starts moving right)", /* 70 */
309 "butterfly (starts moving up)",
310 "butterfly (starts moving left)",
311 "butterfly (starts moving down)",
312 "firefly (starts moving right)",
313 "firefly (starts moving up)",
314 "firefly (starts moving left)",
315 "firefly (starts moving down)",
318 "yellow player", /* 80 */
322 "bug (starts moving right)",
323 "bug (starts moving up)",
324 "bug (starts moving left)",
325 "bug (starts moving down)",
326 "spaceship (starts moving right)",
327 "spaceship (starts moving up)",
328 "spaceship (starts moving left)", /* 90 */
329 "spaceship (starts moving down)",
330 "pac man (starts moving right)",
331 "pac man (starts moving up)",
332 "pac man (starts moving left)",
333 "pac man (starts moving down)",
336 "wall with red emerald",
337 "wall with violet emerald",
343 "normal wall (BD style)",
356 "fire breathing dragon",
358 "letter ' '", /* 120 */
368 "letter '*'", /* 130 */
378 "letter '4'", /* 140 */
388 "letter '>'", /* 150 */
398 "letter 'H'", /* 160 */
408 "letter 'R'", /* 170 */
418 "letter 'Ö'", /* 180 */
428 "letter ''", /* 190 */
438 "growing wall (horizontal)", /* 200 */
439 "growing wall (vertical)",
440 "growing wall (all directions)",
448 "empty space", /* 210 */
457 "port (leading right)",
458 "port (leading down)", /* 220 */
459 "port (leading left)",
461 "port (leading right)",
462 "port (leading down)",
463 "port (leading left)",
468 "red disk", /* 230 */
471 "port (all directions)",
478 "hardware", /* 240 */
501 "white door", /* 260 */
502 "gray door (opened by white key)",
506 "switch gate (open)",
507 "switch gate (closed)",
508 "switch for switch gate",
509 "switch for switch gate",
512 "red conveyor belt (left)",
513 "red conveyor belt (middle)",
514 "red conveyor belt (right)",
515 "switch for red conveyor belt (left)",
516 "switch for red conveyor belt (middle)",
517 "switch for red conveyor belt (right)",
518 "yellow conveyor belt (left)",
519 "yellow conveyor belt (middle)",
520 "yellow conveyor belt (right)",
521 "switch for yellow conveyor belt (left)", /* 280 */
522 "switch for yellow conveyor belt (middle)",
523 "switch for yellow conveyor belt (right)",
524 "green conveyor belt (left)",
525 "green conveyor belt (middle)",
526 "green conveyor belt (right)",
527 "switch for green conveyor belt (left)",
528 "switch for green conveyor belt (middle)",
529 "switch for green conveyor belt (right)",
530 "blue conveyor belt (left)",
531 "blue conveyor belt (middle)", /* 290 */
532 "blue conveyor belt (right)",
533 "switch for blue conveyor belt (left)",
534 "switch for blue conveyor belt (middle)",
535 "switch for blue conveyor belt (right)",
538 "light switch (off)",
540 "sign (exclamation)",
541 "sign (radio activity)", /* 300 */
543 "sign (wheel chair)",
551 "sign (other)", /* 310 */
552 "mole (starts moving left)",
553 "mole (starts moving right)",
554 "mole (starts moving up)",
555 "mole (starts moving down)",
556 "steel wall (slanted)",
562 "shield (active, kills enemies)",
564 "time gate (closed)",
565 "switch for time gate",
566 "switch for time gate",
568 "send balloon to the left",
569 "send balloon to the right",
571 "send balloon down", /* 330 */
572 "send balloon in any direction",
581 "normal wall", /* 340 */
585 "tube (all directions)",
588 "tube (vertical & left)",
589 "tube (vertical & right)",
590 "tube (horizontal & up)",
591 "tube (horizontal & down)", /* 350 */
593 "tube (left & down)",
595 "tube (right & down)",
598 "stable bomb (DX style)",
602 "-------------------------------",
605 int num_element_info = sizeof(element_info)/sizeof(char *);
611 /* +-----------------------------------------------------------------------+ */
612 /* | SDL TEST STUFF | */
613 /* +-----------------------------------------------------------------------+ */
615 #if defined(TARGET_SDL)
617 SDL_Surface *sdl_screen, *sdl_image_tmp, *sdl_image, *sdl_image_masked;
618 SDL_Surface *sdl_image2_tmp, *sdl_image2, *sdl_image2_masked;
620 void TEST_SDL_BLIT_RECT(int x, int y)
622 SDL_Rect rect_src, rect_dst;
624 SDLCopyArea(pix_masked[PIX_HEROES], window,
625 8 * TILEX, 8 * TILEY, TILEX, TILEY, x, y);
628 rect_src.x = 8 * TILEX;
629 rect_src.y = 8 * TILEY;
638 SDL_BlitSurface(sdl_image2_masked, &rect_src, sdl_screen, &rect_dst);
639 SDL_UpdateRect(sdl_screen, x, y, TILEX, TILEY);
642 void TEST_SDL_INIT_DISPLAY()
644 SDL_Rect rect_src, rect_dst;
646 if (SDL_Init(SDL_INIT_VIDEO) < 0)
648 fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError());
652 /* automatically cleanup SDL stuff after exit() */
655 if ((sdl_screen = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, 16, SDL_HWSURFACE))
658 fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
662 SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING);
664 if ((sdl_image_tmp = IMG_Load("graphics/RocksScreen.pcx")) == NULL)
666 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
670 sdl_image = SDL_DisplayFormat(sdl_image_tmp);
672 SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY,
673 SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
674 sdl_image_masked = SDL_DisplayFormat(sdl_image_tmp);
676 SDL_FreeSurface(sdl_image_tmp);
678 if ((sdl_image2_tmp = IMG_Load("graphics/RocksHeroes.pcx")) == NULL)
680 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
684 sdl_image2 = SDL_DisplayFormat(sdl_image2_tmp);
685 SDL_FreeSurface(sdl_image2_tmp);
687 sdl_image2_masked = SDL_DisplayFormat(sdl_image2);
688 SDL_SetColorKey(sdl_image2_masked, SDL_SRCCOLORKEY,
689 SDL_MapRGB(sdl_image2_masked->format, 0x00, 0x00, 0x00));
693 rect_src.w = sdl_image->w;
694 rect_src.h = sdl_image->h;
698 rect_dst.w = sdl_image->w;
699 rect_dst.h = sdl_image->h;
701 SDL_BlitSurface(sdl_image, &rect_src, sdl_screen, &rect_dst);
704 SDL_UpdateRect(sdl_screen, 0, 0, WIN_XSIZE, WIN_YSIZE);
707 SDL_UpdateRect(sdl_screen, 0, 0, 0, 0);
709 SDL_Flip(sdl_screen);
716 void TEST_SDL_EVENT_LOOP()
720 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
723 while (!quit_loop && SDL_WaitEvent(&event) >=0)
730 if (SDL_PollEvent(&event))
732 /* hier werden die Ereignisse behandelt */
741 case SDL_MOUSEBUTTONDOWN:
743 int x = event.button.x;
744 int y = event.button.y;
746 SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
748 TEST_SDL_BLIT_RECT(x, y);
750 printf("SDL_MOUSEBUTTONDOWN(%d, %d)\n", x, y);
754 case SDL_MOUSEBUTTONUP:
756 int x = event.button.x;
757 int y = event.button.y;
759 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
761 printf("SDL_MOUSEBUTTONUP(%d, %d)\n", x, y);
765 case SDL_MOUSEMOTION:
767 int x = event.motion.x;
768 int y = event.motion.y;
770 TEST_SDL_BLIT_RECT(x, y);
772 printf("SDL_MOUSEMOTION(%d, %d)\n", x, y);
781 if (!SDL_PollEvent(NULL)) /* delay only if no pending events */
783 printf("waiting...\n");
788 SDL_FreeSurface(sdl_image);
792 #define SCREEN_WIDTH 640
793 #define SCREEN_HEIGHT 480
795 void WatchJoysticks()
802 SDL_Rect axis_area[2];
804 SDL_Joystick *joystick = Get_SDL_Joystick(joystick_nr);
806 /* Set a video mode to display joystick axis position */
807 screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16, 0);
808 if ( screen == NULL ) {
809 fprintf(stderr, "Couldn't set video mode: %s\n",SDL_GetError());
813 /* Print info about the joysticks we are watching */
816 joystick = Get_SDL_Joystick(i);
818 name = SDL_JoystickName(i);
819 printf("Watching joystick %d: (%s)\n", i,
820 name ? name : "Unknown Joystick");
821 printf("Joystick has %d axes, %d hats, %d balls, and %d buttons\n",
822 SDL_JoystickNumAxes(joystick),
823 SDL_JoystickNumHats(joystick),
824 SDL_JoystickNumBalls(joystick),
825 SDL_JoystickNumButtons(joystick));
828 /* Initialize drawing rectangles */
829 memset(axis_area, 0, (sizeof axis_area));
832 /* Loop, getting joystick events! */
835 while ( SDL_PollEvent(&event) ) {
836 switch (event.type) {
837 case SDL_JOYAXISMOTION:
838 joystick_nr = event.jaxis.which;
839 printf("Joystick %d axis %d value: %d\n",
844 case SDL_JOYHATMOTION:
845 joystick_nr = event.jaxis.which;
846 printf("Joystick %d hat %d value:",
849 if ( event.jhat.value == SDL_HAT_CENTERED )
851 if ( event.jhat.value & SDL_HAT_UP )
853 if ( event.jhat.value & SDL_HAT_RIGHT )
855 if ( event.jhat.value & SDL_HAT_DOWN )
857 if ( event.jhat.value & SDL_HAT_LEFT )
861 case SDL_JOYBALLMOTION:
862 joystick_nr = event.jaxis.which;
863 printf("Joystick %d ball %d delta: (%d,%d)\n",
869 case SDL_JOYBUTTONDOWN:
870 joystick_nr = event.jaxis.which;
871 printf("Joystick %d button %d down\n",
873 event.jbutton.button);
875 case SDL_JOYBUTTONUP:
876 joystick_nr = event.jaxis.which;
877 printf("Joystick %d button %d up\n",
879 event.jbutton.button);
882 if ( event.key.keysym.sym != SDLK_ESCAPE ) {
885 /* Fall through to signal quit */
894 joystick = Get_SDL_Joystick(joystick_nr);
896 /* Update visual joystick state */
897 for ( i=0; i<SDL_JoystickNumButtons(joystick); ++i ) {
901 area.y = SCREEN_HEIGHT-34;
904 if (SDL_JoystickGetButton(joystick, i) == SDL_PRESSED) {
905 SDL_FillRect(screen, &area, 0xFFFF);
907 SDL_FillRect(screen, &area, 0x0000);
909 SDL_UpdateRects(screen, 1, &area);
912 /* Erase previous axes */
913 SDL_FillRect(screen, &axis_area[draw], 0x0000);
915 /* Draw the X/Y axis */
917 x = (((int)SDL_JoystickGetAxis(joystick, 0))+32768);
923 if ( x > (SCREEN_WIDTH-16) ) {
926 y = (((int)SDL_JoystickGetAxis(joystick, 1))+32768);
932 if ( y > (SCREEN_HEIGHT-16) ) {
933 y = SCREEN_HEIGHT-16;
935 axis_area[draw].x = (Sint16)x;
936 axis_area[draw].y = (Sint16)y;
937 axis_area[draw].w = 16;
938 axis_area[draw].h = 16;
939 SDL_FillRect(screen, &axis_area[draw], 0xFFFF);
941 SDL_UpdateRects(screen, 2, axis_area);
945 void TEST_SDL_JOYSTICK()
950 /* Initialize SDL (Note: video is required to start event loop) */
951 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 )
953 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
957 /* Print information about the joysticks */
958 printf("There are %d joysticks attached\n", SDL_NumJoysticks());
959 for ( i=0; i<SDL_NumJoysticks(); ++i )
961 name = SDL_JoystickName(i);
962 printf("Joystick %d: %s\n",i,name ? name : "Unknown Joystick");
967 if (!Open_SDL_Joystick(i))
968 printf("Couldn't open joystick %d: %s\n", i, SDL_GetError());
974 Close_SDL_Joystick(i);
976 SDL_QuitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
979 #endif /* TARGET_SDL */
981 /* +-----------------------------------------------------------------------+ */
982 /* | SDL TEST STUFF | */
983 /* +-----------------------------------------------------------------------+ */
989 int main(int argc, char *argv[])
991 program_name = (strrchr(argv[0],'/') ? strrchr(argv[0],'/') + 1 : argv[0]);
993 #if defined(PLATFORM_MSDOS)
1005 TEST_SDL_BLIT_RECT((WIN_XSIZE - TILEX)/2, (WIN_YSIZE - TILEY)/2);
1006 TEST_SDL_EVENT_LOOP();
1008 TEST_SDL_JOYSTICK();
1015 exit(0); /* to keep compilers happy */