#9257 - Lord Graga - Thu Jul 31, 2003 1:46 pm
Hey all, here I go again!
I am using timers in my compo entry. The game is a action game, so it needs a pause function....
My current problem is, that I cannot pause without loosing to current values of the timer, I do this:
Code: |
void Pause(void)
{
u16 t2,t3;
t2 = REG_TM2D;
t3 = REG_TM3D;
REG_TM2CNT = 0;
REG_TM3CNT = 0;
for(i=0;i<30;i++) MoveSprite(&sprites[i],240,160);
Text(13,10,"pause",27);
while(!(*KEYS&KEY_START)) seed++;
while(*KEYS&KEY_START) seed++;
while(!(*KEYS&KEY_START)) seed++;
Text(13,10," ",27);
REG_TM2CNT = FREQUENCY_256 | TIMER_ENABLE;
REG_TM3CNT = TIMER_CASCADE | TIMER_ENABLE;
REG_TM2D = t2;
REG_TM3D = t3;
} |
Could anyone enlighten to me what I am doing wrong?
#9262 - DekuTree64 - Thu Jul 31, 2003 3:42 pm
Replace
Code: |
REG_TM2CNT = FREQUENCY_256 | TIMER_ENABLE;
REG_TM3CNT = TIMER_CASCADE | TIMER_ENABLE;
REG_TM2D = t2;
REG_TM3D = t3;
|
with
Code: |
REG_TM2D = t2;
REG_TM3D = t3;
REG_TM2CNT = FREQUENCY_256 | TIMER_ENABLE;
REG_TM3CNT = TIMER_CASCADE | TIMER_ENABLE;
|
and it should work. Setting a TMxD reg just sets the timer start value, not the current value in it. Enabling a timer makes it start from the last value you wrote to it, so they will continue from t2/t3. But watch out, when timer 2 overflows, it will start back from t2, not 0, so it will be a shorter time until it overflows again. I'm not sure how you'd go about fixing that, all I can think of at the moment is to set an interrupt to set its start value back to 0 the first time it overflows.
Anyone else have a better way?
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku
#9263 - tepples - Thu Jul 31, 2003 6:13 pm
What are you trying to time? And can you time it better off the start of vblank? It's trivial to pause and resume a timer that synchronizes to vblank.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#9267 - Lord Graga - Thu Jul 31, 2003 7:57 pm
I have a countdown timer in my game. When it reaches 0 you die :)
Currently, I use DekuTree64's solution, though it is a bit buggy that you can make the timer "stop" while you press START rapidly :P
#9270 - niltsair - Thu Jul 31, 2003 8:17 pm
You could use a global variable that increase (or drecrease) with every VBlank. It's easy to manage, and work with all emulators(unlike timers)
There's about 60 VBlanks interupst per seconds
#9274 - Lord Graga - Thu Jul 31, 2003 8:38 pm
If you use timers, it will NOT take any memory, since it's hardware based. Also, it's much more precise. It won't be fun with VBLanks, I wouldn't learn anything from it, since I know how to do it allready.
If I can do it in a new way, I'll do that :P
#9279 - niltsair - Thu Jul 31, 2003 9:28 pm
Didn't knew you were aiming at doing it in a way to learn somthing new opposed to do it in a way that work.
I just mentionned it because i remember having lots of trouble with timer untill i realiazed they weren't implemented right in emulators (well, differently from one another).
#9283 - tepples - Thu Jul 31, 2003 11:36 pm
Lord Graga wrote: |
I have a countdown timer in my game. When it reaches 0 you die :) |
In general, setting strict time limits per level in most levels is bad game design. I understand it for coin-ops that have to flush an inactive player off the system, but in a console or handheld game, it's generally considered good practice to allow the player to explore the world. There can be a few time-limited goals, but if the player feels rushed, the game will leave the player with a bad taste.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#9284 - cappeca - Fri Aug 01, 2003 12:07 am
tepples wrote: |
Lord Graga wrote: | I have a countdown timer in my game. When it reaches 0 you die :) |
In general, setting strict time limits per level in most levels is bad game design. I understand it for coin-ops that have to flush an inactive player off the system, but in a console or handheld game, it's generally considered good practice to allow the player to explore the world. There can be a few time-limited goals, but if the player feels rushed, the game will leave the player with a bad taste. |
I think that REALLY depends on the type of game.
#9285 - cappeca - Fri Aug 01, 2003 12:13 am
#include <twocents.h>
niltsair wrote: |
You could use a global variable that increase (or drecrease) with every VBlank. It's easy to manage, and work with all emulators(unlike timers)
|
I don't use VBlank as timer. To me it sounds more like a workaround, since there *are* timers in the machine. Shouldn't the emulators emulate it correctly, instead of the community come to develop a culture of do's and don'ts because of them being all diferent?
Cesar
#9288 - tepples - Fri Aug 01, 2003 12:46 am
cappeca wrote: |
I don't use VBlank as timer. |
Then you disagree with the practice of pretty much every game programmer who has worked on consoles or handhelds since the Atari VCS model 2600. Almost every known game synchronizes its universe updates to some multiple of vblank.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#9294 - cappeca - Fri Aug 01, 2003 3:11 am
tepples wrote: |
cappeca wrote: | I don't use VBlank as timer. |
Then you disagree with the practice of pretty much every game programmer who has worked on consoles or handhelds since the Atari VCS model 2600. |
So what?
I'm not arguing here. Do it with vblank, good. Maybe that was the only way to do it back in the day. All I'm saying is that there are other practices, and judging someone because they use a different - but not wrong - method is quite offensive. I'm insisting on this point because of the posts in this thread:
- I used timers instead of vblank
- YOU WHAT!!?!?!?!
- I'm sorry, sir. It was for educational purposes. Please don't hit me.
"Didn't knew you were aiming at doing it in a way to learn somthing new opposed to do it in a way that work. "
Ouch! What is this? Is there a holy war for the VBlank/Timer now?
Assuming that nobody will use hardware timers - when the hardware provides it - just because some old console cabala says so, and making an emulator that doesn't emulate the CPU right because of such assumptions, is the actual bad design.
#9298 - tepples - Fri Aug 01, 2003 4:59 am
I don't know how to reset timers to a given count part-way through their range. In general, if I don't know how to do something, I step back and ask myself "what are you trying to accomplish by doing this?" and explore alternate approaches. When I wanted to implement pausing in Tetanus On Drugs, I just turned off the ISR's incrementing of the game clock on vblank during pause.
I'm not trying to knock your approach. If you have some free timers, it's ok if you use timers to time your game loop. Just remember that you still have to synchronize your graphics "thread" to vblank, and many have likened synchronization between threads to a female dog. It becomes much easier if you schedule all your threads from the same timer, and vblank is convenient. Also remember that you have only three programmable timers after subtracting the one that will usually be tied up with sound playback. Because associating a hardware timer to each game object will quickly run you out of hardware timers, it's best to multiplex them somehow through a periodic timer.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#9343 - cappeca - Sat Aug 02, 2003 2:18 am
I see. I'm sorry if I came out too harsh.
#9345 - slip - Sat Aug 02, 2003 3:25 am
Well Lord Graga's problem can be fixed many ways, depending on why the timer needs to be reset back to its value before the pause. There is the interrupt idea DekuTree64 had, but as far as I see it your code shouldn't change the value of the TMXD register, once you pause the timer it shouldn't change, that way when you start the timer again it should be at its value it was before.
As for the timers vs Vblank discussion. I use Timers and don't have any problems.
Quote: |
Because associating a hardware timer to each game object will quickly run you out of hardware timers, it's best to multiplex them somehow through a periodic timer. |
That doesn't make a lot of sense to me. You only have one VBlank counter which you arn't going to use multiples of. I use one timer for most my timing. I'm not going to argue that VBlank isn't a good way to do it, because what works works. But to have the opinion to use VBlank because "pretty much every game programmer who has worked on consoles or handhelds since the Atari VCS model 2600" isn't nessasarally a good arguement. First "pretty much" doesn't mean all, and whats the point in implementing Timers in a system if they arn't going to be used. I'm sure Nintendo use them.
I may be wrong about what the discusion is about, but I don't see a problem in using Timers for this purpose, but I do agree with cappeca "judging someone because they use a different - but not wrong - method is quite offensive". Unless you justify why we should use VBlank rather than Timers and its a clear reason, then I don't see why we shouldn't use Timers.
_________________
[url="http://www.ice-d.com"]www.ice-d.com[/url]
#9353 - tepples - Sat Aug 02, 2003 4:30 pm
slip wrote: |
I use one timer for most my timing. |
I'm curious. At what frequency do you set it?
Quote: |
Unless you justify why we should use VBlank rather than Timers and its a clear reason, then I don't see why we shouldn't use Timers. |
Use the programmable timers if you want, but let me explain some of the pro-vblank arguments.
Smooth animation comes from tight synchronization between the display controller and the game code. If you time your game to vblank, you'll get smoother animation without tearing, especially if you're scrolling a couple backgrounds.
If you time your game to vblank, you won't have to worry about contention between your game loop and your hblank/vcount handlers, and you won't get inconsistent data when your timer ISR modifies the game world structures while your vblank code is in the middle of drawing everything.
If you time your game to vblank, it'll work on more emulators. This can be useful if some other program emulates multiple linked GBA systems before somebody forks VisualBoyAdvance to do it.
If you time your game to vblank, you can pause it more easily.
In conclusion, if you time your game to vblank, your code will often be simpler overall. As you said, "what works works," but it's easier to get something simple to a state of "works."
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#9357 - slip - Sat Aug 02, 2003 5:09 pm
I was talking to a friend and now I understand some of the beifits of syncing to Vblank. "it's easier to get something simple to a state of "works."" You are right, but in the case of the count down timer I don't see a great need to use Vblank.
When I set my timer I set the frequency to 1024, at the moment in my current project I'm only using a timer for timing key presses, I've written some code you call once each game loop and it will update a global "Fake register" which is just a unsigned short. It allows you to have repeat times. I'm only using one timer to which I reset each loop but take the value of it first which I use later for the last loop time which is added to a time watcher variable for each key. I get pretty accurate repeat times on hardware and VBA isn't too far off.
I'm going to have to use a Vblank interrupt though to stop tearing like you said syncing to Vblank prevents. =)
_________________
[url="http://www.ice-d.com"]www.ice-d.com[/url]