added support for CE change pages triggering global animations
authorHolger Schemel <info@artsoft.org>
Sun, 13 Aug 2023 11:57:49 +0000 (13:57 +0200)
committerHolger Schemel <info@artsoft.org>
Sun, 3 Sep 2023 20:59:57 +0000 (22:59 +0200)
This commit extends the previous commit to not only be able to trigger
global animations using "ce_change:custom_X" (by any CE change page),
but also by specifying change page using "ce_change:custom_X.page_Y".

src/anim.c
src/anim.h
src/files.c
src/game.c
src/libgame/system.h

index bbc38dc45903bde745711a925b9ad3bc3983333e..d780658c39e8c4567542f79b86d0476a42c95082 100644 (file)
@@ -1191,6 +1191,7 @@ static void PlayGlobalAnimSoundIfLoop(struct GlobalAnimPartControlInfo *part)
 static boolean checkGlobalAnimEvent(int anim_event, int mask)
 {
   int mask_anim_only = mask & ~ANIM_EVENT_PART_MASK;
+  int mask_ce_only   = mask & ~ANIM_EVENT_PAGE_MASK;
 
   if (mask & ANIM_EVENT_ANY)
     return (anim_event & ANIM_EVENT_ANY);
@@ -1199,7 +1200,8 @@ static boolean checkGlobalAnimEvent(int anim_event, int mask)
   else if (mask & ANIM_EVENT_UNCLICK_ANY)
     return (anim_event & ANIM_EVENT_UNCLICK_ANY);
   else if (mask & ANIM_EVENT_CE_CHANGE)
-    return (anim_event == mask);
+    return (anim_event == mask ||
+           anim_event == mask_ce_only);
   else
     return (anim_event == mask ||
            anim_event == mask_anim_only);
@@ -1358,12 +1360,13 @@ static void InitGlobalAnim_Triggered(struct GlobalAnimPartControlInfo *part,
   }
 }
 
-static void InitGlobalAnim_Triggered_ByCustomElement(int nr)
+static void InitGlobalAnim_Triggered_ByCustomElement(int nr, int page)
 {
   struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[GAME_MODE_PLAYING];
 
   int event_value = ANIM_EVENT_CE_CHANGE;
-  int mask = event_value | (nr << ANIM_EVENT_CE_BIT);
+  int event_bits = (nr << ANIM_EVENT_CE_BIT) | (page << ANIM_EVENT_PAGE_BIT);
+  int mask = event_value | event_bits;
   int anim2_nr;
 
   for (anim2_nr = 0; anim2_nr < ctrl->num_anims; anim2_nr++)
@@ -2140,10 +2143,11 @@ int getGlobalAnimSyncFrame(void)
   return anim_sync_frame;
 }
 
-void HandleGlobalAnimEventByElementChange(int element)
+void HandleGlobalAnimEventByElementChange(int element, int page)
 {
   if (!IS_CUSTOM_ELEMENT(element))
     return;
 
-  InitGlobalAnim_Triggered_ByCustomElement(element - EL_CUSTOM_START);
+  // custom element stored as 0 to 255, change page stored as 1 to 32
+  InitGlobalAnim_Triggered_ByCustomElement(element - EL_CUSTOM_START, page + 1);
 }
index bf9561fde35c37c6e98f01640415d217b8f9332a..5224be131a38b0133f3ea9515b66720f8e446454 100644 (file)
@@ -22,7 +22,7 @@ void DrawGlobalAnimations(int, int);
 void RestartGlobalAnimsByStatus(int);
 
 boolean HandleGlobalAnimClicks(int, int, int, boolean);
-void HandleGlobalAnimEventByElementChange(int);
+void HandleGlobalAnimEventByElementChange(int, int);
 
 int getGlobalAnimSyncFrame(void);
 
