added first version of simple click events for global animations
authorHolger Schemel <info@artsoft.org>
Tue, 18 Apr 2017 10:00:40 +0000 (12:00 +0200)
committerHolger Schemel <info@artsoft.org>
Tue, 18 Apr 2017 10:00:40 +0000 (12:00 +0200)
src/anim.c
src/anim.h
src/conf_gfx.c
src/events.c
src/init.c
src/libgame/misc.c
src/libgame/system.h
src/main.h

index b9ea8becc2a44d2b84ea4e32e8424a95e96a7e87..3018fc137fce3d3a9260a76abf41f3df42599f1d 100644 (file)
@@ -9,6 +9,8 @@
 // anim.c
 // ============================================================================
 
+#include "libgame/libgame.h"
+
 #include "anim.h"
 #include "main.h"
 #include "tools.h"
@@ -90,6 +92,9 @@ struct GlobalAnimPartControlInfo
   int anim_delay_counter;
   int post_delay_counter;
 
+  boolean init_event_state;
+  boolean anim_event_state;
+
   int drawing_stage;
 
   int state;
@@ -186,6 +191,10 @@ static int anim_classes_last = ANIM_CLASS_NONE;
 
 static boolean drawing_to_fading_buffer = FALSE;
 
+static boolean anim_click_event = FALSE;
+static int anim_click_mx = 0;
+static int anim_click_my = 0;
+
 
 /* ========================================================================= */
 /* generic animation frame calculation                                       */
@@ -881,11 +890,43 @@ static void StopGlobalAnimSoundAndMusic(struct GlobalAnimPartControlInfo *part)
   StopGlobalAnimMusic(part);
 }
 
+static boolean getPartClickEvent(struct GlobalAnimPartControlInfo *part)
+{
+  struct GraphicInfo *g = &part->graphic_info;
+  int part_x = part->viewport_x + part->x;
+  int part_y = part->viewport_y + part->y;
+  int part_width  = g->width;
+  int part_height = g->height;
+  int mx = anim_click_mx;
+  int my = anim_click_my;
+
+  // check if mouse click event was detected at all
+  if (!anim_click_event)
+    return FALSE;
+
+  // check if mouse click is inside the animation part's viewport
+  if (mx <  part->viewport_x ||
+      mx >= part->viewport_x + part->viewport_width ||
+      my <  part->viewport_y ||
+      my >= part->viewport_y + part->viewport_height)
+    return FALSE;
+
+  // check if mouse click is inside the animation part's graphic
+  if (mx <  part_x ||
+      mx >= part_x + part_width ||
+      my <  part_y ||
+      my >= part_y + part_height)
+    return FALSE;
+
+  return TRUE;
+}
+
 int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state)
 {
   struct GraphicInfo *g = &part->graphic_info;
   struct GraphicInfo *c = &part->control_info;
   boolean viewport_changed = SetGlobalAnimPart_Viewport(part);
+  boolean part_click_event = getPartClickEvent(part);
 
   if (viewport_changed)
     state |= ANIM_STATE_RESTART;
@@ -905,6 +946,9 @@ int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state)
     part->anim_delay_counter =
       (c->anim_delay_fixed + GetSimpleRandom(c->anim_delay_random));
 
+    part->init_event_state = c->init_event;
+    part->anim_event_state = c->anim_event;
+
     part->initial_anim_sync_frame =
       (g->anim_global_sync ? 0 : anim_sync_frame + part->init_delay_counter);
 
@@ -981,26 +1025,58 @@ int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state)
     if (c->step_yoffset != ARG_UNDEFINED_VALUE)
       part->step_yoffset = c->step_yoffset;
 
-    if (part->init_delay_counter == 0)
+    if (part->init_delay_counter == 0 &&
+       part->init_event_state == ANIM_EVENT_NONE)
       PlayGlobalAnimSoundAndMusic(part);
   }
 
+  if (part_click_event &&
+      part->init_event_state != ANIM_EVENT_NONE)
+  {
+    if (part->initial_anim_sync_frame > 0)
+      part->initial_anim_sync_frame -= part->init_delay_counter - 1;
+
+    part->init_delay_counter = 1;
+    part->init_event_state = ANIM_EVENT_NONE;
+
+    anim_click_event = FALSE;
+  }
+
+  if (part_click_event &&
+      part->anim_event_state != ANIM_EVENT_NONE)
+  {
+    part->anim_delay_counter = 1;
+    part->anim_event_state = ANIM_EVENT_NONE;
+
+    anim_click_event = FALSE;
+  }
+
   if (part->init_delay_counter > 0)
   {
     part->init_delay_counter--;
 
     if (part->init_delay_counter == 0)
+    {
+      part->init_event_state = ANIM_EVENT_NONE;
+
       PlayGlobalAnimSoundAndMusic(part);
+    }
 
     return ANIM_STATE_WAITING;
   }
 
