Sort include order.
[gemrb.git] / gemrb / core / GlobalTimer.cpp
bloba3af8b7cfd2878d46aa609bef9b761bdd849dc08
1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003-2005 The GemRB Project
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "GlobalTimer.h"
23 #include "ControlAnimation.h"
24 #include "Game.h"
25 #include "GameControl.h"
26 #include "Interface.h"
27 #include "Video.h"
29 GlobalTimer::GlobalTimer(void)
31 //AI_UPDATE_TIME: how many AI updates in a second
32 interval = ( 1000 / AI_UPDATE_TIME );
33 Init();
36 GlobalTimer::~GlobalTimer(void)
38 std::vector<AnimationRef *>::iterator i;
39 for(i = animations.begin(); i != animations.end(); ++i) {
40 delete (*i);
44 void GlobalTimer::Init()
46 fadeToCounter = 0;
47 fadeFromCounter = 0;
48 fadeFromMax = 0;
49 fadeToMax = 0;
50 waitCounter = 0;
51 shakeCounter = 0;
52 startTime = 0; //forcing an update
53 speed = 0;
54 ClearAnimations();
57 void GlobalTimer::Freeze()
59 unsigned long thisTime;
60 unsigned long advance;
62 GetTime( thisTime );
63 advance = thisTime - startTime;
64 if ( advance < interval) {
65 return;
67 startTime = thisTime;
68 Game* game = core->GetGame();
69 if (!game) {
70 return;
72 game->RealTime+=advance;
74 ieDword count = advance/interval;
75 // pst/bg2 do this, if you fix it for another game, wrap it in a check
76 DoFadeStep(count);
78 // show scrolling cursor while paused
79 GameControl* gc = core->GetGameControl();
80 if (gc)
81 gc->UpdateScrolling();
84 bool GlobalTimer::ViewportIsMoving()
86 return (goal.x!=currentVP.x) || (goal.y!=currentVP.y);
89 void GlobalTimer::SetMoveViewPort(ieDword x, ieDword y, int spd, bool center)
91 speed=spd;
92 currentVP=core->GetVideoDriver()->GetViewport();
93 if (center) {
94 x-=currentVP.w/2;
95 y-=currentVP.h/2;
97 goal.x=(short) x;
98 goal.y=(short) y;
101 void GlobalTimer::DoStep(int count)
103 Video *video = core->GetVideoDriver();
105 int x = currentVP.x;
106 int y = currentVP.y;
107 if ( (x != goal.x) || (y != goal.y)) {
108 if (speed) {
109 if (x<goal.x) {
110 x+=speed;
111 if (x>goal.x) x=goal.x;
112 } else {
113 x-=speed;
114 if (x<goal.x) x=goal.x;
116 if (y<goal.y) {
117 y+=speed;
118 if (y>goal.y) y=goal.y;
119 } else {
120 y-=speed;
121 if (y<goal.y) y=goal.y;
123 } else {
124 x=goal.x;
125 y=goal.y;
127 currentVP.x=x;
128 currentVP.y=y;
131 if (shakeCounter) {
132 shakeCounter-=count;
133 if (shakeCounter<0) {
134 shakeCounter=0;
136 if (shakeCounter) {
137 x += (rand()%shakeX) - (shakeX>>1);
138 y += (rand()%shakeY) - (shakeY>>1);
141 video->MoveViewportTo(x,y);
144 void GlobalTimer::Update()
146 Map *map;
147 Game *game;
148 GameControl* gc;
149 unsigned long thisTime;
150 unsigned long advance;
152 gc = core->GetGameControl();
153 if (gc)
154 gc->UpdateScrolling();
156 UpdateAnimations();
158 GetTime( thisTime );
160 if (!startTime) {
161 startTime = thisTime;
162 return;
165 advance = thisTime - startTime;
166 if ( advance < interval) {
167 return;
169 ieDword count = advance/interval;
170 DoStep(count);
171 DoFadeStep(count);
172 if (!gc) {
173 goto end;
175 game = core->GetGame();
176 if (!game) {
177 goto end;
179 map = game->GetCurrentArea();
180 if (!map) {
181 goto end;
183 //do spell effects expire in dialogs?
184 //if yes, then we should remove this condition
185 if (!(gc->GetDialogueFlags()&DF_IN_DIALOG) ) {
186 map->UpdateFog();
187 map->UpdateEffects();
188 if (thisTime) {
189 //this measures in-world time (affected by effects, actions, etc)
190 game->AdvanceTime(count);
193 //this measures time spent in the game (including pauses)
194 if (thisTime) {
195 game->RealTime+=advance;
197 end:
198 startTime = thisTime;
202 void GlobalTimer::DoFadeStep(ieDword count) {
203 Video *video = core->GetVideoDriver();
204 if (fadeToCounter) {
205 fadeToCounter-=count;
206 if (fadeToCounter<0) {
207 fadeToCounter=0;
209 video->SetFadePercent( ( ( fadeToMax - fadeToCounter ) * 100 ) / fadeToMax );
210 //bug/patch #1837747 made this unneeded
211 //goto end; //hmm, freeze gametime?
213 //i think this 'else' is needed now because of the 'goto' cut above
214 else if (fadeFromCounter!=fadeFromMax) {
215 if (fadeFromCounter>fadeFromMax) {
216 fadeFromCounter-=count;
217 if (fadeFromCounter<fadeFromMax) {
218 fadeFromCounter=fadeFromMax;
220 //don't freeze gametime when already dark
221 } else {
222 fadeFromCounter+=count;
223 if (fadeToCounter>fadeFromMax) {
224 fadeToCounter=fadeFromMax;
226 video->SetFadePercent( ( ( fadeFromMax - fadeFromCounter ) * 100 ) / fadeFromMax );
227 //bug/patch #1837747 made this unneeded
228 //goto end; //freeze gametime?
231 if (fadeFromCounter==fadeFromMax) {
232 video->SetFadePercent( 0 );
236 void GlobalTimer::SetFadeToColor(unsigned long Count)
238 if(!Count) {
239 Count = 64;
241 fadeToCounter = Count;
242 fadeToMax = fadeToCounter;
243 //stay black for a while
244 fadeFromCounter = 128;
245 fadeFromMax = 0;
248 void GlobalTimer::SetFadeFromColor(unsigned long Count)
250 if(!Count) {
251 Count = 64;
253 fadeFromCounter = 0;
254 fadeFromMax = Count;
257 void GlobalTimer::SetWait(unsigned long Count)
259 waitCounter = Count;
262 void GlobalTimer::AddAnimation(ControlAnimation* ctlanim, unsigned long time)
264 AnimationRef* anim;
265 unsigned long thisTime;
267 GetTime( thisTime );
268 time += thisTime;
270 // if there are no free animation reference objects,
271 // alloc one, else take the first free one
272 if (first_animation == 0)
273 anim = new AnimationRef;
274 else {
275 anim = animations.front ();
276 animations.erase (animations.begin());
277 first_animation--;
280 // fill in data
281 anim->time = time;
282 anim->ctlanim = ctlanim;
284 // and insert it into list of other anim refs, sorted by time
285 for (std::vector<AnimationRef*>::iterator it = animations.begin() + first_animation; it != animations.end (); it++) {
286 if ((*it)->time > time) {
287 animations.insert( it, anim );
288 anim = NULL;
289 break;
292 if (anim)
293 animations.push_back( anim );
296 void GlobalTimer::RemoveAnimation(ControlAnimation* ctlanim)
298 // Animation refs for given control are not physically removed,
299 // but just marked by erasing ptr to the control. They will be
300 // collected when they get to the front of the vector
301 for (std::vector<AnimationRef*>::iterator it = animations.begin() + first_animation; it != animations.end (); it++) {
302 if ((*it)->ctlanim == ctlanim) {
303 (*it)->ctlanim = NULL;
308 void GlobalTimer::UpdateAnimations()
310 unsigned long thisTime;
311 GetTime( thisTime );
312 while (animations.begin() + first_animation != animations.end()) {
313 AnimationRef* anim = animations[first_animation];
314 if (anim->ctlanim == NULL) {
315 first_animation++;
316 continue;
319 if (anim->time <= thisTime) {
320 anim->ctlanim->UpdateAnimation();
321 first_animation++;
322 continue;
324 break;
328 void GlobalTimer::ClearAnimations()
330 first_animation = (unsigned int) animations.size();
333 void GlobalTimer::SetScreenShake(unsigned long shakeX, unsigned long shakeY,
334 unsigned long Count)
336 this->shakeX = shakeX;
337 this->shakeY = shakeY;
338 shakeCounter = Count+1;