English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General

 
 
Thread Tools
Old 11 June 2018, 14:17   #1
Tigerskunk
Inviyya Dude!
 
Tigerskunk's Avatar
 
Join Date: Sep 2016
Location: Amiga Island
Posts: 2,770
How to do 25 hz/fps properly?

I always thought that would be something super easy, just wait two frames until switching to the other buffer and blit like crazy all the time...

Well, seems it isn't...

I tried a couple of things with a two step counter, like deactivating the vbl wait on each even frame, and switching buffers on every two frames instead of each.

But somehow stuff doesn't work out.

So, how would you guys implement a proper "have two frames for drawing stuff" 25hz mode?
Tigerskunk is offline  
Old 11 June 2018, 14:27   #2
Shatterhand
Warhasneverbeensomuchfun
 
Shatterhand's Avatar
 
Join Date: Jun 2001
Location: Rio de Janeiro / Brazil
Age: 41
Posts: 3,450
Well, in Blitz what I am doing right now is basically I do half of my operations/blitz, wait for the vblank (with a VWait command in Blitz) and then do the other half. THEN I switch buffer.

What I need to be sure is that each "half" of commands will fit on a frame, or else we fall on 17 hz territory.

To do that I split my BOBs on 2 separate lists.

For me it's working pretty well so far.
Shatterhand is offline  
Old 11 June 2018, 14:45   #3
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,322
I use a frame counter for this.
For running in 2 frames, it is set to be 2. Then it is decremented every frame (in the vertical blank interrupt).

In main program, in the loop :
- draw your stuff,
- wait 1 vbl (to keep in sync even in cases it was too slow),
- as long as the counter hasn't gone to zero, wait another vbl.
meynaf is offline  
Old 11 June 2018, 14:52   #4
Tigerskunk
Inviyya Dude!
 
Tigerskunk's Avatar
 
Join Date: Sep 2016
Location: Amiga Island
Posts: 2,770
Quote:
Originally Posted by Shatterhand View Post
To do that I split my BOBs on 2 separate lists.

Keeping two lists is what I really would like to avoid. :/

@meynaf:
What I don't get: If I draw more than one frame allows, and then wait for VBL, and then for another one, my game will slow down to 17hz, won't it?
Tigerskunk is offline  
Old 11 June 2018, 15:19   #5
Master484
Registered User
 
Master484's Avatar
 
Join Date: Nov 2015
Location: Vaasa, Finland
Posts: 524
For 25 FPS I also use a frame counter that starts from 0, and +1 is added to it in every vertical blank interrupt.

But I have only 1 wait for vbl.

But just before the "wait for vbl" command happens, I have a separate waiting loop which waits for the frame counter to reach 2. And somehow, after the interrupt has updated the value to 2 and program flow switches back to the main code, the main code vbl wait can still "reach" that same vbl that triggered the interrupt.

In Blitz Basic this method works fine, don't know if ASM is different.
Master484 is offline  
Old 11 June 2018, 15:32   #6
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Code:
vbl_irq	addq.b	#1,_25hz_flag
	ble.b	.skip
	tst.b	_done_flag
	bne.b	.skip
	
	update_all

	st	_25hz_flag	; move.b #$fe for 17hz and so on
	st	_done_flag

.skip	some_irq_exit_code
	rte

_25hz_flag	dc.b	-1
_done_flag	dc.b	-1

main_loop
	if (main_draw_completed) sf _done_flag;
	while (_done_flag==0) loop;
ross is offline  
Old 11 June 2018, 15:43   #7
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,322
Quote:
Originally Posted by Steril707 View Post
@meynaf:
What I don't get: If I draw more than one frame allows, and then wait for VBL, and then for another one, my game will slow down to 17hz, won't it?
Of course. So you need to detect this case and wait only 1 vbl.

If you draw more than one frame allows, you will have one vbl interrupt during that. Then the counter will be decremented. Then you will detect that one frame occured, and wait only for one vbl.

More precisely...

Events for drawing smaller than 1 frame :
- init counter to 2
- draw the stuff
- counter is 2 so you wait 2 vbl

Events for drawing in more than 1 frame :
- init counter to 2
- draw during 1 frame
- vbl interrupt sets counter to 1
- finish drawing
- counter is 1 so you wait 1 vbl
meynaf is offline  
Old 11 June 2018, 15:52   #8
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
If you use a Graphics.library-style blitter interrupt to draw your bobs and so on, you can actually let the blitter blit and use the CPU to run the program at the same time! Just using QBlit to do any unusual blitting such as filling and so on allows you to use Graphics.library itself if you're so inclined. This is to avoid having multiple blitter lists.

Last edited by Samurai_Crow; 11 June 2018 at 16:12.
Samurai_Crow is offline  
Old 11 June 2018, 17:19   #9
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Perhaps Steril707's game engine is itself running in VBL? He didn't say that explicitely. This would make things a little bit more complicated.
phx is offline  
Old 11 June 2018, 17:41   #10
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by phx View Post
Perhaps Steril707's game engine is itself running in VBL? He didn't say that explicitely. This would make things a little bit more complicated.
Actually is the same

Code:
vbl_irq	move.w	#$20,$dff09c	; this if only level3 vbl irq in $dff09a..
	move	#$2200,sr	; make reentrant
	addq.b	#1,_25hz_flag
	ble.b	.skip
	tst.b	_done_flag
	bne.b	.skip
	
	update_all		; sprite/bpl pointer (switch double buffer)
	
	st	_25hz_flag	; move.b #$fe for 17hz and so on
	st	_done_flag
	make_screen		; double buffer logic inside
	sf	_done_flag