+  if (part->init_event_state != ANIM_EVENT_NONE)
+    return ANIM_STATE_WAITING;
+
   // check if moving animation has left the visible screen area
   if ((part->x <= -g->width              && part->step_xoffset <= 0) ||
       (part->x >=  part->viewport_width  && part->step_xoffset >= 0) ||
       (part->y <= -g->height             && part->step_yoffset <= 0) ||
       (part->y >=  part->viewport_height && part->step_yoffset >= 0))
   {
+    // do not wait for "anim" events for off-screen animations
+    part->anim_event_state = ANIM_EVENT_NONE;
+
     // do not stop animation before "anim" or "post" counter are finished
     if (part->anim_delay_counter == 0 &&
        part->post_delay_counter == 0)
@@ -1024,6 +1100,8 @@ int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state)
 
     if (part->anim_delay_counter == 0)
     {
+      part->anim_event_state = ANIM_EVENT_NONE;
+
       StopGlobalAnimSoundAndMusic(part);
 
       part->post_delay_counter =
@@ -1263,3 +1341,20 @@ static void DoAnimationExt()
   redraw_mask = REDRAW_ALL;
 #endif
 }
+
+void HandleGlobalAnimClicks(int mx, int my, int button)
+{
+  static int last_button = 0;
+  boolean press_event;
+  boolean release_event;
+
+  /* check if button state has changed since last invocation */
+  press_event   = (button != 0 && last_button == 0);
+  release_event = (button == 0 && last_button != 0);
+  last_button = button;
+
+  anim_click_mx = mx;
+  anim_click_my = my;
+  anim_click_event = (press_event   ? TRUE  :
+                     release_event ? FALSE : anim_click_event);
+}
index 99de93ea660bff57a7f5125e4e25bfdcfdf280b4..d553dc5a3669a8841d6d4ba5fe60d53a908d1faf 100644 (file)
@@ -18,4 +18,6 @@ int getAnimationFrame(int, int, int, int, int);
 void InitGlobalAnimations(void);
 void DrawGlobalAnimations(int, int);
 
+void HandleGlobalAnimClicks(int, int, int);
+
 #endif
index 9693b1f205e7a0b9c985106816d4523a00f93dcc..935d6f146f74a5443083ce2c1b4a5a25c40adef0 100644 (file)
@@ -60,6 +60,8 @@ struct ConfigTypeInfo image_config_suffix[] =
   { ".anim_delay_random",              ARG_UNDEFINED,  TYPE_INTEGER    },
   { ".post_delay_fixed",               ARG_UNDEFINED,  TYPE_INTEGER    },
   { ".post_delay_random",              ARG_UNDEFINED,  TYPE_INTEGER    },
+  { ".init_event",                     ARG_UNDEFINED,  TYPE_STRING     },
+  { ".anim_event",                     ARG_UNDEFINED,  TYPE_STRING     },
   { ".name",                           ARG_UNDEFINED,  TYPE_STRING     },
   { ".scale_up_factor",                        ARG_UNDEFINED,  TYPE_INTEGER    },
   { ".tile_size",                      ARG_UNDEFINED,  TYPE_INTEGER    },
index 25d243b7b105f5beb368b203e7195ee97a1bc450..20c6e3432e3dff614ea005e59cda0fb70c92a371 100644 (file)
@@ -1233,6 +1233,8 @@ void HandleButton(int mx, int my, int button, int button_nr)
   }
 #endif
 
+  HandleGlobalAnimClicks(mx, my, button);
+
   if (button_hold && game_status == GAME_MODE_PLAYING && tape.pausing)
     return;
 
index 97eaf2bf17ddfbb20f4f3d76c932626cf9a18978..a4b7f59f2b909adb6ef3e2c3163c65477ba8a912 100644 (file)
@@ -1258,6 +1258,8 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
   g->anim_delay_random = 0;
   g->post_delay_fixed = 0;
   g->post_delay_random = 0;
+  g->init_event = ANIM_EVENT_DEFAULT;
+  g->anim_event = ANIM_EVENT_DEFAULT;
   g->draw_order = 0;
   g->fade_mode = FADE_MODE_DEFAULT;
   g->fade_delay = -1;
@@ -1474,6 +1476,12 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
   if (parameter[GFX_ARG_POST_DELAY_RANDOM] != ARG_UNDEFINED_VALUE)
     g->post_delay_random = parameter[GFX_ARG_POST_DELAY_RANDOM];
 
