It is currently Fri Dec 15, 2017 9:07 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: Advice for timing
PostPosted: Sun Nov 20, 2016 7:34 pm 
Offline

Joined: Fri Oct 28, 2016 12:37 pm
Posts: 15
I have some sprites I'm trying to control the speed of, or how often they move.

What I have done is place a counter in my NMI,

Code:
; increase frame counter
LDA frameCounter
CLC
ADC #$01
STA frameCounter


In my game logic, which is separate from my NMI code, I check if frameCounter is greater than 30 (or roughly half a second) and I move my sprites if that condition is true. I then reset the frame counter back to zero.

Is this a common approach to timing? I figure the NMI will fire roughly 60 times a second so I can piggyback off that?

In Allegro and SDL I would get the current time and compare if the elapsed time between the last movement was greater than some timing variable.


Top
 Profile  
 
 Post subject: Re: Advice for timing
PostPosted: Sun Nov 20, 2016 7:54 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19347
Location: NE Indiana, USA (NTSC)
Yes, that's one way of indicating to the main thread that an NMI has occurred.

But there's a shortcut for the addition:
Code:
inc frameCounter


If your NMI handler is fairly simple, this also saves you from having to push and pull A so as not to disrupt the main thread's use of A. Many of my games so far have used just this sort of trivial NMI handler. You can see it in, for example, my NROM project template:
Code:
.proc nmi_handler
  inc nmis
  rti
.endproc


If you have more than one thing animating at once, you'll need to let frameCounter free-run without resetting it, and then treat frameCounter as you would retrace_count in Allegro: saving the value at the start of an interval and comparing it at the end of an interval.


Top
 Profile  
 
 Post subject: Re: Advice for timing
PostPosted: Sun Nov 20, 2016 8:02 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3487
Location: Indianapolis
You'll want to look at fixed-point addition, aka sub-pixel precision. It's explained pretty well in this thread:
https://forums.nesdev.com/viewtopic.php?f=10&t=12125

I don't know how often a timer-based approach is used for movement, but I can say that I've used it before in my earlier programs and it was ugly and inflexible. Using sub-pixel positioning (with 16 bits for movement rates and positions, where only the upper 8 bits are full pixels) is much cleaner.


Top
 Profile  
 
 Post subject: Re: Advice for timing
PostPosted: Sun Nov 20, 2016 8:19 pm 
Offline
Formerly 43110
User avatar

Joined: Wed Feb 05, 2014 7:01 am
Posts: 313
Location: us-east
like tepples said, I think it's best to not reset the NMI counter variable in main code.

2 ways to implement a half second timer is to have a variable that decrements towards 0 each frame in your main code, or to add 30 with the NMI counter into a different variable and compare that every frame.
Code:
; setup
lda #30
sta timer_1

; for every frame in your main loop
dec timer_1
bne timer_1_not_triggered
  ; do action
timer_1_not_triggered:


This second method is different in that even if the main loop lags, the timer will still fire in at least 30 frames, but it has the disadvantage of having half the range due to using bmi to account for the frameCounter overshooting from lag.
Code:
; setup
clc
lda frameCounter
adc #30
sta timer_2

; for every frame in your main loop
lda frameCounter
cmp timer_2
bmi timer_2_not_triggered
  ; do action
timer_2_not_triggered:


Top
 Profile  
 
 Post subject: Re: Advice for timing
PostPosted: Sun Nov 20, 2016 8:22 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19347
Location: NE Indiana, USA (NTSC)
Memblers wrote:
I don't know how often a timer-based approach is used for movement

Thwaite and RHDE use a 6-frame timer for tiny sprites that need to move only once every tenth of a second or less often. The units in both games move once every 0.2 seconds. Machine guns in several games use a frame count to tell how often to fire. Counting frames between moves is also commonly used for cursor movement and in falling block games for sideways piece movement, both of which behave similarly to keyboard autorepeat.

But for things that change continuously, such as the position of a character in a platformer, I agree that fixed-point arithmetic is the best choice.


Top
 Profile  
 
 Post subject: Re: Advice for timing
PostPosted: Mon Nov 21, 2016 12:24 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5898
Location: Canada
If the numbers involved are powers of two, like 2, 4, 8, 16, etc. as an alternative to storing individual states you can just apply bitwise operations to the free-running frameCounter variable you have.

For example, if you have 4 frames of animation, and want to switch every 8 frames:

Code:
lda frameCounter
lsr
lsr
lsr ; A = frameCounter / 8
and #3 ; A = A % 4
; A is now either 0,1,2,3 and will change every 8 frames.

I don't do this for most of my objects, because I usually want different timings besides ones that line up with 4/8/16 etc. but I still find it's a useful alternative in some cases.

casprog wrote:
Is this a common approach to timing? I figure the NMI will fire roughly 60 times a second so I can piggyback off that?

In Allegro and SDL I would get the current time and compare if the elapsed time between the last movement was greater than some timing variable.

It is a very common approach to count frames in some way, and base your animation timings off of that, yes.

This is often applicable to modern games, too, if they have a fixed framerate design (e.g. fighting games almost always do this). Choosing a fixed vs. variable framerate makes a big impact on a game's design, but with NES normally a fixed framerate approach is presumed.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: Bing [Bot] and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group