.skip	rte

_25hz_flag	dc.b	-1
_done_flag	dc.b	0
EDIT: just noticed a possible 'academic' stack overflow in my code.
I think it's practically impossible that it happens in real cases... but is just an instruction, so:
Code:
	make_screen		; double buffer logic inside
	move	#$2300,sr	; <-- insert this
	sf	_done_flag      ; [protect flag from (repeated)-irq between sf and rte]

Last edited by ross; 11 June 2018 at 18:28.
ross is offline  
Old 12 June 2018, 18:29   #11
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by ross View Post
Actually is the same

Code:
vbl_irq    move.w    #$20,$dff09c    ; this if only level3 vbl irq in $dff09a..
    move    #$2200,sr    ; make reentrant
Hmm. Really? As far as I understand that wouldn't give you the possibility to finish your update_all, when it takes more than 20ms, because the current VBL is interrupted by the next VBL, which restarts update_all from the beginning.
phx is offline  
Old 12 June 2018, 18:40   #12
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by phx View Post
Hmm. Really? As far as I understand that wouldn't give you the possibility to finish your update_all, when it takes more than 20ms, because the current VBL is interrupted by the next VBL, which restarts update_all from the beginning.
At first I did not remember why I had written this code yesterday, now I remember
update_all is a really fast routine only changing bpl and sprite pointers (double buffer swith) so it can not last 20ms but only few video lines!
[sure the name is misleading, it should be something like update_pointers or buffers_switch]

All the drawing is on make_screen.

So the double barrier:
Code:
	addq.b	#1,_25hz_flag
	ble.b	.skip
	tst.b	_done_flag
	bne.b	.skip
can work.

At the end writing like this:
Code:
	st	_25hz_flag	; move.b #$fe for 17hz and so on
	st	_done_flag
	update_all		; sprite/bpl pointer (switch double buffer)
	make_screen		; double buffer logic inside
does not make any difference.

Sorry for the multiple edit, my memory does not work anymore as it should

Last edited by ross; 12 June 2018 at 19:22.
ross is offline  
Old 12 June 2018, 23:15   #13
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by ross View Post
update_all is a really fast routine only changing bpl and sprite pointers (double buffer swith)
Oh, yes. I was already wondering why the comment didn't really match the function name.

Quote:
All the drawing is on make_screen.
Ok. I see. The _done_flag makes every second interrupt skip the make_screen routine, which continues to run in the previous interrupt context, when the new one returns.
phx is offline  
Old 13 June 2018, 08:14   #14
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by phx View Post
Ok. I see. The _done_flag makes every second interrupt skip the make_screen routine, which continues to run in the previous interrupt context, when the new one returns.
You got it.
The beauty of this approach is that it is a general solution.
No special cases for specific situation and it works for every requested frame rate (actually frame rate below <0.4 fps is not supported )
ross is offline  
Old 13 June 2018, 09:38   #15
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,771
Quote:
Originally Posted by ross View Post
(actually frame rate below <0.4 fps is not supported )
That rules out most modern Amiga demos then.
Hewitson is offline  
Old 13 June 2018, 09:47   #16
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by Hewitson View Post
That rules out most modern Amiga demos then.
Surely you forgot to add a smiley face

(in any case it is really trivial to adapt it to any framerate)
ross is offline  
Old 13 June 2018, 11:36   #17
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,771
Whilst I was obviously exaggerating, it is true that most demos released for the Amiga in the last 20 years or so run like slideshows even on an 060.

On the C64, a demo would be laughed at if it didn't run at 50fps on a standard machine.
Hewitson is offline  
Old 13 June 2018, 11:44   #18
britelite
Registered User
 
Join Date: Feb 2010
Location: Espoo / Finland
Posts: 818
Quote:
Originally Posted by Hewitson View Post
Whilst I was obviously exaggerating, it is true that most demos released for the Amiga in the last 20 years or so run like slideshows even on an 060.
You have a weird definition of slideshows in that case

Quote:
On the C64, a demo would be laughed at if it didn't run at 50fps on a standard machine.
A lot of C64 demos which are regarded as classics have stuff running below 50fps.
britelite is offline  
Old 15 June 2018, 15:19   #19
Megol
Registered User
 
Megol's Avatar
 
Join Date: May 2014
Location: inside the emulator
Posts: 377
Quote:
Originally Posted by Hewitson View Post
Whilst I was obviously exaggerating, it is true that most demos released for the Amiga in the last 20 years or so run like slideshows even on an 060.

On the C64, a demo would be laughed at if it didn't run at 50fps on a standard machine.
I can assure you nobody laughed at the Andropolis 3D part.
Megol is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
The Best Amiga 3D FPS Steve Retrogaming General Discussion 112 22 November 2015 16:28
Less than 50 fps...? pmc Coders. General 4 19 April 2010 11:59
ADoom FPS W4r3DeV1L support.Games 5 09 December 2008 15:56
200 % fps turrican3 request.UAE Wishlist 13 30 July 2008 18:34
FPS Adjustment Crow777 support.WinUAE 1 07 July 2008 00:47

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 08:44.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.13266 seconds with 15 queries