+  /* used for global animations */
+  if (parameter[GFX_ARG_INIT_EVENT] != ARG_UNDEFINED_VALUE)
+    g->init_event = parameter[GFX_ARG_INIT_EVENT];
+  if (parameter[GFX_ARG_ANIM_EVENT] != ARG_UNDEFINED_VALUE)
+    g->anim_event = parameter[GFX_ARG_ANIM_EVENT];
+
   /* used for toon animations and global animations */
   g->step_offset  = parameter[GFX_ARG_STEP_OFFSET];
   g->step_xoffset = parameter[GFX_ARG_STEP_XOFFSET];
index 0c0e82c2bc45e6621f104f9bd0947e3ff3dfa269..bb732ffa4ac8d517f511b236ea014f275a6c6247 100644 (file)
@@ -2782,6 +2782,14 @@ int get_parameter_value(char *value_raw, char *suffix, int type)
     if (string_has_parameter(value, "static_panel"))
       result |= ANIM_STATIC_PANEL;
   }
+  else if (strEqual(suffix, ".init_event") ||
+          strEqual(suffix, ".anim_event"))
+  {
+    result = ANIM_EVENT_DEFAULT;
+
+    if (string_has_parameter(value, "click"))
+      result |= ANIM_EVENT_CLICK;
+  }
   else if (strEqual(suffix, ".class"))
   {
     result = (strEqual(value, ARG_UNDEFINED) ? ARG_UNDEFINED_VALUE :
index 4a54de8767f20a1c5416cc5d2d65100b2b04082e..9c95802d34d0bed74bae579b123a2cbe9441f523 100644 (file)
 
 #define STYLE_DEFAULT          STYLE_NONE
 
+#define ANIM_EVENT_NONE                0
+#define ANIM_EVENT_CLICK       (1 << 0)
+
+#define ANIM_EVENT_DEFAULT     ANIM_EVENT_NONE
+
 /* values for fade mode */
 #define FADE_TYPE_NONE         0
 #define FADE_TYPE_FADE_IN      (1 << 0)
index 12c911b3a3c50f14806562099fc11be42e10bf8a..2f1a103978513d915de232626c1a9ec3a47295de 100644 (file)
 #define GFX_ARG_ANIM_DELAY_RANDOM      38
 #define GFX_ARG_POST_DELAY_FIXED       39
 #define GFX_ARG_POST_DELAY_RANDOM      40
-#define GFX_ARG_NAME                   41
-#define GFX_ARG_SCALE_UP_FACTOR                42
-#define GFX_ARG_TILE_SIZE              43
-#define GFX_ARG_CLONE_FROM             44
-#define GFX_ARG_FADE_MODE              45
-#define GFX_ARG_FADE_DELAY             46
-#define GFX_ARG_POST_DELAY             47
-#define GFX_ARG_AUTO_DELAY             48
-#define GFX_ARG_ALIGN                  49
-#define GFX_ARG_VALIGN                 50
-#define GFX_ARG_SORT_PRIORITY          51
-#define GFX_ARG_CLASS                  52
-#define GFX_ARG_STYLE                  53
-#define GFX_ARG_ACTIVE_XOFFSET         54
-#define GFX_ARG_ACTIVE_YOFFSET         55
-#define GFX_ARG_PRESSED_XOFFSET                56
-#define GFX_ARG_PRESSED_YOFFSET                57
-
-#define NUM_GFX_ARGS                   58
+#define GFX_ARG_INIT_EVENT             41
+#define GFX_ARG_ANIM_EVENT             42
+#define GFX_ARG_NAME                   43
+#define GFX_ARG_SCALE_UP_FACTOR                44
+#define GFX_ARG_TILE_SIZE              45
+#define GFX_ARG_CLONE_FROM             46
+#define GFX_ARG_FADE_MODE              47
+#define GFX_ARG_FADE_DELAY             48
+#define GFX_ARG_POST_DELAY             49
+#define GFX_ARG_AUTO_DELAY             50
+#define GFX_ARG_ALIGN                  51
+#define GFX_ARG_VALIGN                 52
+#define GFX_ARG_SORT_PRIORITY          53
+#define GFX_ARG_CLASS                  54
+#define GFX_ARG_STYLE                  55
+#define GFX_ARG_ACTIVE_XOFFSET         56
+#define GFX_ARG_ACTIVE_YOFFSET         57
+#define GFX_ARG_PRESSED_XOFFSET                58
+#define GFX_ARG_PRESSED_YOFFSET                59
+
+#define NUM_GFX_ARGS                   60
 
 
 /* values for sound configuration suffixes */
@@ -2883,6 +2885,9 @@ struct GraphicInfo
   int post_delay_fixed;                /* optional delay values after bored/global */
   int post_delay_random;       /* animations (pause before next animation) */
 
+  int init_event;              /* optional event triggering animation start */
+  int anim_event;              /* optional event triggering animation end   */
+
   int step_offset;             /* optional step offset of toon animations */
   int step_xoffset;            /* optional step offset of toon animations */
   int step_yoffset;            /* optional step offset of toon animations */