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;
32 GC clip_gc[NUM_BITMAPS], tile_clip_gc;
33 Bitmap pix[NUM_BITMAPS];
34 Bitmap pix_masked[NUM_BITMAPS], tile_masked[NUM_TILES];
35 Pixmap clipmask[NUM_BITMAPS], tile_clipmask[NUM_TILES];
37 DrawBuffer drawto, drawto_field, fieldbuffer;
43 char *sound_device_name = AUDIO_DEVICE;
46 int joystick_device = 0;
47 char *joystick_device_name[MAX_PLAYERS] =
55 char *program_name = NULL;
57 int game_status = MAINMENU;
58 boolean level_editor_test_game = FALSE;
59 boolean network_playing = FALSE;
60 int button_status = MB_NOT_PRESSED;
61 boolean motion_status = FALSE;
62 int key_joystick_mapping = 0;
63 int global_joystick_status = JOYSTICK_STATUS;
64 int joystick_status = JOYSTICK_STATUS;
67 boolean fullscreen_available = FULLSCREEN_STATUS;
68 boolean fullscreen_enabled = FALSE;
71 boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
72 int redraw_x1 = 0, redraw_y1 = 0;
76 short Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
77 short Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
78 short MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
79 short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
80 short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
81 short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
82 short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
83 short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
84 short Frame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
85 boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
86 short JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
87 short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
88 short AmoebaCnt[MAX_NUM_AMOEBA], AmoebaCnt2[MAX_NUM_AMOEBA];
89 unsigned long Elementeigenschaften1[MAX_ELEMENTS];
90 unsigned long Elementeigenschaften2[MAX_ELEMENTS];
93 int lev_fieldx,lev_fieldy, scroll_x,scroll_y;
95 int FX = SX, FY = SY, ScrollStepSize;
96 int ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0;
98 int BorderElement = EL_BETON;
99 int GameFrameDelay = GAME_FRAME_DELAY;
100 int FfwdFrameDelay = FFWD_FRAME_DELAY;
101 int BX1 = 0, BY1 = 0, BX2 = SCR_FIELDX-1, BY2 = SCR_FIELDY-1;
102 int SBX_Left, SBX_Right;
103 int SBY_Upper, SBY_Lower;
104 int ZX,ZY, ExitX,ExitY;
111 int TimeFrames, TimePlayed, TimeLeft;
113 boolean network_player_action_received = FALSE;
115 struct LevelDirInfo *leveldir_first = NULL, *leveldir_current = NULL;
116 struct LevelInfo level;
117 struct PlayerInfo stored_player[MAX_PLAYERS], *local_player = NULL;
118 struct HiScore highscore[MAX_SCORE_ENTRIES];
119 struct SampleInfo Sound[NUM_SOUNDS];
120 struct TapeInfo tape;
123 struct OptionInfo options;
126 struct SetupInfo setup;
127 struct GameInfo game;
130 struct VideoSystemInfo video;
131 struct AudioSystemInfo audio;
134 struct GlobalInfo global;
136 /* data needed for playing sounds */
137 char *sound_name[NUM_SOUNDS] =
203 /* background music */
204 int background_loop[] =
214 int num_bg_loops = sizeof(background_loop)/sizeof(int);
216 char *element_info[] =
218 "empty space", /* 0 */
228 "spaceship", /* 10 */
235 "quicksand with rock",
238 "magic wall", /* 20 */
248 "magic wheel", /* 30 */
258 "gray door (opened by red key)", /* 40 */
259 "gray door (opened by yellow key)",
260 "gray door (opened by green key)",
261 "gray door (opened by blue key)",
264 "invisible normal wall",
266 "ligh bulb (glowing)",
268 "wall with diamond", /* 50 */
269 "amoeba with content",
274 "diamond (BD style)",
276 "wall with BD style diamond",
277 "wall with yellow emerald",
278 "dark yam yam", /* 60 */
279 "magic wall (BD style)",
280 "invisible steel wall",
282 "increases number of bombs",
283 "increases explosion size",
284 "increases power of explosion",
286 "sokoban empty field",
287 "sokoban field with object",
288 "butterfly (starts moving right)", /* 70 */
289 "butterfly (starts moving up)",
290 "butterfly (starts moving left)",
291 "butterfly (starts moving down)",
292 "firefly (starts moving right)",
293 "firefly (starts moving up)",
294 "firefly (starts moving left)",
295 "firefly (starts moving down)",
298 "yellow player", /* 80 */
302 "bug (starts moving right)",
303 "bug (starts moving up)",
304 "bug (starts moving left)",
305 "bug (starts moving down)",
306 "spaceship (starts moving right)",
307 "spaceship (starts moving up)",
308 "spaceship (starts moving left)", /* 90 */
309 "spaceship (starts moving down)",
310 "pac man (starts moving right)",
311 "pac man (starts moving up)",
312 "pac man (starts moving left)",
313 "pac man (starts moving down)",
316 "wall with red emerald",
317 "wall with violet emerald",
323 "normal wall (BD style)",
336 "fire breathing dragon",
338 "letter ' '", /* 120 */
348 "letter '*'", /* 130 */
358 "letter '4'", /* 140 */
368 "letter '>'", /* 150 */
378 "letter 'H'", /* 160 */
388 "letter 'R'", /* 170 */
398 "letter 'Ö'", /* 180 */
408 "letter ''", /* 190 */
418 "growing wall (horizontal)", /* 200 */
419 "growing wall (vertical)",
420 "growing wall (all directions)",
428 "empty space", /* 210 */
437 "port (leading right)",
438 "port (leading down)", /* 220 */
439 "port (leading left)",
441 "port (leading right)",
442 "port (leading down)",
443 "port (leading left)",
448 "red disk", /* 230 */
451 "port (all directions)",
458 "hardware", /* 240 */
481 "white door", /* 260 */
482 "gray door (opened by white key)",
486 "switch gate (open)",
487 "switch gate (closed)",
488 "switch for switch gate",
489 "switch for switch gate",
492 "red conveyor belt (left)",
493 "red conveyor belt (middle)",
494 "red conveyor belt (right)",
495 "switch for red conveyor belt (left)",
496 "switch for red conveyor belt (middle)",
497 "switch for red conveyor belt (right)",
498 "yellow conveyor belt (left)",
499 "yellow conveyor belt (middle)",
500 "yellow conveyor belt (right)",
501 "switch for yellow conveyor belt (left)", /* 280 */
502 "switch for yellow conveyor belt (middle)",
503 "switch for yellow conveyor belt (right)",
504 "green conveyor belt (left)",
505 "green conveyor belt (middle)",
506 "green conveyor belt (right)",
507 "switch for green conveyor belt (left)",
508 "switch for green conveyor belt (middle)",
509 "switch for green conveyor belt (right)",
510 "blue conveyor belt (left)",
511 "blue conveyor belt (middle)", /* 290 */
512 "blue conveyor belt (right)",
513 "switch for blue conveyor belt (left)",
514 "switch for blue conveyor belt (middle)",
515 "switch for blue conveyor belt (right)",
518 "light switch (off)",
520 "sign (exclamation)",
521 "sign (radio activity)", /* 300 */
523 "sign (wheel chair)",
531 "sign (other)", /* 310 */
532 "mole (starts moving left)",
533 "mole (starts moving right)",
534 "mole (starts moving up)",
535 "mole (starts moving down)",
536 "steel wall (slanted)",
542 "shield (active, kills enemies)",
544 "time gate (closed)",
545 "switch for time gate",
546 "switch for time gate",
548 "send balloon to the left",
549 "send balloon to the right",
551 "send balloon down", /* 330 */
552 "send balloon in any direction",
561 "normal wall", /* 340 */
565 "tube (all directions)",
568 "tube (vertical & left)",
569 "tube (vertical & right)",
570 "tube (horizontal & up)",
571 "tube (horizontal & down)", /* 350 */
573 "tube (left & down)",
575 "tube (right & down)",
578 "stable bomb (DX style)",
582 "-------------------------------",
585 int num_element_info = sizeof(element_info)/sizeof(char *);
589 /* +-----------------------------------------------------------------------+ */
590 /* | SDL TEST STUFF | */
591 /* +-----------------------------------------------------------------------+ */
593 #if defined(TARGET_SDL)
595 SDL_Surface *sdl_screen, *sdl_image_tmp, *sdl_image, *sdl_image_masked;
596 SDL_Surface *sdl_image2_tmp, *sdl_image2, *sdl_image2_masked;
598 void TEST_SDL_BLIT_RECT(int x, int y)
600 SDL_Rect rect_src, rect_dst;
602 SDLCopyArea(pix_masked[PIX_HEROES], window,
603 8 * TILEX, 8 * TILEY, TILEX, TILEY, x, y);
606 rect_src.x = 8 * TILEX;
607 rect_src.y = 8 * TILEY;
616 SDL_BlitSurface(sdl_image2_masked, &rect_src, sdl_screen, &rect_dst);
617 SDL_UpdateRect(sdl_screen, x, y, TILEX, TILEY);
620 void TEST_SDL_INIT_DISPLAY()
622 SDL_Rect rect_src, rect_dst;
624 if (SDL_Init(SDL_INIT_VIDEO) < 0)
626 fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError());
630 /* automatically cleanup SDL stuff after exit() */
633 if ((sdl_screen = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, 16, SDL_HWSURFACE))
636 fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
640 SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING);
642 if ((sdl_image_tmp = IMG_Load("graphics/RocksScreen.pcx")) == NULL)
644 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
648 sdl_image = SDL_DisplayFormat(sdl_image_tmp);
650 SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY,
651 SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
652 sdl_image_masked = SDL_DisplayFormat(sdl_image_tmp);
654 SDL_FreeSurface(sdl_image_tmp);
656 if ((sdl_image2_tmp = IMG_Load("graphics/RocksHeroes.pcx")) == NULL)
658 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
662 sdl_image2 = SDL_DisplayFormat(sdl_image2_tmp);
663 SDL_FreeSurface(sdl_image2_tmp);
665 sdl_image2_masked = SDL_DisplayFormat(sdl_image2);
666 SDL_SetColorKey(sdl_image2_masked, SDL_SRCCOLORKEY,
667 SDL_MapRGB(sdl_image2_masked->format, 0x00, 0x00, 0x00));
671 rect_src.w = sdl_image->w;
672 rect_src.h = sdl_image->h;
676 rect_dst.w = sdl_image->w;
677 rect_dst.h = sdl_image->h;
679 SDL_BlitSurface(sdl_image, &rect_src, sdl_screen, &rect_dst);
682 SDL_UpdateRect(sdl_screen, 0, 0, WIN_XSIZE, WIN_YSIZE);
685 SDL_UpdateRect(sdl_screen, 0, 0, 0, 0);
687 SDL_Flip(sdl_screen);
694 void TEST_SDL_EVENT_LOOP()
698 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
701 while (!quit_loop && SDL_WaitEvent(&event) >=0)
708 if (SDL_PollEvent(&event))
710 /* hier werden die Ereignisse behandelt */
719 case SDL_MOUSEBUTTONDOWN:
721 int x = event.button.x;
722 int y = event.button.y;
724 SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
726 TEST_SDL_BLIT_RECT(x, y);
728 printf("SDL_MOUSEBUTTONDOWN(%d, %d)\n", x, y);
732 case SDL_MOUSEBUTTONUP:
734 int x = event.button.x;
735 int y = event.button.y;
737 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
739 printf("SDL_MOUSEBUTTONUP(%d, %d)\n", x, y);
743 case SDL_MOUSEMOTION:
745 int x = event.motion.x;
746 int y = event.motion.y;
748 TEST_SDL_BLIT_RECT(x, y);
750 printf("SDL_MOUSEMOTION(%d, %d)\n", x, y);
759 if (!SDL_PollEvent(NULL)) /* delay only if no pending events */
761 printf("waiting...\n");
766 SDL_FreeSurface(sdl_image);
770 #define SCREEN_WIDTH 640
771 #define SCREEN_HEIGHT 480
773 void WatchJoysticks()
780 SDL_Rect axis_area[2];
782 SDL_Joystick *joystick = Get_SDL_Joystick(joystick_nr);
784 /* Set a video mode to display joystick axis position */
785 screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16, 0);
786 if ( screen == NULL ) {
787 fprintf(stderr, "Couldn't set video mode: %s\n",SDL_GetError());
791 /* Print info about the joysticks we are watching */
794 joystick = Get_SDL_Joystick(i);
796 name = SDL_JoystickName(i);
797 printf("Watching joystick %d: (%s)\n", i,
798 name ? name : "Unknown Joystick");
799 printf("Joystick has %d axes, %d hats, %d balls, and %d buttons\n",
800 SDL_JoystickNumAxes(joystick),
801 SDL_JoystickNumHats(joystick),
802 SDL_JoystickNumBalls(joystick),
803 SDL_JoystickNumButtons(joystick));
806 /* Initialize drawing rectangles */
807 memset(axis_area, 0, (sizeof axis_area));
810 /* Loop, getting joystick events! */
813 while ( SDL_PollEvent(&event) ) {
814 switch (event.type) {
815 case SDL_JOYAXISMOTION:
816 joystick_nr = event.jaxis.which;
817 printf("Joystick %d axis %d value: %d\n",
822 case SDL_JOYHATMOTION:
823 joystick_nr = event.jaxis.which;
824 printf("Joystick %d hat %d value:",
827 if ( event.jhat.value == SDL_HAT_CENTERED )
829 if ( event.jhat.value & SDL_HAT_UP )
831 if ( event.jhat.value & SDL_HAT_RIGHT )
833 if ( event.jhat.value & SDL_HAT_DOWN )
835 if ( event.jhat.value & SDL_HAT_LEFT )
839 case SDL_JOYBALLMOTION:
840 joystick_nr = event.jaxis.which;
841 printf("Joystick %d ball %d delta: (%d,%d)\n",
847 case SDL_JOYBUTTONDOWN:
848 joystick_nr = event.jaxis.which;
849 printf("Joystick %d button %d down\n",
851 event.jbutton.button);
853 case SDL_JOYBUTTONUP:
854 joystick_nr = event.jaxis.which;
855 printf("Joystick %d button %d up\n",
857 event.jbutton.button);
860 if ( event.key.keysym.sym != SDLK_ESCAPE ) {
863 /* Fall through to signal quit */
872 joystick = Get_SDL_Joystick(joystick_nr);
874 /* Update visual joystick state */
875 for ( i=0; i<SDL_JoystickNumButtons(joystick); ++i ) {
879 area.y = SCREEN_HEIGHT-34;
882 if (SDL_JoystickGetButton(joystick, i) == SDL_PRESSED) {
883 SDL_FillRect(screen, &area, 0xFFFF);
885 SDL_FillRect(screen, &area, 0x0000);
887 SDL_UpdateRects(screen, 1, &area);
890 /* Erase previous axes */
891 SDL_FillRect(screen, &axis_area[draw], 0x0000);
893 /* Draw the X/Y axis */
895 x = (((int)SDL_JoystickGetAxis(joystick, 0))+32768);
901 if ( x > (SCREEN_WIDTH-16) ) {
904 y = (((int)SDL_JoystickGetAxis(joystick, 1))+32768);
910 if ( y > (SCREEN_HEIGHT-16) ) {
911 y = SCREEN_HEIGHT-16;
913 axis_area[draw].x = (Sint16)x;
914 axis_area[draw].y = (Sint16)y;
915 axis_area[draw].w = 16;
916 axis_area[draw].h = 16;
917 SDL_FillRect(screen, &axis_area[draw], 0xFFFF);
919 SDL_UpdateRects(screen, 2, axis_area);
923 void TEST_SDL_JOYSTICK()
928 /* Initialize SDL (Note: video is required to start event loop) */
929 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 )
931 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
935 /* Print information about the joysticks */
936 printf("There are %d joysticks attached\n", SDL_NumJoysticks());
937 for ( i=0; i<SDL_NumJoysticks(); ++i )
939 name = SDL_JoystickName(i);
940 printf("Joystick %d: %s\n",i,name ? name : "Unknown Joystick");
945 if (!Open_SDL_Joystick(i))
946 printf("Couldn't open joystick %d: %s\n", i, SDL_GetError());
952 Close_SDL_Joystick(i);
954 SDL_QuitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
957 #endif /* TARGET_SDL */
959 /* +-----------------------------------------------------------------------+ */
960 /* | SDL TEST STUFF | */
961 /* +-----------------------------------------------------------------------+ */
965 int main(int argc, char *argv[])
967 program_name = (strrchr(argv[0],'/') ? strrchr(argv[0],'/') + 1 : argv[0]);
969 #if defined(PLATFORM_MSDOS)
981 TEST_SDL_BLIT_RECT((WIN_XSIZE - TILEX)/2, (WIN_YSIZE - TILEY)/2);
982 TEST_SDL_EVENT_LOOP();
991 exit(0); /* to keep compilers happy */