HookTimer problem
Displaying 1-10 of 10 total.
1
Please enter a numerical value for the importance of this sticky.
Enter 0 to unsticky.
gungnir

Okay, so I have a function to track time, and I use HookTimer('my_timer') to set it.


void my_timer ()
{
if (timer_paused)
return;
hour_timer++;
if (hour_timer >= ONE_HOUR)
{
hour_timer = 0;
game_hour++;
if (game_hour >= 24)
{
game_hour = 0;
game_day++;
}
}
}


Anyways, when I enter a menu, I try to pause the timer, by setting the timer_paused variable to 1. After being in the menu for a while, and then exiting (where timer_paused goes back to 0), I am dismayed to find that the timer kept on going while I was in the menu. It's almost as if the seting of this variable (which is, of course, a global) is not working. I tried the following to be sure it wasn't a problem with return:


void my_timer ()
{
if (!timer_paused)
{
hour_timer++;
if (hour_timer >= ONE_HOUR)
{
hour_timer = 0;
game_hour++;
if (game_hour >= 24)
{
game_hour = 0;
game_day++;
}
}
}
}


There's a strong possibility that I'm simply missing something, but perhaps I'm encountering an actual bug, so I thought I'd mention it.

/g

Posted on 2004-10-13 02:31:11 (last edited on 2004-10-13 02:43:02)

blues_zodiakos

If it's the only hooktimer you are using (no layered code) then you could just HookTimer(''); until you need it again...

Perhaps Timer_Paused is reserved and nobody said anything. X/

Also... are you sure RELEASE mode isn't enabled? It could be just using the same compiled code over and over. :D

Don't listen to me, all my helpful tips always end up sucking. :p

Posted on 2004-10-13 02:51:42

gungnir

Nope, release mode isn't set and I had the variable as timer_pause to start with and I just tried tpawzd. No luck :(

/g

Posted on 2004-10-13 04:32:46

vecna

My guess is that something else funky is going on in the code. However, there's another possibility, I consider it unlikely, but who knows.

Since I changed hooktimer away from being threaded, the actual hooktimer calls no longer interrupt whatever might happen to be executing at the time. Instead they are kept track of and pooled and then executed sequentially at a point where it knows its safe to do so.

If they were basically all being pooled and then all executed at once after you set timer_paused back to 0, then you'd get that behavior.

But, verge dumps those hooktimer calls at number of opportunities, including every time controls are checked or Showpage() is done. I doubt if you're going through a menu without ever calling ShowPage, so that seems like its probably not the problem.

Otherwise, I suggest dumping a 'logconsole 1' in your verge.cfg and making use of Log() to see whats going on in realtime.

Posted on 2004-10-13 05:14:36

gungnir

Now, I've used log to track what's happening to the timer_paused variable, and it appears to be getting set back to 0 after a single tick. In other words, after I set the timer_paused variable to 1, the first time my_timer is called, it sees timer_paused as 1. However, each subsequent call sees timer_paused as 0.

At any rate, here is all of the code I'm using to run this test:


#define ONE_HOUR 200

int timer_paused = 0;
int hour_timer,game_hour,game_day = 1;
int fonto;
int plyr;
int menuopen = 0;

void autoexec ()
{
initialize_stuff ();
HookTimer ('my_timer');
map ('paround.map');
}

void initialize_stuff ()
{
fonto = LoadFont ('shadowc.png');
EnableVariableWidth (fonto);
SetButtonKey (1, SCAN_ALT);
SetButtonKey (2, SCAN_CTRL);
SetButtonKey (3, SCAN_ENTER);
SetButtonKey (4, SCAN_ESC);
}

void cleanup ()
{
FreeFont (fonto);
Exit ('');
}

void my_timer ()
{
if (timer_paused)
return;
hour_timer++;
if (hour_timer >= ONE_HOUR)
{
hour_timer = 0;
game_hour++;
if (game_hour >= 24)
{
game_hour = 0;
game_day++;
}
}
}

void start_map ()
{
plyr = EntitySpawn(8,11,'temmin.chr');
setPlayer (plyr);
HookButton (3,'open_menu');
HookKey (SCAN_Q,'cleanup');
}

void open_menu ()
{
if (menuopen == 1)
return;
SetEntitiesPaused (1);
menuopen = 1;
timer_paused = 1;
PrintString (0,0,screen,fonto,'Day: ' + str(game_day) + ', Hour: ' + str(game_hour));
ShowPage ();
Unpress (1);
while (!b1)
UpdateControls ();
Unpress (1);
timer_paused = 0;
menuopen = 0;
SetEntitiesPaused (0);
}


