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];
145 struct SampleInfo Sound[NUM_SOUNDS];
146 struct TapeInfo tape;
149 struct OptionInfo options;
152 struct SetupInfo setup;
153 struct GameInfo game;
156 struct VideoSystemInfo video;
157 struct AudioSystemInfo audio;
160 struct GlobalInfo global;
162 /* data needed for playing sounds */
163 char *sound_name[NUM_SOUNDS] =
229 /* background music */
230 int background_loop[] =
240 int num_bg_loops = sizeof(background_loop)/sizeof(int);
242 char *element_info[] =
244 "empty space", /* 0 */
254 "spaceship", /* 10 */
261 "quicksand with rock",
264 "magic wall", /* 20 */
274 "magic wheel", /* 30 */
284 "gray door (opened by red key)", /* 40 */
285 "gray door (opened by yellow key)",
286 "gray door (opened by green key)",
287 "gray door (opened by blue key)",
290 "invisible normal wall",
292 "ligh bulb (glowing)",
294 "wall with diamond", /* 50 */
295 "amoeba with content",
300 "diamond (BD style)",
302 "wall with BD style diamond",
303 "wall with yellow emerald",
304 "dark yam yam", /* 60 */
305 "magic wall (BD style)",
306 "invisible steel wall",
308 "increases number of bombs",
309 "increases explosion size",
310 "increases power of explosion",
312 "sokoban empty field",
313 "sokoban field with object",
314 "butterfly (starts moving right)", /* 70 */
315 "butterfly (starts moving up)",
316 "butterfly (starts moving left)",
317 "butterfly (starts moving down)",
318 "firefly (starts moving right)",
319 "firefly (starts moving up)",
320 "firefly (starts moving left)",
321 "firefly (starts moving down)",
324 "yellow player", /* 80 */
328 "bug (starts moving right)",
329 "bug (starts moving up)",
330 "bug (starts moving left)",
331 "bug (starts moving down)",
332 "spaceship (starts moving right)",
333 "spaceship (starts moving up)",
334 "spaceship (starts moving left)", /* 90 */
335 "spaceship (starts moving down)",
336 "pac man (starts moving right)",
337 "pac man (starts moving up)",
338 "pac man (starts moving left)",
339 "pac man (starts moving down)",
342 "wall with red emerald",
343 "wall with violet emerald",
349 "normal wall (BD style)",
362 "fire breathing dragon",
364 "letter ' '", /* 120 */
374 "letter '*'", /* 130 */
384 "letter '4'", /* 140 */
394 "letter '>'", /* 150 */
404 "letter 'H'", /* 160 */
414 "letter 'R'", /* 170 */
424 "letter 'Ö'", /* 180 */
434 "letter ''", /* 190 */
444 "growing wall (horizontal)", /* 200 */
445 "growing wall (vertical)",
446 "growing wall (all directions)",
454 "empty space", /* 210 */
463 "port (leading right)",
464 "port (leading down)", /* 220 */
465 "port (leading left)",
467 "port (leading right)",
468 "port (leading down)",
469 "port (leading left)",
474 "red disk", /* 230 */
477 "port (all directions)",
484 "hardware", /* 240 */
507 "white door", /* 260 */
508 "gray door (opened by white key)",
512 "switch gate (open)",
513 "switch gate (closed)",
514 "switch for switch gate",
515 "switch for switch gate",
518 "red conveyor belt (left)",
519 "red conveyor belt (middle)",
520 "red conveyor belt (right)",
521 "switch for red conveyor belt (left)",
522 "switch for red conveyor belt (middle)",
523 "switch for red conveyor belt (right)",
524 "yellow conveyor belt (left)",
525 "yellow conveyor belt (middle)",
526 "yellow conveyor belt (right)",
527 "switch for yellow conveyor belt (left)", /* 280 */
528 "switch for yellow conveyor belt (middle)",
529 "switch for yellow conveyor belt (right)",
530 "green conveyor belt (left)",
531 "green conveyor belt (middle)",
532 "green conveyor belt (right)",
533 "switch for green conveyor belt (left)",
534 "switch for green conveyor belt (middle)",
535 "switch for green conveyor belt (right)",
536 "blue conveyor belt (left)",
537 "blue conveyor belt (middle)", /* 290 */
538 "blue conveyor belt (right)",
539 "switch for blue conveyor belt (left)",
540 "switch for blue conveyor belt (middle)",
541 "switch for blue conveyor belt (right)",
544 "light switch (off)",
546 "sign (exclamation)",
547 "sign (radio activity)", /* 300 */
549 "sign (wheel chair)",
557 "sign (other)", /* 310 */
558 "mole (starts moving left)",
559 "mole (starts moving right)",
560 "mole (starts moving up)",
561 "mole (starts moving down)",
562 "steel wall (slanted)",
568 "shield (active, kills enemies)",
570 "time gate (closed)",
571 "switch for time gate",
572 "switch for time gate",
574 "send balloon to the left",
575 "send balloon to the right",
577 "send balloon down", /* 330 */
578 "send balloon in any direction",
587 "normal wall", /* 340 */
591 "tube (all directions)",
594 "tube (vertical & left)",
595 "tube (vertical & right)",
596 "tube (horizontal & up)",
597 "tube (horizontal & down)", /* 350 */
599 "tube (left & down)",
601 "tube (right & down)",
604 "stable bomb (DX style)",
608 "-------------------------------",
611 int num_element_info = sizeof(element_info)/sizeof(char *);
617 /* +-----------------------------------------------------------------------+ */
618 /* | SDL TEST STUFF | */
619 /* +-----------------------------------------------------------------------+ */
621 #if defined(TARGET_SDL)
623 SDL_Surface *sdl_screen, *sdl_image_tmp, *sdl_image, *sdl_image_masked;
624 SDL_Surface *sdl_image2_tmp, *sdl_image2, *sdl_image2_masked;
626 void TEST_SDL_BLIT_RECT(int x, int y)
628 SDL_Rect rect_src, rect_dst;
630 SDLCopyArea(pix_masked[PIX_HEROES], window,
631 8 * TILEX, 8 * TILEY, TILEX, TILEY, x, y);
634 rect_src.x = 8 * TILEX;
635 rect_src.y = 8 * TILEY;
644 SDL_BlitSurface(sdl_image2_masked, &rect_src, sdl_screen, &rect_dst);
645 SDL_UpdateRect(sdl_screen, x, y, TILEX, TILEY);
648 void TEST_SDL_INIT_DISPLAY()
650 SDL_Rect rect_src, rect_dst;
652 if (SDL_Init(SDL_INIT_VIDEO) < 0)
654 fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError());
658 /* automatically cleanup SDL stuff after exit() */
661 if ((sdl_screen = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, 16, SDL_HWSURFACE))
664 fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
668 SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING);
670 if ((sdl_image_tmp = IMG_Load("graphics/RocksScreen.pcx")) == NULL)
672 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
676 sdl_image = SDL_DisplayFormat(sdl_image_tmp);
678 SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY,
679 SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
680 sdl_image_masked = SDL_DisplayFormat(sdl_image_tmp);
682 SDL_FreeSurface(sdl_image_tmp);
684 if ((sdl_image2_tmp = IMG_Load("graphics/RocksHeroes.pcx")) == NULL)
686 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
690 sdl_image2 = SDL_DisplayFormat(sdl_image2_tmp);
691 SDL_FreeSurface(sdl_image2_tmp);
693 sdl_image2_masked = SDL_DisplayFormat(sdl_image2);
694 SDL_SetColorKey(sdl_image2_masked, SDL_SRCCOLORKEY,
695 SDL_MapRGB(sdl_image2_masked->format, 0x00, 0x00, 0x00));
699 rect_src.w = sdl_image->w;
700 rect_src.h = sdl_image->h;
704 rect_dst.w = sdl_image->w;
705 rect_dst.h = sdl_image->h;
707 SDL_BlitSurface(sdl_image, &rect_src, sdl_screen, &rect_dst);
710 SDL_UpdateRect(sdl_screen, 0, 0, WIN_XSIZE, WIN_YSIZE);
713 SDL_UpdateRect(sdl_screen, 0, 0, 0, 0);
715 SDL_Flip(sdl_screen);
722 void TEST_SDL_EVENT_LOOP()
726 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
729 while (!quit_loop && SDL_WaitEvent(&event) >=0)
736 if (SDL_PollEvent(&event))
738 /* hier werden die Ereignisse behandelt */
747 case SDL_MOUSEBUTTONDOWN:
749 int x = event.button.x;
750 int y = event.button.y;
752 SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
754 TEST_SDL_BLIT_RECT(x, y);
756 printf("SDL_MOUSEBUTTONDOWN(%d, %d)\n", x, y);
760 case SDL_MOUSEBUTTONUP:
762 int x = event.button.x;
763 int y = event.button.y;
765 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
767 printf("SDL_MOUSEBUTTONUP(%d, %d)\n", x, y);
771 case SDL_MOUSEMOTION:
773 int x = event.motion.x;
774 int y = event.motion.y;
776 TEST_SDL_BLIT_RECT(x, y);
778 printf("SDL_MOUSEMOTION(%d, %d)\n", x, y);
787 if (!SDL_PollEvent(NULL)) /* delay only if no pending events */
789 printf("waiting...\n");
794 SDL_FreeSurface(sdl_image);
798 #define SCREEN_WIDTH 640
799 #define SCREEN_HEIGHT 480
801 void WatchJoysticks()
808 SDL_Rect axis_area[2];
810 SDL_Joystick *joystick = Get_SDL_Joystick(joystick_nr);
812 /* Set a video mode to display joystick axis position */
813 screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16, 0);
814 if ( screen == NULL ) {
815 fprintf(stderr, "Couldn't set video mode: %s\n",SDL_GetError());
819 /* Print info about the joysticks we are watching */
822 joystick = Get_SDL_Joystick(i);
824 name = SDL_JoystickName(i);
825 printf("Watching joystick %d: (%s)\n", i,
826 name ? name : "Unknown Joystick");
827 printf("Joystick has %d axes, %d hats, %d balls, and %d buttons\n",
828 SDL_JoystickNumAxes(joystick),
829 SDL_JoystickNumHats(joystick),
830 SDL_JoystickNumBalls(joystick),
831 SDL_JoystickNumButtons(joystick));
834 /* Initialize drawing rectangles */
835 memset(axis_area, 0, (sizeof axis_area));
838 /* Loop, getting joystick events! */
841 while ( SDL_PollEvent(&event) ) {
842 switch (event.type) {
843 case SDL_JOYAXISMOTION:
844 joystick_nr = event.jaxis.which;
845 printf("Joystick %d axis %d value: %d\n",
850 case SDL_JOYHATMOTION:
851 joystick_nr = event.jaxis.which;
852 printf("Joystick %d hat %d value:",
855 if ( event.jhat.value == SDL_HAT_CENTERED )
857 if ( event.jhat.value & SDL_HAT_UP )
859 if ( event.jhat.value & SDL_HAT_RIGHT )
861 if ( event.jhat.value & SDL_HAT_DOWN )
863 if ( event.jhat.value & SDL_HAT_LEFT )
867 case SDL_JOYBALLMOTION:
868 joystick_nr = event.jaxis.which;
869 printf("Joystick %d ball %d delta: (%d,%d)\n",
875 case SDL_JOYBUTTONDOWN:
876 joystick_nr = event.jaxis.which;
877 printf("Joystick %d button %d down\n",
879 event.jbutton.button);
881 case SDL_JOYBUTTONUP:
882 joystick_nr = event.jaxis.which;
883 printf("Joystick %d button %d up\n",
885 event.jbutton.button);
888 if ( event.key.keysym.sym != SDLK_ESCAPE ) {
891 /* Fall through to signal quit */
900 joystick = Get_SDL_Joystick(joystick_nr);
902 /* Update visual joystick state */
903 for ( i=0; i<SDL_JoystickNumButtons(joystick); ++i ) {
907 area.y = SCREEN_HEIGHT-34;
910 if (SDL_JoystickGetButton(joystick, i) == SDL_PRESSED) {
911 SDL_FillRect(screen, &area, 0xFFFF);
913 SDL_FillRect(screen, &area, 0x0000);
915 SDL_UpdateRects(screen, 1, &area);
918 /* Erase previous axes */
919 SDL_FillRect(screen, &axis_area[draw], 0x0000);
921 /* Draw the X/Y axis */
923 x = (((int)SDL_JoystickGetAxis(joystick, 0))+32768);
929 if ( x > (SCREEN_WIDTH-16) ) {
932 y = (((int)SDL_JoystickGetAxis(joystick, 1))+32768);
938 if ( y > (SCREEN_HEIGHT-16) ) {
939 y = SCREEN_HEIGHT-16;
941 axis_area[draw].x = (Sint16)x;
942 axis_area[draw].y = (Sint16)y;
943 axis_area[draw].w = 16;
944 axis_area[draw].h = 16;
945 SDL_FillRect(screen, &axis_area[draw], 0xFFFF);
947 SDL_UpdateRects(screen, 2, axis_area);
951 void TEST_SDL_JOYSTICK()
956 /* Initialize SDL (Note: video is required to start event loop) */
957 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 )
959 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
963 /* Print information about the joysticks */
964 printf("There are %d joysticks attached\n", SDL_NumJoysticks());
965 for ( i=0; i<SDL_NumJoysticks(); ++i )
967 name = SDL_JoystickName(i);
968 printf("Joystick %d: %s\n",i,name ? name : "Unknown Joystick");
973 if (!Open_SDL_Joystick(i))
974 printf("Couldn't open joystick %d: %s\n", i, SDL_GetError());
980 Close_SDL_Joystick(i);
982 SDL_QuitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
985 #endif /* TARGET_SDL */
987 /* +-----------------------------------------------------------------------+ */
988 /* | SDL TEST STUFF | */
989 /* +-----------------------------------------------------------------------+ */
995 int main(int argc, char *argv[])
998 program_name = (strrchr(argv[0],'/') ? strrchr(argv[0],'/') + 1 : argv[0]);
1001 InitCommandName(argv[0]);
1002 InitExitFunction(CloseAllAndExit);
1003 InitPlatformDependantStuff();
1006 #if defined(PLATFORM_MSDOS)
1019 TEST_SDL_BLIT_RECT((WIN_XSIZE - TILEX)/2, (WIN_YSIZE - TILEY)/2);
1020 TEST_SDL_EVENT_LOOP();
1022 TEST_SDL_JOYSTICK();
1029 exit(0); /* to keep compilers happy */