summaryrefslogtreecommitdiff
path: root/src/uqm/flash.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/uqm/flash.h')
-rw-r--r--src/uqm/flash.h223
1 files changed, 223 insertions, 0 deletions
diff --git a/src/uqm/flash.h b/src/uqm/flash.h
new file mode 100644
index 0000000..0488fd3
--- /dev/null
+++ b/src/uqm/flash.h
@@ -0,0 +1,223 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef UQM_FLASH_H_
+#define UQM_FLASH_H_
+
+/*
+ * This code can draw three kinds of flashing areas.
+ * - a rectangular highlight area. The brightness of the area oscilates.
+ * - an overlay; an image is laid over an area, with oscilating brightness.
+ * - a transition/cross-fade between two images.
+ *
+ * NB. The graphics lock should not be held when any of the Flash functions
+ * is called.
+ *
+ *
+ * Example:
+ *
+ * // We create the flash context; it is used to manipulate the flash
+ * // rectangle while it exists.
+ * FlashContext *fc = Flash_createHighlight (gfxContext, rect);
+ *
+ * // Specify how bright the flash is at the beginning and ending of the
+ * // sequence.
+ * Flash_setMergeFactors(fc, 2, 3, 2);
+ *
+ * // We change the flashing speed from the defaults.
+ * Flash_setSpeed (fc, ONE_SECOND, ONE_SECOND, ONE_SECOND, ONE_SECOND);
+ *
+ * // During cross-fades, update 8 times per second.
+ * Flash_setFrameTime (fc, ONE_SECOND / 8);
+ *
+ * // We start the flashing. The default is to start from the "off" state.
+ * Flash_start (fc);
+ *
+ * // Some other stuff happens
+ * ...
+ *
+ * // The user has activated the selection. We pause for instance while
+ * // a pop-up window is active.
+ * Flash_pause (fc);
+ *
+ * // We set the flashing rectangle full on, to indicate the current
+ * // selection while the popup is active.
+ * Flash_setState (FlashState_on);
+ * ...
+ * // Continue the flashing.
+ * Flash_continue (fc);
+ * ...
+ * // Modifying the graphics of the area that is flashing:
+ * void Flash_preUpdate (fc);
+ * ... // do drawing
+ * void Flash_postUpdate (fc);
+ * ...
+ * // We're done. Terminating the flash restores the flash area to its
+ * // original state.
+ * Flash_terminate (fc);
+ *
+ *
+ * Periodically, Flash_process() should be called on the flash context,
+ * so that the flashing square is updated.
+ * You can use Flash_nextTime() to determine when the next update is needed,
+ * or just call Flash_process() to try (it does no updates if not needed).
+ *
+ * Limitations:
+ *
+ * * Functions that draw to the gfxContext or read the original gfxContext
+ * contents, which is most of them, must be called with gfxContext having
+ * the same clip-rect as it did when other drawing functions were called.
+ * Otherwise, original contents restoration may draw to the wrong area, or
+ * the wrong area may be read.
+ * There may be cases where one would *want* that to happen, and such
+ * cases are not covered by this limitation.
+ * * Multiple flashes may be used simultaneously, but don't let them
+ * overlap; artifacts would occur.
+ */
+
+#include "libs/gfxlib.h"
+#include "libs/timelib.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+typedef enum {
+ FlashState_fadeIn = 0,
+ // Someway between on and off, going towards on.
+ FlashState_on = 1,
+ // The overlay image is visible at 100% opacity.
+ FlashState_fadeOut = 2,
+ // Someway between on and off, going towards off.
+ FlashState_off = 3,
+ // The overlay image is not visible.
+} FlashState;
+
+typedef struct FlashContext FlashContext;
+
+#ifdef FLASH_INTERNAL
+typedef enum {
+ FlashType_highlight,
+ FlashType_transition,
+ FlashType_overlay,
+} FlashType;
+
+struct FlashContext {
+ CONTEXT gfxContext;
+ // The graphics context used for drawing.
+
+ RECT rect;
+ // The rectangle to flash.
+
+ FRAME original;
+ // The original contents of the flash area.
+
+ FlashType type;
+ // The type of flash animation.
+
+ union {
+ /*struct {
+ } highlight;*/
+ struct {
+ FRAME first;
+ // The first image from the transition (cross-fade).
+ // (FRAME) 0 means that the original is to be used.
+ FRAME final;
+ // The last image from the transition.
+ // (FRAME) 0 means that the original is to be used.
+ } transition;
+ struct {
+ FRAME frame;
+ } overlay;
+ } u;
+
+ int startNumer;
+ // Numerator for the merge factor for the on state.
+ int endNumer;
+ // Numerator for the merge factor for the off state.
+ int denom;
+ // Denominator for the merge factor.
+
+ TimeCount fadeInTime;
+ TimeCount onTime;
+ TimeCount fadeOutTime;
+ TimeCount offTime;
+
+ TimeCount frameTime;
+
+ FlashState state;
+ TimeCount lastStateTime;
+ // Time of the last state change.
+ TimeCount lastFrameTime;
+ // Time of the last frame draw.
+
+ BOOLEAN started;
+ BOOLEAN paused;
+
+ FRAME *cache;
+ COUNT cacheSize;
+
+ COUNT lastFrameIndex;
+ // Last frame drawn; used to determine whether a frame needs to
+ // be redawn. If a cache is used, this is the index in the cache.
+ // If no cache is used, this is either 0, 1, or 2, for
+ // the respectively first, last, or other frame for the flash
+ // animation.
+};
+
+# define Flash_DEFAULT_FADE_IN_TIME 0
+# define Flash_DEFAULT_ON_TIME (ONE_SECOND / 8)
+# define Flash_DEFAULT_FADE_OUT_TIME 0
+# define Flash_DEFAULT_OFF_TIME (ONE_SECOND / 8)
+
+# define Flash_DEFAULT_CACHE_SIZE 9
+#endif /* FLASH_INTERNAL */
+
+
+FlashContext *Flash_createHighlight (CONTEXT gfxContext, const RECT *rect);
+FlashContext *Flash_createTransition (CONTEXT gfxContext,
+ const POINT *origin, FRAME first, FRAME final);
+FlashContext *Flash_createOverlay (CONTEXT gfxContext,
+ const POINT *origin, FRAME overlay);
+
+void Flash_setState (FlashContext *context, FlashState state,
+ TimeCount timeSpentInState);
+void Flash_start (FlashContext *context);
+void Flash_terminate (FlashContext *context);
+void Flash_pause (FlashContext *context);
+void Flash_continue (FlashContext *context);
+void Flash_process (FlashContext *context);
+void Flash_setSpeed (FlashContext *context, TimeCount fadeInTime,
+ TimeCount onTime, TimeCount fadeOutTime, TimeCount offTime);
+void Flash_setMergeFactors(FlashContext *context, int startNumer,
+ int endNumer, int denom);
+void Flash_setFrameTime (FlashContext *context, TimeCount frameTime);
+TimeCount Flash_nextTime (FlashContext *context);
+void Flash_setRect (FlashContext *context, const RECT *rect);
+void Flash_getRect (FlashContext *context, RECT *rect);
+void Flash_setOverlay(FlashContext *context, const POINT *origin,
+ FRAME overlay);
+void Flash_preUpdate (FlashContext *context);
+void Flash_postUpdate (FlashContext *context);
+void Flash_setCacheSize (FlashContext *context, COUNT size);
+COUNT Flash_getCacheSize (const FlashContext *context);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* UQM_FLASH_H_ */