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;
31 GC clip_gc[NUM_BITMAPS], tile_clip_gc;
32 Bitmap pix[NUM_BITMAPS];
33 Bitmap pix_masked[NUM_BITMAPS], tile_masked[NUM_TILES];
34 Pixmap clipmask[NUM_BITMAPS], tile_clipmask[NUM_TILES];
36 DrawBuffer drawto, drawto_field, backbuffer, fieldbuffer;
42 char *sound_device_name = AUDIO_DEVICE;
45 int joystick_device = 0;
46 char *joystick_device_name[MAX_PLAYERS] =
54 char *program_name = NULL;
56 int game_status = MAINMENU;
57 boolean level_editor_test_game = FALSE;
58 boolean network_playing = FALSE;
59 int button_status = MB_NOT_PRESSED;
60 boolean motion_status = FALSE;
61 int key_joystick_mapping = 0;
62 int global_joystick_status = JOYSTICK_STATUS;
63 int joystick_status = JOYSTICK_STATUS;
66 boolean fullscreen_available = FULLSCREEN_STATUS;
67 boolean fullscreen_enabled = FALSE;
70 boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
71 int redraw_x1 = 0, redraw_y1 = 0;
75 short Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
76 short Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
77 short MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
78 short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
79 short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
80 short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
81 short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
82 short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
83 short Frame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
84 boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
85 short JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
86 short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
87 short AmoebaCnt[MAX_NUM_AMOEBA], AmoebaCnt2[MAX_NUM_AMOEBA];
88 unsigned long Elementeigenschaften1[MAX_ELEMENTS];
89 unsigned long Elementeigenschaften2[MAX_ELEMENTS];
92 int lev_fieldx,lev_fieldy, scroll_x,scroll_y;
94 int FX = SX, FY = SY, ScrollStepSize;
95 int ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0;
97 int BorderElement = EL_BETON;
98 int GameFrameDelay = GAME_FRAME_DELAY;
99 int FfwdFrameDelay = FFWD_FRAME_DELAY;
100 int BX1 = 0, BY1 = 0, BX2 = SCR_FIELDX-1, BY2 = SCR_FIELDY-1;
101 int SBX_Left, SBX_Right;
102 int SBY_Upper, SBY_Lower;
103 int ZX,ZY, ExitX,ExitY;
110 int TimeFrames, TimePlayed, TimeLeft;
112 boolean network_player_action_received = FALSE;
114 struct LevelDirInfo *leveldir_first = NULL, *leveldir_current = NULL;
115 struct LevelInfo level;
116 struct PlayerInfo stored_player[MAX_PLAYERS], *local_player = NULL;
117 struct HiScore highscore[MAX_SCORE_ENTRIES];
118 struct SampleInfo Sound[NUM_SOUNDS];
119 struct TapeInfo tape;
122 struct OptionInfo options;
125 struct SetupInfo setup;
126 struct GameInfo game;
129 struct VideoSystemInfo video;
130 struct AudioSystemInfo audio;
133 struct GlobalInfo global;
135 /* data needed for playing sounds */
136 char *sound_name[NUM_SOUNDS] =
202 /* background music */
203 int background_loop[] =
213 int num_bg_loops = sizeof(background_loop)/sizeof(int);
215 char *element_info[] =
217 "empty space", /* 0 */
227 "spaceship", /* 10 */
234 "quicksand with rock",
237 "magic wall", /* 20 */
247 "magic wheel", /* 30 */
257 "gray door (opened by red key)", /* 40 */
258 "gray door (opened by yellow key)",
259 "gray door (opened by green key)",
260 "gray door (opened by blue key)",
263 "invisible normal wall",
265 "ligh bulb (glowing)",
267 "wall with diamond", /* 50 */
268 "amoeba with content",
273 "diamond (BD style)",
275 "wall with BD style diamond",
276 "wall with yellow emerald",
277 "dark yam yam", /* 60 */
278 "magic wall (BD style)",
279 "invisible steel wall",
281 "increases number of bombs",
282 "increases explosion size",
283 "increases power of explosion",
285 "sokoban empty field",
286 "sokoban field with object",
287 "butterfly (starts moving right)", /* 70 */
288 "butterfly (starts moving up)",
289 "butterfly (starts moving left)",
290 "butterfly (starts moving down)",
291 "firefly (starts moving right)",
292 "firefly (starts moving up)",
293 "firefly (starts moving left)",
294 "firefly (starts moving down)",
297 "yellow player", /* 80 */
301 "bug (starts moving right)",
302 "bug (starts moving up)",
303 "bug (starts moving left)",
304 "bug (starts moving down)",
305 "spaceship (starts moving right)",
306 "spaceship (starts moving up)",
307 "spaceship (starts moving left)", /* 90 */
308 "spaceship (starts moving down)",
309 "pac man (starts moving right)",
310 "pac man (starts moving up)",
311 "pac man (starts moving left)",
312 "pac man (starts moving down)",
315 "wall with red emerald",
316 "wall with violet emerald",
322 "normal wall (BD style)",
335 "fire breathing dragon",
337 "letter ' '", /* 120 */
347 "letter '*'", /* 130 */
357 "letter '4'", /* 140 */
367 "letter '>'", /* 150 */
377 "letter 'H'", /* 160 */
387 "letter 'R'", /* 170 */
397 "letter 'Ö'", /* 180 */
407 "letter ''", /* 190 */
417 "growing wall (horizontal)", /* 200 */
418 "growing wall (vertical)",
419 "growing wall (all directions)",
427 "empty space", /* 210 */
436 "port (leading right)",
437 "port (leading down)", /* 220 */
438 "port (leading left)",
440 "port (leading right)",
441 "port (leading down)",
442 "port (leading left)",
447 "red disk", /* 230 */
450 "port (all directions)",
457 "hardware", /* 240 */
480 "white door", /* 260 */
481 "gray door (opened by white key)",
485 "switch gate (open)",
486 "switch gate (closed)",
487 "switch for switch gate",
488 "switch for switch gate",
491 "red conveyor belt (left)",
492 "red conveyor belt (middle)",
493 "red conveyor belt (right)",
494 "switch for red conveyor belt (left)",
495 "switch for red conveyor belt (middle)",
496 "switch for red conveyor belt (right)",
497 "yellow conveyor belt (left)",
498 "yellow conveyor belt (middle)",
499 "yellow conveyor belt (right)",
500 "switch for yellow conveyor belt (left)", /* 280 */
501 "switch for yellow conveyor belt (middle)",
502 "switch for yellow conveyor belt (right)",
503 "green conveyor belt (left)",
504 "green conveyor belt (middle)",
505 "green conveyor belt (right)",
506 "switch for green conveyor belt (left)",
507 "switch for green conveyor belt (middle)",
508 "switch for green conveyor belt (right)",
509 "blue conveyor belt (left)",
510 "blue conveyor belt (middle)", /* 290 */
511 "blue conveyor belt (right)",
512 "switch for blue conveyor belt (left)",
513 "switch for blue conveyor belt (middle)",
514 "switch for blue conveyor belt (right)",
517 "light switch (off)",
519 "sign (exclamation)",
520 "sign (radio activity)", /* 300 */
522 "sign (wheel chair)",
530 "sign (other)", /* 310 */
531 "mole (starts moving left)",
532 "mole (starts moving right)",
533 "mole (starts moving up)",
534 "mole (starts moving down)",
535 "steel wall (slanted)",
541 "shield (active, kills enemies)",
543 "time gate (closed)",
544 "switch for time gate",
545 "switch for time gate",
547 "send balloon to the left",
548 "send balloon to the right",
550 "send balloon down", /* 330 */
551 "send balloon in any direction",
560 "normal wall", /* 340 */
564 "tube (all directions)",
567 "tube (vertical & left)",
568 "tube (vertical & right)",
569 "tube (horizontal & up)",
570 "tube (horizontal & down)", /* 350 */
572 "tube (left & down)",
574 "tube (right & down)",
577 "stable bomb (DX style)",
581 "-------------------------------",
584 int num_element_info = sizeof(element_info)/sizeof(char *);
588 /* +-----------------------------------------------------------------------+ */
589 /* | SDL TEST STUFF | */
590 /* +-----------------------------------------------------------------------+ */
592 #if defined(TARGET_SDL)
594 SDL_Surface *sdl_screen, *sdl_image_tmp, *sdl_image, *sdl_image_masked;
595 SDL_Surface *sdl_image2_tmp, *sdl_image2, *sdl_image2_masked;
597 void TEST_SDL_BLIT_RECT(int x, int y)
599 SDL_Rect rect_src, rect_dst;
601 SDLCopyArea(pix_masked[PIX_HEROES], window,
602 8 * TILEX, 8 * TILEY, TILEX, TILEY, x, y);
605 rect_src.x = 8 * TILEX;
606 rect_src.y = 8 * TILEY;
615 SDL_BlitSurface(sdl_image2_masked, &rect_src, sdl_screen, &rect_dst);
616 SDL_UpdateRect(sdl_screen, x, y, TILEX, TILEY);
619 void TEST_SDL_INIT_DISPLAY()
621 SDL_Rect rect_src, rect_dst;
623 if (SDL_Init(SDL_INIT_VIDEO) < 0)
625 fprintf(stderr, "SDL_Init() failed: %s\n", SDL_GetError());
629 /* automatically cleanup SDL stuff after exit() */
632 if ((sdl_screen = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, 16, SDL_HWSURFACE))
635 fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
639 SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING);
641 if ((sdl_image_tmp = IMG_Load("graphics/RocksScreen.pcx")) == NULL)
643 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
647 sdl_image = SDL_DisplayFormat(sdl_image_tmp);
649 SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY,
650 SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
651 sdl_image_masked = SDL_DisplayFormat(sdl_image_tmp);
653 SDL_FreeSurface(sdl_image_tmp);
655 if ((sdl_image2_tmp = IMG_Load("graphics/RocksHeroes.pcx")) == NULL)
657 fprintf(stderr, "IMG_Load() failed: %s\n", SDL_GetError());
661 sdl_image2 = SDL_DisplayFormat(sdl_image2_tmp);
662 SDL_FreeSurface(sdl_image2_tmp);
664 sdl_image2_masked = SDL_DisplayFormat(sdl_image2);
665 SDL_SetColorKey(sdl_image2_masked, SDL_SRCCOLORKEY,
666 SDL_MapRGB(sdl_image2_masked->format, 0x00, 0x00, 0x00));
670 rect_src.w = sdl_image->w;
671 rect_src.h = sdl_image->h;
675 rect_dst.w = sdl_image->w;
676 rect_dst.h = sdl_image->h;
678 SDL_BlitSurface(sdl_image, &rect_src, sdl_screen, &rect_dst);
681 SDL_UpdateRect(sdl_screen, 0, 0, WIN_XSIZE, WIN_YSIZE);
684 SDL_UpdateRect(sdl_screen, 0, 0, 0, 0);
686 SDL_Flip(sdl_screen);
693 void TEST_SDL_EVENT_LOOP()
697 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
700 while (!quit_loop && SDL_WaitEvent(&event) >=0)
707 if (SDL_PollEvent(&event))
709 /* hier werden die Ereignisse behandelt */
718 case SDL_MOUSEBUTTONDOWN:
720 int x = event.button.x;
721 int y = event.button.y;
723 SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
725 TEST_SDL_BLIT_RECT(x, y);
727 printf("SDL_MOUSEBUTTONDOWN(%d, %d)\n", x, y);
731 case SDL_MOUSEBUTTONUP:
733 int x = event.button.x;
734 int y = event.button.y;
736 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
738 printf("SDL_MOUSEBUTTONUP(%d, %d)\n", x, y);
742 case SDL_MOUSEMOTION:
744 int x = event.motion.x;
745 int y = event.motion.y;
747 TEST_SDL_BLIT_RECT(x, y);
749 printf("SDL_MOUSEMOTION(%d, %d)\n", x, y);
758 if (!SDL_PollEvent(NULL)) /* delay only if no pending events */
760 printf("waiting...\n");
765 SDL_FreeSurface(sdl_image);
769 #define SCREEN_WIDTH 640
770 #define SCREEN_HEIGHT 480
772 void WatchJoysticks()
779 SDL_Rect axis_area[2];
781 SDL_Joystick *joystick = Get_SDL_Joystick(joystick_nr);
783 /* Set a video mode to display joystick axis position */
784 screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16, 0);
785 if ( screen == NULL ) {
786 fprintf(stderr, "Couldn't set video mode: %s\n",SDL_GetError());
790 /* Print info about the joysticks we are watching */
793 joystick = Get_SDL_Joystick(i);
795 name = SDL_JoystickName(i);
796 printf("Watching joystick %d: (%s)\n", i,
797 name ? name : "Unknown Joystick");
798 printf("Joystick has %d axes, %d hats, %d balls, and %d buttons\n",
799 SDL_JoystickNumAxes(joystick),
800 SDL_JoystickNumHats(joystick),
801 SDL_JoystickNumBalls(joystick),
802 SDL_JoystickNumButtons(joystick));
805 /* Initialize drawing rectangles */
806 memset(axis_area, 0, (sizeof axis_area));
809 /* Loop, getting joystick events! */
812 while ( SDL_PollEvent(&event) ) {
813 switch (event.type) {
814 case SDL_JOYAXISMOTION:
815 joystick_nr = event.jaxis.which;
816 printf("Joystick %d axis %d value: %d\n",
821 case SDL_JOYHATMOTION:
822 joystick_nr = event.jaxis.which;
823 printf("Joystick %d hat %d value:",
826 if ( event.jhat.value == SDL_HAT_CENTERED )
828 if ( event.jhat.value & SDL_HAT_UP )
830 if ( event.jhat.value & SDL_HAT_RIGHT )
832 if ( event.jhat.value & SDL_HAT_DOWN )
834 if ( event.jhat.value & SDL_HAT_LEFT )
838 case SDL_JOYBALLMOTION:
839 joystick_nr = event.jaxis.which;
840 printf("Joystick %d ball %d delta: (%d,%d)\n",
846 case SDL_JOYBUTTONDOWN:
847 joystick_nr = event.jaxis.which;
848 printf("Joystick %d button %d down\n",
850 event.jbutton.button);
852 case SDL_JOYBUTTONUP:
853 joystick_nr = event.jaxis.which;
854 printf("Joystick %d button %d up\n",
856 event.jbutton.button);
859 if ( event.key.keysym.sym != SDLK_ESCAPE ) {
862 /* Fall through to signal quit */
871 joystick = Get_SDL_Joystick(joystick_nr);
873 /* Update visual joystick state */
874 for ( i=0; i<SDL_JoystickNumButtons(joystick); ++i ) {
878 area.y = SCREEN_HEIGHT-34;
881 if (SDL_JoystickGetButton(joystick, i) == SDL_PRESSED) {
882 SDL_FillRect(screen, &area, 0xFFFF);
884 SDL_FillRect(screen, &area, 0x0000);
886 SDL_UpdateRects(screen, 1, &area);
889 /* Erase previous axes */
890 SDL_FillRect(screen, &axis_area[draw], 0x0000);
892 /* Draw the X/Y axis */
894 x = (((int)SDL_JoystickGetAxis(joystick, 0))+32768);
900 if ( x > (SCREEN_WIDTH-16) ) {
903 y = (((int)SDL_JoystickGetAxis(joystick, 1))+32768);
909 if ( y > (SCREEN_HEIGHT-16) ) {
910 y = SCREEN_HEIGHT-16;
912 axis_area[draw].x = (Sint16)x;
913 axis_area[draw].y = (Sint16)y;
914 axis_area[draw].w = 16;
915 axis_area[draw].h = 16;
916 SDL_FillRect(screen, &axis_area[draw], 0xFFFF);
918 SDL_UpdateRects(screen, 2, axis_area);
922 void TEST_SDL_JOYSTICK()
927 /* Initialize SDL (Note: video is required to start event loop) */
928 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0 )
930 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
934 /* Print information about the joysticks */
935 printf("There are %d joysticks attached\n", SDL_NumJoysticks());
936 for ( i=0; i<SDL_NumJoysticks(); ++i )
938 name = SDL_JoystickName(i);
939 printf("Joystick %d: %s\n",i,name ? name : "Unknown Joystick");
944 if (!Open_SDL_Joystick(i))
945 printf("Couldn't open joystick %d: %s\n", i, SDL_GetError());
951 Close_SDL_Joystick(i);
953 SDL_QuitSubSystem(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
956 #endif /* TARGET_SDL */
958 /* +-----------------------------------------------------------------------+ */
959 /* | SDL TEST STUFF | */
960 /* +-----------------------------------------------------------------------+ */
964 int main(int argc, char *argv[])
966 program_name = (strrchr(argv[0],'/') ? strrchr(argv[0],'/') + 1 : argv[0]);
968 #if defined(PLATFORM_MSDOS)
980 TEST_SDL_BLIT_RECT((WIN_XSIZE - TILEX)/2, (WIN_YSIZE - TILEY)/2);
981 TEST_SDL_EVENT_LOOP();
990 exit(0); /* to keep compilers happy */