Nothing complicated going on here, but I still have the problem. I press b3 to invoke day/time display. Then I wait several seconds (for testing purposes, 200 ticks is one hour) and press b1 to exit the 'menu'. Then I quickly press b3 again to see the day/time, and it's advanced as if I had never tried to stop it.

I logged the timer_paused variable at the very start of the my_timer function, and my log showed me a series of 0s, then a single 1, and then more 0s.

I've posted the whole test in a zip here if you'd care to try it.

This includes a log with the results I mentioned above.

EDIT: I tried logging a message just before I set timer_paused to 1 and then again just before setting timer_paused to 0 and I get this in the log:

0
0
0
Paused timer
1
Unpaused timer
0
0
0

And that's with waiting several seconds in between. It's as if it is playing catch-up afterwards.


/g

Posted on 2004-10-13 06:33:55 (last edited on 2004-10-13 06:42:28)

Wolf

Quote:Originally posted by gungnir



void open_menu ()
{
if (menuopen == 1)
return;
SetEntitiesPaused (1);
menuopen = 1;
timer_paused = 1;
PrintString (0,0,screen,fonto,'Day: ' + str(game_day) + ', Hour: ' + str(game_hour));
ShowPage ();
Unpress (1);
while (!b1)
UpdateControls ();
Unpress (1);
timer_paused = 0;
menuopen = 0;
SetEntitiesPaused (0);
}


Nothing complicated going on here, but I still have the problem. I press b3 to invoke day/time display. Then I wait several seconds (for testing purposes, 200 ticks is one hour) and press b1 to exit the 'menu'. Then I quickly press b3 again to see the day/time, and it's advanced as if I had never tried to stop it.

I`m pretty sure it's because the screen doesn't get updated.
The timer goes on fine, but you're not rendering and showpaging the screen, because you have:
while (!b1)

UpdateControls ();

Try it with:
while (!b1)

{
Render();
PrintString (0,0,screen,fonto,'Day: ' + str(game_day) + ', Hour: ' + str(game_hour));
Showpage();
}
Unpress(1);


I think that will work.

Posted on 2004-10-13 07:49:11

gungnir

I think my real problem is that I was assuming that the 'my_timer' function would be called every 1/100 of a second regardless of what I'm doing in my code... you know, like it was threaded or handled by way of interrupt processing. But, it does not appear to be handled that way. It also seems that anything that does get Hooked to the timer will play catch-up as soon as it get's a chance.

So yes, you are correct because unless I have Render or ShowPage being called constantly, my_timer() isn't going to be called and it's going to queue up. That's just different from what I had assumed. I'm not a big fan of constantly updating the screen even when nothing is going on though, so this does work against me, and I'll have to rework a few things. Oh well, better to discover this early on I suppose :)

/jb

Posted on 2004-10-14 02:43:21

mcgrue

Like I told Gayo to his dismay, it really is best to make your movement and animation based on functions of time. The timer is reliable to accurattely report how much time has presently elapsed, so if you make your code only work on the principle that it'll be recieving the present time and that's it, your game will be properly timed even on Pentium Is.

Posted on 2004-10-14 14:23:13

vecna

A few quick notes.

You do not have to re-render everything to call Showpage(), and I strongly recommend you keep at least showpage in your waiting loops anyway because if you're running in windowed mode, or fullscreen and you alt-tab out, basically, if some other app overdraws the window/screen, it will not be refreshed until Showpage is called again.

(eg, you can just call showpage, you don't need to re-render your map or your menu or whatnot- the contents of screen hasn't changed, you're just re-blasting it to the physical screen. additionally, theres not really any benefit to doing a wait for keypress loop that way, you aren't saving any cpu usage by not re-rendering. If you want to be cpu-usage conscious, make use of Sleep() instead, but still call showpage).

Second, if the timer queue is not being dumped on updatecontrols, that's a bug and I'll fix it. It's also dumped on a few other events, but I guess those dont fire when you're just sitting in a updatecontrols poll loop.

Posted on 2004-10-14 22:32:20

gungnir

No, it's all cool. I wasn't necessarily trying to be CPU conscious... I'm just lazy :) It's just a little different from what I had assumed and it's really my fault for making the assumption. Like I said, better I realize this now and only have to make changes in a couple of spots instead of later when it could be a couple of dozen spots.

Thanks dudes.
/g

Posted on 2004-10-16 00:18:59


Displaying 1-10 of 10 total.
1
 
Newest messages

Ben McGraw's lovingly crafted this website from scratch for years.
It's a lot prettier this go around because of Jon Wofford.
Verge-rpg.com is a member of the lunarnet irc network, and would like to take this opportunity to remind you that regardless how babies taste, it is wrong to eat them.