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"
25 #include "GameControl.h"
26 #include "Interface.h"
29 GlobalTimer::GlobalTimer(void)
31 //AI_UPDATE_TIME: how many AI updates in a second
32 interval
= ( 1000 / AI_UPDATE_TIME
);
36 GlobalTimer::~GlobalTimer(void)
38 std::vector
<AnimationRef
*>::iterator i
;
39 for(i
= animations
.begin(); i
!= animations
.end(); ++i
) {
44 void GlobalTimer::Init()
52 startTime
= 0; //forcing an update
57 void GlobalTimer::Freeze()
59 unsigned long thisTime
;
60 unsigned long advance
;
63 advance
= thisTime
- startTime
;
64 if ( advance
< interval
) {
68 Game
* game
= core
->GetGame();
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
78 // show scrolling cursor while paused
79 GameControl
* gc
= core
->GetGameControl();
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
)
92 currentVP
=core
->GetVideoDriver()->GetViewport();
101 void GlobalTimer::DoStep(int count
)
103 Video
*video
= core
->GetVideoDriver();
107 if ( (x
!= goal
.x
) || (y
!= goal
.y
)) {
111 if (x
>goal
.x
) x
=goal
.x
;
114 if (x
<goal
.x
) x
=goal
.x
;
118 if (y
>goal
.y
) y
=goal
.y
;
121 if (y
<goal
.y
) y
=goal
.y
;
133 if (shakeCounter
<0) {
137 x
+= (rand()%shakeX
) - (shakeX
>>1);
138 y
+= (rand()%shakeY
) - (shakeY
>>1);
141 video
->MoveViewportTo(x
,y
);
144 void GlobalTimer::Update()
149 unsigned long thisTime
;
150 unsigned long advance
;
152 gc
= core
->GetGameControl();
154 gc
->UpdateScrolling();
161 startTime
= thisTime
;
165 advance
= thisTime
- startTime
;
166 if ( advance
< interval
) {
169 ieDword count
= advance
/interval
;
175 game
= core
->GetGame();
179 map
= game
->GetCurrentArea();
183 //do spell effects expire in dialogs?
184 //if yes, then we should remove this condition
185 if (!(gc
->GetDialogueFlags()&DF_IN_DIALOG
) ) {
187 map
->UpdateEffects();
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)
195 game
->RealTime
+=advance
;
198 startTime
= thisTime
;
202 void GlobalTimer::DoFadeStep(ieDword count
) {
203 Video
*video
= core
->GetVideoDriver();
205 fadeToCounter
-=count
;
206 if (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
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
)
241 fadeToCounter
= Count
;
242 fadeToMax
= fadeToCounter
;
243 //stay black for a while
244 fadeFromCounter
= 128;
248 void GlobalTimer::SetFadeFromColor(unsigned long Count
)
257 void GlobalTimer::SetWait(unsigned long Count
)
262 void GlobalTimer::AddAnimation(ControlAnimation
* ctlanim
, unsigned long time
)
265 unsigned long 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
;
275 anim
= animations
.front ();
276 animations
.erase (animations
.begin());
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
);
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
;
312 while (animations
.begin() + first_animation
!= animations
.end()) {
313 AnimationRef
* anim
= animations
[first_animation
];
314 if (anim
->ctlanim
== NULL
) {
319 if (anim
->time
<= thisTime
) {
320 anim
->ctlanim
->UpdateAnimation();
328 void GlobalTimer::ClearAnimations()
330 first_animation
= (unsigned int) animations
.size();
333 void GlobalTimer::SetScreenShake(unsigned long shakeX
, unsigned long shakeY
,
336 this->shakeX
= shakeX
;
337 this->shakeY
= shakeY
;
338 shakeCounter
= Count
+1;