rnd-19990808-1-src
authorHolger Schemel <info@artsoft.org>
Sun, 8 Aug 1999 01:45:49 +0000 (03:45 +0200)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:34:07 +0000 (10:34 +0200)
src/editor.c
src/events.c
src/game.c
src/main.h
src/tools.c

index 6aa94aeb8a70e83c0256b1ca2d709c85512081bc..5fb13e1ee035bc9056ea69a6cfa87fdadea0245b 100644 (file)
@@ -3935,6 +3935,8 @@ void HandleLevelEditorKeyInput(KeySym key)
       ClickOnGadget(level_editor_gadget[id], button);
     else if (letter == '.')
       ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS], button);
+    else if (key == XK_space || key == XK_Return)
+      ClickOnGadget(level_editor_gadget[GADGET_ID_TEST], button);
     else
       for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
        if (letter && letter == control_info[i].shortcut)
@@ -3954,7 +3956,7 @@ void HandleEditorGadgetInfoText(void *ptr)
 {
   struct GadgetInfo *gi = (struct GadgetInfo *)ptr;
   char infotext[MAX_INFOTEXT_LEN + 1];
-  char shortcut[20];
+  char shortcut[MAX_INFOTEXT_LEN + 1];
 
   ClearEditorGadgetInfoText();
 
@@ -3974,10 +3976,13 @@ void HandleEditorGadgetInfoText(void *ptr)
 
     if (key)
     {
-      sprintf(shortcut, " ('%s%c')",
-             (key >= 'A' && key <= 'Z' ? "Shift-" :
-              gi->custom_id == GADGET_ID_SINGLE_ITEMS ? ".' or '" : ""),
-             key);
+      if (gi->custom_id == GADGET_ID_SINGLE_ITEMS)     /* special case 1 */
+       sprintf(shortcut, " ('.' or '%c')", key);
+      else if (gi->custom_id == GADGET_ID_TEST)                /* special case 2 */
+       sprintf(shortcut, " ('Enter' or 'Shift-%c')", key);
+      else                                             /* normal case */
+       sprintf(shortcut, " ('%s%c')",
+               (key >= 'A' && key <= 'Z' ? "Shift-" : ""), key);
 
       if (strlen(infotext) + strlen(shortcut) <= MAX_INFOTEXT_LEN)
        strcat(infotext, shortcut);
index a34c1ab9a762e501abbbd947f643497601d67dfd..0e8122853385e642df43e2dae3711a2b12b0d318 100644 (file)
@@ -477,7 +477,8 @@ void HandleKey(KeySym key, int key_status)
   if (key_status == KEY_RELEASED)
     return;
 
-  if (key == XK_Return && game_status == PLAYING && AllPlayersGone)
+  if ((key == XK_Return || key == XK_space) &&
+      game_status == PLAYING && AllPlayersGone)
   {
     CloseDoor(DOOR_CLOSE_1);
     game_status = MAINMENU;
@@ -520,6 +521,7 @@ void HandleKey(KeySym key, int key_status)
       switch(key)
       {
        case XK_Return:
+       case XK_space:
          if (game_status == MAINMENU)
            HandleMainMenu(0,0, 0,0, MB_MENU_CHOICE);
           else if (game_status == CHOOSELEVEL)
@@ -553,6 +555,7 @@ void HandleKey(KeySym key, int key_status)
       switch(key)
       {
        case XK_Return:
+       case XK_space:
          game_status = MAINMENU;
          DrawMainMenu();
          BackToFront();
index ce6ca3ab084668cdfcd63662c5408697270e0fce..2fd57d065386332b48ac485ef92cf707fec8edd2 100644 (file)
@@ -179,6 +179,50 @@ void GetPlayerConfig()
   InitJoysticks();
 }
 
+static int getBeltNrFromElement(int element)
+{
+  return (element < EL_BELT2_LEFT ? 0 :
+         element < EL_BELT3_LEFT ? 1 :
+         element < EL_BELT4_LEFT ? 2 : 3);
+}
+
+static int getBeltNrFromSwitchElement(int element)
+{
+  return (element < EL_BELT2_SWITCH_L ? 0 :
+         element < EL_BELT3_SWITCH_L ? 1 :
+         element < EL_BELT4_SWITCH_L ? 2 : 3);
+}
+
+static int getBeltDirNrFromSwitchElement(int element)
+{
+  static int belt_base_element[4] =
+  {
+    EL_BELT1_SWITCH_L,
+    EL_BELT2_SWITCH_L,
+    EL_BELT3_SWITCH_L,
+    EL_BELT4_SWITCH_L
+  };
+
+  int belt_nr = getBeltNrFromSwitchElement(element);
+  int belt_dir_nr = element - belt_base_element[belt_nr];
+
+  return (belt_dir_nr % 3);
+}
+
+static int getBeltDirFromSwitchElement(int element)
+{
+  static int belt_move_dir[3] =
+  {
+    MV_LEFT,
+    MV_NO_MOVING,
+    MV_RIGHT
+  };
+
+  int belt_dir_nr = getBeltDirNrFromSwitchElement(element);
+
+  return belt_move_dir[belt_dir_nr];
+}
+
 static void InitField(int x, int y, boolean init_game)
 {
   switch (Feld[x][y])
@@ -322,6 +366,34 @@ static void InitField(int x, int y, boolean init_game)
       Feld[x][y] = EL_EM_KEY_4;
       break;
 
+    case EL_BELT1_SWITCH_L:
+    case EL_BELT1_SWITCH_M:
+    case EL_BELT1_SWITCH_R:
+    case EL_BELT2_SWITCH_L:
+    case EL_BELT2_SWITCH_M:
+    case EL_BELT2_SWITCH_R:
+    case EL_BELT3_SWITCH_L:
+    case EL_BELT3_SWITCH_M:
+    case EL_BELT3_SWITCH_R:
+    case EL_BELT4_SWITCH_L:
+    case EL_BELT4_SWITCH_M:
+    case EL_BELT4_SWITCH_R:
+      if (init_game)
+      {
+       int belt_nr = getBeltNrFromSwitchElement(Feld[x][y]);
+       int belt_dir = getBeltDirFromSwitchElement(Feld[x][y]);
+       int belt_dir_nr = getBeltDirNrFromSwitchElement(Feld[x][y]);
+
+       if (game.belt_dir_nr[belt_nr] == 3)     /* initial value */
+       {
+         game.belt_dir[belt_nr] = belt_dir;
+         game.belt_dir_nr[belt_nr] = belt_dir_nr;
+       }
+       else    /* more than one switch -- set it like the first switch */
+       {
+         Feld[x][y] = Feld[x][y] - belt_dir_nr + game.belt_dir_nr[belt_nr];
+       }
+      }
     default:
       break;
   }
@@ -424,7 +496,10 @@ void InitGame()
   game.magic_wall_active = FALSE;
   game.magic_wall_time_left = 0;
   for (i=0; i<4; i++)
+  {
     game.belt_dir[i] = MV_NO_MOVING;
+    game.belt_dir_nr[i] = 3;           /* no moving, next switch left */
+  }
 
   for (i=0; i<MAX_NUM_AMOEBA; i++)
     AmoebaCnt[i] = AmoebaCnt2[i] = 0;
@@ -2145,6 +2220,17 @@ void StartMoving(int x, int y)
        InitMovingField(x, y, left ? MV_LEFT : MV_RIGHT);
       }
     }
+    else if (IS_BELT(Feld[x][y+1]))
+    {
+      boolean left_is_free  = (x>0 && IS_FREE(x-1, y));
+      boolean right_is_free = (x<lev_fieldx-1 && IS_FREE(x+1, y));
+      int belt_nr = getBeltNrFromElement(Feld[x][y+1]);
+      int belt_dir = game.belt_dir[belt_nr];
+
+      if ((belt_dir == MV_LEFT  && left_is_free) ||
+         (belt_dir == MV_RIGHT && right_is_free))
+       InitMovingField(x, y, belt_dir);
+    }
   }
   else if (CAN_MOVE(element))
   {
@@ -2441,12 +2527,16 @@ void ContinueMoving(int x, int y)
   int dy = (direction == MV_UP   ? -1 : direction == MV_DOWN  ? +1 : 0);
   int horiz_move = (dx!=0);
   int newx = x + dx, newy = y + dy;
-  int step = (horiz_move ? dx : dy) * TILEX/8;
+  int step = (horiz_move ? dx : dy) * TILEX / 8;
 
   if (element == EL_TROPFEN)
-    step/=2;
+    step /= 2;
   else if (Store[x][y] == EL_MORAST_VOLL || Store[x][y] == EL_MORAST_LEER)
-    step/=4;
+    step /= 4;
+  else if (CAN_FALL(element) && horiz_move &&
+          y < lev_fieldy-1 && IS_BELT(Feld[x][y+1]))
+    step /= 2;
+
 #if OLD_GAME_BEHAVIOUR
   else if (CAN_FALL(element) && horiz_move && !IS_SP_ELEMENT(element))
     step*=2;
@@ -3369,6 +3459,21 @@ static void CheckBuggyBase(int x, int y)
   }
 }
 