index 42208ce6ec4b99dd9e9499d8cbb64a9923ca29e0..13141d7f8d3c9f1eee7eaeca0fdcc901de96a6af 100644 (file)
@@ -11549,9 +11549,10 @@ static boolean string_has_parameter(char *s, char *s_contained)
 static int get_anim_parameter_value_ce(char *s)
 {
   char *s_ptr = s;
-  char *pattern = "ce_change:custom_";
-  int pattern_len = strlen(pattern);
-  char *matching_char = strstr(s_ptr, pattern);
+  char *pattern_1 = "ce_change:custom_";
+  char *pattern_2 = ".page_";
+  int pattern_1_len = strlen(pattern_1);
+  char *matching_char = strstr(s_ptr, pattern_1);
   int result = ANIM_EVENT_NONE;
 
   if (matching_char == NULL)
@@ -11559,9 +11560,9 @@ static int get_anim_parameter_value_ce(char *s)
 
   result = ANIM_EVENT_CE_CHANGE;
 
-  s_ptr = matching_char + pattern_len;
+  s_ptr = matching_char + pattern_1_len;
 
-  // check for custom element number ("custom_X" or "custom_XX" or "custom_XXX")
+  // check for custom element number ("custom_X", "custom_XX" or "custom_XXX")
   if (*s_ptr >= '0' && *s_ptr <= '9')
   {
     int gic_ce_nr = (*s_ptr++ - '0');
@@ -11577,7 +11578,7 @@ static int get_anim_parameter_value_ce(char *s)
     if (gic_ce_nr < 1 || gic_ce_nr > NUM_CUSTOM_ELEMENTS)
       return ANIM_EVENT_NONE;
 
-    // store internal CE number (0 to 255, not "custom_1" to "custom_256")
+    // custom element stored as 0 to 255
     gic_ce_nr--;
 
     result |= gic_ce_nr << ANIM_EVENT_CE_BIT;
@@ -11589,6 +11590,33 @@ static int get_anim_parameter_value_ce(char *s)
     return ANIM_EVENT_NONE;
   }
 
+  // check for change page number ("page_X" or "page_XX") (optional)
+  if (strPrefix(s_ptr, pattern_2))
+  {
+    s_ptr += strlen(pattern_2);
+
+    if (*s_ptr >= '0' && *s_ptr <= '9')
+    {
+      int gic_page_nr = (*s_ptr++ - '0');
+
+      if (*s_ptr >= '0' && *s_ptr <= '9')
+       gic_page_nr = 10 * gic_page_nr + (*s_ptr++ - '0');
+
+      if (gic_page_nr < 1 || gic_page_nr > MAX_CHANGE_PAGES)
+       return ANIM_EVENT_NONE;
+
+      // change page stored as 1 to 32 (0 means "all change pages")
+
+      result |= gic_page_nr << ANIM_EVENT_PAGE_BIT;
+    }
+    else
+    {
+      // invalid animation part number specified
+
+      return ANIM_EVENT_NONE;
+    }
+  }
+
   // discard result if next character is neither delimiter nor whitespace
   if (!(*s_ptr == ',' || *s_ptr == '\0' ||
        *s_ptr == ' ' || *s_ptr == '\t'))
index 0d1830340a376487b5c2b7d6cd972b537a7060d7..299fd72bdd934957fc06ca6e9343f1ad315c60aa 100644 (file)
@@ -10716,7 +10716,7 @@ static boolean ChangeElement(int x, int y, int element, int page)
   ChangeCount[x][y]++;         // count number of changes in the same frame
 
   if (ei->has_anim_event)
-    HandleGlobalAnimEventByElementChange(element);
+    HandleGlobalAnimEventByElementChange(element, page);
 
   if (change->explode)
   {
index 1c6cb88d39b2875508b79e336910a83b13c51e9c..e429d2336a6c8406cb7ef38c0eab3cea22bafd93 100644 (file)
 // event mask:  bits 0-15
 // CE number:   bits 16-23
 // anim number: bits 16-23
+// page number: bits 24-31
 // part number: bits 24-31
 #define ANIM_EVENT_CE_BIT      16
 #define ANIM_EVENT_ANIM_BIT    16
+#define ANIM_EVENT_PAGE_BIT    24
 #define ANIM_EVENT_PART_BIT    24
 
 #define ANIM_EVENT_CE_MASK     (0xff << ANIM_EVENT_CE_BIT)
 #define ANIM_EVENT_ANIM_MASK   (0xff << ANIM_EVENT_ANIM_BIT)
+#define ANIM_EVENT_PAGE_MASK   (0xff << ANIM_EVENT_PAGE_BIT)
 #define ANIM_EVENT_PART_MASK   (0xff << ANIM_EVENT_PART_BIT)
 
 #define ANIM_EVENT_DEFAULT     ANIM_EVENT_NONE