1 /*
2  *  This program is free software; you can redistribute it and/or modify
3  *  it under the terms of the GNU General Public License as published by
4  *  the Free Software Foundation; either version 2 of the License, or
5  *  (at your option) any later version.
6  *
7  *  This program is distributed in the hope that it will be useful,
8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *  GNU General Public License for more details.
11  *
12  *  You should have received a copy of the GNU General Public License
13  *  along with this program; if not, write to the Free Software
14  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16 
17 #ifndef UQM_FLASH_H_
18 #define UQM_FLASH_H_
19 
20 /*
21  * This code can draw three kinds of flashing areas.
22  * - a rectangular highlight area. The brightness of the area oscilates.
23  * - an overlay; an image is laid over an area, with oscilating brightness.
24  * - a transition/cross-fade between two images.
25  *
26  * NB. The graphics lock should not be held when any of the Flash functions
27  *     is called.
28  *
29  *
30  * Example:
31  *
32  * // We create the flash context; it is used to manipulate the flash
33  * // rectangle while it exists.
34  * FlashContext *fc = Flash_createHighlight (gfxContext, rect);
35  *
36  * // Specify how bright the flash is at the beginning and ending of the
37  * // sequence.
38  * Flash_setMergeFactors(fc, 2, 3, 2);
39  *
40  * // We change the flashing speed from the defaults.
41  * Flash_setSpeed (fc, ONE_SECOND, ONE_SECOND, ONE_SECOND, ONE_SECOND);
42  *
43  * // During cross-fades, update 8 times per second.
44  * Flash_setFrameTime (fc, ONE_SECOND / 8);
45  *
46  * // We start the flashing. The default is to start from the "off" state.
47  * Flash_start (fc);
48  *
49  * // Some other stuff happens
50  * ...
51  *
52  * // The user has activated the selection. We pause for instance while
53  * // a pop-up window is active.
54  * Flash_pause (fc);
55  *
56  * // We set the flashing rectangle full on, to indicate the current
57  * // selection while the popup is active.
58  * Flash_setState (FlashState_on);
59  * ...
60  * // Continue the flashing.
61  * Flash_continue (fc);
62  * ...
63  * // Modifying the graphics of the area that is flashing:
64  * void Flash_preUpdate (fc);
65  * ... // do drawing
66  * void Flash_postUpdate (fc);
67  * ...
68  * // We're done. Terminating the flash restores the flash area to its
69  * // original state.
70  * Flash_terminate (fc);
71  *
72  *
73  * Periodically, Flash_process() should be called on the flash context,
74  * so that the flashing square is updated.
75  * You can use Flash_nextTime() to determine when the next update is needed,
76  * or just call Flash_process() to try (it does no updates if not needed).
77  *
78  * Limitations:
79  *
80  * * Functions that draw to the gfxContext or read the original gfxContext
81  *   contents, which is most of them, must be called with gfxContext having
82  *   the same clip-rect as it did when other drawing functions were called.
83  *   Otherwise, original contents restoration may draw to the wrong area, or
84  *   the wrong area may be read.
85  *   There may be cases where one would *want* that to happen, and such
86  *   cases are not covered by this limitation.
87  * * Multiple flashes may be used simultaneously, but don't let them
88  *   overlap; artifacts would occur.
89  */
90 
91 #include "libs/gfxlib.h"
92 #include "libs/timelib.h"
93 
94 #if defined(__cplusplus)
95 extern "C" {
96 #endif
97 
98 typedef enum {
99 	FlashState_fadeIn = 0,
100 			// Someway between on and off, going towards on.
101 	FlashState_on = 1,
102 			// The overlay image is visible at 100% opacity.
103 	FlashState_fadeOut = 2,
104 			// Someway between on and off, going towards off.
105 	FlashState_off = 3,
106 			// The overlay image is not visible.
107 } FlashState;
108 
109 typedef struct FlashContext FlashContext;
110 
111 #ifdef FLASH_INTERNAL
112 typedef enum {
113 	FlashType_highlight,
114 	FlashType_transition,
115 	FlashType_overlay,
116 } FlashType;
117 
118 struct FlashContext {
119 	CONTEXT gfxContext;
120 			// The graphics context used for drawing.
121 
122 	RECT rect;
123 			// The rectangle to flash.
124 
125 	FRAME original;
126 			// The original contents of the flash area.
127 
128 	FlashType type;
129 			// The type of flash animation.
130 
131 	union {
132 		/*struct {
133 		} highlight;*/
134 		struct {
135 			FRAME first;
136 					// The first image from the transition (cross-fade).
137 					// (FRAME) 0 means that the original is to be used.
138 			FRAME final;
139 					// The last image from the transition.
140 					// (FRAME) 0 means that the original is to be used.
141 		} transition;
142 		struct {
143 			FRAME frame;
144 		} overlay;
145 	} u;
146 
147 	int startNumer;
148 			// Numerator for the merge factor for the on state.
149 	int endNumer;
150 			// Numerator for the merge factor for the off state.
151 	int denom;
152 			// Denominator for the merge factor.
153 
154 	TimeCount fadeInTime;
155 	TimeCount onTime;
156 	TimeCount fadeOutTime;
157 	TimeCount offTime;
158 
159 	TimeCount frameTime;
160 
161 	FlashState state;
162 	TimeCount lastStateTime;
163 			// Time of the last state change.
164 	TimeCount lastFrameTime;
165 			// Time of the last frame draw.
166 
167 	BOOLEAN started;
168 	BOOLEAN paused;
169 
170 	FRAME *cache;
171 	COUNT cacheSize;
172 
173 	COUNT lastFrameIndex;
174 			// Last frame drawn; used to determine whether a frame needs to
175 			// be redawn. If a cache is used, this is the index in the cache.
176 			// If no cache is used, this is either 0, 1, or 2, for
177 			// the respectively first, last, or other frame for the flash
178 			// animation.
179 };
180 
181 #	define Flash_DEFAULT_FADE_IN_TIME   0
182 #	define Flash_DEFAULT_ON_TIME        (ONE_SECOND / 8)
183 #	define Flash_DEFAULT_FADE_OUT_TIME  0
184 #	define Flash_DEFAULT_OFF_TIME       (ONE_SECOND / 8)
185 
186 #	define Flash_DEFAULT_CACHE_SIZE 9
187 #endif  /* FLASH_INTERNAL */
188 
189 
190 FlashContext *Flash_createHighlight (CONTEXT gfxContext, const RECT *rect);
191 FlashContext *Flash_createTransition (CONTEXT gfxContext,
192 		const POINT *origin, FRAME first, FRAME final);
193 FlashContext *Flash_createOverlay (CONTEXT gfxContext,
194 		const POINT *origin, FRAME overlay);
195 
196 void Flash_setState (FlashContext *context, FlashState state,
197 		TimeCount timeSpentInState);
198 void Flash_start (FlashContext *context);
199 void Flash_terminate (FlashContext *context);
200 void Flash_pause (FlashContext *context);
201 void Flash_continue (FlashContext *context);
202 void Flash_process (FlashContext *context);
203 void Flash_setSpeed (FlashContext *context, TimeCount fadeInTime,
204 		TimeCount onTime, TimeCount fadeOutTime, TimeCount offTime);
205 void Flash_setMergeFactors(FlashContext *context, int startNumer,
206 		int endNumer, int denom);
207 void Flash_setFrameTime (FlashContext *context, TimeCount frameTime);
208 TimeCount Flash_nextTime (FlashContext *context);
209 void Flash_setRect (FlashContext *context, const RECT *rect);
210 void Flash_getRect (FlashContext *context, RECT *rect);
211 void Flash_setOverlay(FlashContext *context, const POINT *origin,
212 		FRAME overlay);
213 void Flash_preUpdate (FlashContext *context);
214 void Flash_postUpdate (FlashContext *context);
215 void Flash_setCacheSize (FlashContext *context, COUNT size);
216 COUNT Flash_getCacheSize (const FlashContext *context);
217 
218 
219 #if defined(__cplusplus)
220 }
221 #endif
222 
223 #endif  /* UQM_FLASH_H_ */
224