+static void DrawBeltAnimation(int x, int y, int element)
+{
+  int belt_nr = getBeltNrFromElement(element);
+  int belt_dir = game.belt_dir[belt_nr];
+
+  if (belt_dir != MV_NO_MOVING)
+  {
+    int delay = 2;
+    int mode = (belt_dir == MV_LEFT ? ANIM_NORMAL : ANIM_REVERSE);
+    int graphic = el2gfx(element) + (belt_dir == MV_LEFT ? 0 : 7);
+
+    DrawGraphicAnimation(x, y, graphic, 8, delay, mode);
+  }
+}
+
 static void PlayerActions(struct PlayerInfo *player, byte player_action)
 {
   static byte stored_player_action[MAX_PLAYERS];
@@ -3655,6 +3760,8 @@ void GameActions()
       DrawGraphicAnimation(x, y, GFX2_SP_TERMINAL, 7, 12, ANIM_NORMAL);
     else if (element == EL_SP_TERMINAL_ACTIVE)
       DrawGraphicAnimation(x, y, GFX2_SP_TERMINAL_ACTIVE, 7, 4, ANIM_NORMAL);
+    else if (IS_BELT(element))
+      DrawBeltAnimation(x, y, element);
 
     if (game.magic_wall_active)
     {
@@ -4546,25 +4653,29 @@ int DigField(struct PlayerInfo *player,
          EL_BELT3_SWITCH_L,
          EL_BELT4_SWITCH_L
        };
-       static int belt_move_dir[3] =
+       static int belt_move_dir[4] =
        {
          MV_LEFT,
          MV_NO_MOVING,
-         MV_RIGHT
+         MV_RIGHT,
+         MV_NO_MOVING,
        };
 
-       int belt_nr = (element < EL_BELT2_SWITCH_L ? 0 :
-                      element < EL_BELT3_SWITCH_L ? 1 :
-                      element < EL_BELT4_SWITCH_L ? 2 : 3);
-       int belt_dir_nr = element - belt_base_element[belt_nr];
-       int belt_dir_nr_next = (belt_dir_nr + 1) % 3;
-       int belt_dir_next = belt_move_dir[belt_dir_nr_next];
+       int belt_nr = getBeltNrFromSwitchElement(element);
+       int belt_dir_nr = (game.belt_dir_nr[belt_nr] + 1) % 4;
+       int belt_dir = belt_move_dir[belt_dir_nr];
        int xx, yy;
 
        if (player->Switching)
          return MF_ACTION;
 
-       game.belt_dir[belt_nr] = belt_dir_next;
+       game.belt_dir_nr[belt_nr] = belt_dir_nr;
+       game.belt_dir[belt_nr] = belt_dir;
+
+       if (belt_dir_nr == 3)
+         belt_dir_nr = 1;
+
+       player->Switching = TRUE;
 
        for (yy=0; yy<lev_fieldy; yy++)
        {
@@ -4572,22 +4683,24 @@ int DigField(struct PlayerInfo *player,
          {
            if (IS_BELT_SWITCH(Feld[xx][yy]))
            {
-             int e = Feld[xx][yy];
-             int e_belt_nr = (e < EL_BELT2_SWITCH_L ? 0 :
-                              e < EL_BELT3_SWITCH_L ? 1 :
-                              e < EL_BELT4_SWITCH_L ? 2 : 3);
+             int e_belt_nr = getBeltNrFromSwitchElement(Feld[xx][yy]);
 
              if (e_belt_nr == belt_nr)
              {
-               Feld[xx][yy] = belt_base_element[belt_nr] + belt_dir_nr_next;
+               Feld[xx][yy] = belt_base_element[belt_nr] + belt_dir_nr;
                DrawLevelField(xx, yy);
              }
            }
+           else if (belt_dir == MV_NO_MOVING && IS_BELT(Feld[xx][yy]))
+           {
+             int e_belt_nr = getBeltNrFromElement(Feld[xx][yy]);
+
+             if (e_belt_nr == belt_nr)
+               DrawLevelField(xx, yy);    /* set belt to parking position */
+           }
          }
        }
 
-       player->Switching = TRUE;
-
        return MF_ACTION;
       }
       break;
index b10d0357c549147bd7759504fb66821cd094a1ed..72528fa688af21c1994980d20ba0aa3f9631a584 100644 (file)
@@ -216,7 +216,7 @@ typedef unsigned char byte;
 #define MAX_TAPELEN            (1000 * 50)     /* max. time * framerate */
 #define MAX_LEVDIR_ENTRIES     100
 #define MAX_SCORE_ENTRIES      100
-#define MAX_ELEMENTS           512
+#define MAX_ELEMENTS           700             /* 500 static + 200 runtime */
 #define MAX_NUM_AMOEBA         100
 
 /* values for elements with content */
@@ -419,6 +419,7 @@ struct GameInfo
   boolean magic_wall_active;
   int magic_wall_time_left;
   int belt_dir[4];
+  int belt_dir_nr[4];
 };
 
 struct GlobalInfo
@@ -576,6 +577,7 @@ extern char         *element_info[];
 #define MICRO_GFX_PER_LINE     128
 
 #define HEROES_PER_LINE                16
+
 #define MINI_SP_STARTX         0
 #define MINI_SP_STARTY         352
 #define MICRO_SP_STARTX                0
@@ -586,18 +588,18 @@ extern char               *element_info[];
 
 #define MINI_DC_STARTX         256
 #define MINI_DC_STARTY         0
-#define MICRO_DC_STARTX                0
-#define MICRO_DC_STARTY                0
+#define MICRO_DC_STARTX                256
+#define MICRO_DC_STARTY                384
 #define DC_PER_LINE            8
 #define MINI_DC_PER_LINE       8
-#define MICRO_DC_PER_LINE      32
+#define MICRO_DC_PER_LINE      8
 
 #define FONT_CHARS_PER_LINE    16
 #define FONT_LINES_PER_FONT    4
 
 /* game elements:
-**       0 - 1000: real elements, stored in level file
-**     1000 - 2000: flag elements, only used at runtime
+**       0 - 499: real elements, stored in level file
+**      500 - 699: flag elements, only used at runtime
 */
 /* "real" level elements */
 #define EL_LEERRAUM            0
@@ -901,34 +903,34 @@ extern char               *element_info[];
 #define EL_SAND_INVISIBLE      315
 
 /* "real" (and therefore drawable) runtime elements */
-#define EL_SIEB_LEER           1000
-#define EL_SIEB2_LEER          1001
-#define EL_SIEB_VOLL           1002
-#define EL_SIEB2_VOLL          1003
-#define EL_SIEB_TOT            1004
-#define EL_SIEB2_TOT           1005
-#define EL_AUSGANG_ACT         1006
-#define EL_SP_TERMINAL_ACTIVE  1007
-#define EL_SP_BUG_ACTIVE       1008
-#define EL_EM_KEY_1            1009
-#define EL_EM_KEY_2            1010
-#define EL_EM_KEY_3            1011
-#define EL_EM_KEY_4            1012
-#define EL_DYNABOMB_ACTIVE_1   1013
-#define EL_DYNABOMB_ACTIVE_2   1014
-#define EL_DYNABOMB_ACTIVE_3   1015
-#define EL_DYNABOMB_ACTIVE_4   1016
+#define EL_SIEB_LEER           500
+#define EL_SIEB2_LEER          501
+#define EL_SIEB_VOLL           502
+#define EL_SIEB2_VOLL          503
+#define EL_SIEB_TOT            504
+#define EL_SIEB2_TOT           505
+#define EL_AUSGANG_ACT         506
+#define EL_SP_TERMINAL_ACTIVE  507
+#define EL_SP_BUG_ACTIVE       508
+#define EL_EM_KEY_1            509
+#define EL_EM_KEY_2            510
+#define EL_EM_KEY_3            511
+#define EL_EM_KEY_4            512
+#define EL_DYNABOMB_ACTIVE_1   513
+#define EL_DYNABOMB_ACTIVE_2   514
+#define EL_DYNABOMB_ACTIVE_3   515
+#define EL_DYNABOMB_ACTIVE_4   516
 
 /* "unreal" (and therefore not drawable) runtime elements */
-#define EL_BLOCKED             2000
-#define EL_EXPLODING           2001
-#define EL_CRACKINGNUT         2002
-#define EL_BLURB_LEFT          2003
-#define EL_BLURB_RIGHT         2004
-#define EL_AMOEBING            2005
-#define EL_MAUERND             2006
-#define EL_BURNING             2007
-#define EL_PLAYER_IS_LEAVING   2008
+#define EL_BLOCKED             600
+#define EL_EXPLODING           601
+#define EL_CRACKINGNUT         602
+#define EL_BLURB_LEFT          603
+#define EL_BLURB_RIGHT         604
+#define EL_AMOEBING            605
+#define EL_MAUERND             606
+#define EL_BURNING             607
+#define EL_PLAYER_IS_LEAVING   608
 
 /* game graphics:
 **       0 -  255: graphics from "RocksScreen"
index b9c4a826f90bf4c8c33b5d07fdeb95a67a9cf29a..bde3b716213f7ef947d164585c302d3026d5717d 100644 (file)
@@ -1116,17 +1116,20 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
   else if ((element == EL_FELSBROCKEN || element == EL_SP_ZONK ||
            IS_GEM(element)) && !cut_mode)
   {
-    if (element == EL_FELSBROCKEN || element == EL_SP_ZONK)
+    if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
     {
-      if (dir == MV_LEFT)
-       graphic += (4 - phase4) % 4;
-      else if (dir == MV_RIGHT)
-       graphic += phase4;
-      else
-       graphic += phase2 * 2;
+      if (element == EL_FELSBROCKEN || element == EL_SP_ZONK)
+      {
+       if (dir == MV_LEFT)
+         graphic += (4 - phase4) % 4;
+       else if (dir == MV_RIGHT)
+         graphic += phase4;
+       else
+         graphic += phase2 * 2;
+      }
+      else if (element != EL_SP_INFOTRON)
+       graphic += phase2;
     }
-    else if (element != EL_SP_INFOTRON)
-      graphic += phase2;
   }
   else if (element == EL_SIEB_LEER || element == EL_SIEB2_LEER ||
           element == EL_SIEB_VOLL || element == EL_SIEB2_VOLL)
@@ -1478,17 +1481,16 @@ void DrawMicroElement(int xpos, int ypos, int element)
     graphic -= GFX_START_ROCKSSP;
     graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
     XCopyArea(display, pix[PIX_SP], drawto, gc,
-             MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) *MICRO_TILEX,
-             MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) *MICRO_TILEY,
+             MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
+             MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
              MICRO_TILEX, MICRO_TILEY, xpos, ypos);
   }
   else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
   {
     graphic -= GFX_START_ROCKSDC;
-    graphic -= ((graphic / DC_PER_LINE) * DC_PER_LINE) / 2;
     XCopyArea(display, pix[PIX_DC], drawto, gc,
-             MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) *MICRO_TILEX,
-             MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) *MICRO_TILEY,
+             MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
+             MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
              MICRO_TILEX, MICRO_TILEY, xpos, ypos);
   }
   else