Screensync / wait / Inp issue

General FreeBASIC programming questions.
h4tt3n
Posts: 698
Joined: Oct 22, 2005 21:12
Location: Denmark

Screensync / wait / Inp issue

Post by h4tt3n »

When trying to optimize games I keep wondering about the screensync command. Is there any other way of synchronizing graphics with the graphics card - one that doesn't stop the entire program and wait until it gets the right feedback?

This way, instead of halting the progam and waiting, you could spend all the remaining time between graphics updates on calculating other stuff.

It seemed obvious to use the Inp command instead:

Since Screensync is basically the same as the old "Wait &h3da, &h8" command, you should be able to synchronize graphics without waiting by doing something like this:

Code: Select all

Do
  "Calculate lots of stuff here"
  If (Inp(&h3da) and &h8) > 0 Then
    "Draw Graphics Here"
  End If
Loop
Except I can't make it work!? It does synchronize graphics to the screen framerate, but it seems to wait too. Any way around this?
DOS386
Posts: 798
Joined: Jul 02, 2005 20:55

INP ???

Post by DOS386 »

It seemed obvious to use the Inp command instead
NO. Don't use INP except for DOS target.
any other way of synchronizing graphics with the graphics card - one that doesn't stop the entire program and wait until it gets the right feedback
Double or triple buffering.
cha0s
Site Admin
Posts: 5319
Joined: May 27, 2005 6:42
Location: USA
Contact:

Post by cha0s »

screenlock

draw

screenunlock
h4tt3n
Posts: 698
Joined: Oct 22, 2005 21:12
Location: Denmark

Post by h4tt3n »

Ah yes, I already always use screenlock / unlock when drawing. This makes things look a lot smoother, agree, but as far as I understand it doesn't synchronize with the graphics card. If a program using lock / unlock is able to run at 10000 fps it will draw to screen just as often, which is a waste of cpu cycles.

What I am looking for is a method that will make the program jump to the draw-to-screen subroutine only when it gets a signal from the graphics card that it has just finished drawing the last image - just as Screensync does, except without the waiting part.

Is this possible in any way ??

So far I've used a frames-per-sec and loop-per-sec counter which manually kept track of things and made the program draw a new screen image apprx. every 1/frame rate secs. It works pretty well but it's not perfect (and I'm a perfectionist ^^).

I suppose that obtaining clear, smooth graphics is such a common problem that almost all of you out there must have worked out the problem one way or another...
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Post by MichaelW »

Under Windows there is DirectDraw GetScanLine, which I have used to synchronize with vertical retrace by testing for DDERR_VERTICALBLANKINPROGRESS, and GetVerticalBlankStatus, which I seem to recall I could not make work.
ikkejw
Posts: 258
Joined: Jan 15, 2006 15:51
Location: Fryslân, the Netherlands
Contact:

Post by ikkejw »

just some thoughts, not sure if it might work:

Code: Select all

dim shared as any ptr m
m = mutexcreate

sub	flipsync_t
	mutexlock m
	screensync
	flip
	mutexunlock m
end sub

#define flipsync _
mutexlock m : threadcreate(@flipsync_t) : mutexunlock m

screenres 1024, 768, 32, 2
screenset 1, 0

do
	'get keyb/mouse input
	
	'calculate stuff
	
	'draw stuff

	flipsync
	sleep 15
loop

mutexdestroy m
Antoni
Posts: 1393
Joined: May 27, 2005 15:40
Location: Barcelona, Spain

Post by Antoni »

Use screensync and a thread in the background doind the things you want to do while waiting.
anonymous1337
Posts: 5494
Joined: Sep 12, 2005 20:06
Location: California

Post by anonymous1337 »

Antoni wrote:Use screensync and a thread in the background doind the things you want to do while waiting.
I saw about this in someone's design documents for a triple buffer and why it would be useful. I didn't get a chance to see how it was done, though.

Thread for your main code
Thread to wait
Update graphics?
Antoni
Posts: 1393
Joined: May 27, 2005 15:40
Location: Barcelona, Spain

Post by Antoni »

Perhaps
put the screen refresh and the wait in the background thread
leave the rest of the code in the main thread
HalfByte
Posts: 20
Joined: Jul 30, 2005 19:27

Post by HalfByte »

A simple method that works well but still has a small amount of flicker.

ScreenLock
--draw graphics--
ScreenUnlock
Sleep 1

~ 60 FPS
low CPU usage
h4tt3n
Posts: 698
Joined: Oct 22, 2005 21:12
Location: Denmark

Post by h4tt3n »

Seems like I need to learn about threading, then. Anyone got some working example code?
Oz
Posts: 586
Joined: Jul 02, 2005 14:21
Location: Waterloo, Ontario, Canada
Contact:

Post by Oz »

I have a relatively useful thing you could use.

Code: Select all

Declare Sub ScrnUpdate( byval n as any ptr )

' Our thread pointer (in all it's glory - sweet nothin)
Dim t As Any Ptr
' Terminate flag - lets the thread know when we're ready to close
Dim Shared terminate As Byte = 0

' Make sure you use 2+ (two or more) pages
ScreenRes 320, 200, 16, 2
' Set our work and visual pages
ScreenSet 0, 1

' Start the thread a'motoring
t = ThreadCreate( @ScrnUpdate, 0 )

Do

  ' Always make sure we screen lock - this will avoid
  ' half-drawn images when it updates
  ScreenLock

  ' Do all the drawing inside the screen lock

  CLS

  Line (1, 1)-(30, 10), rgb( 100, 255, 0 ), bf

  Draw String (50, 50), "Hurray - no flicker (I hope)", rgb( 255, 255, 255 )

  ScreenUnLock

  ' Sleep to free up time-slices (for our thread, and other programs)
  Sleep 1, 1

' Loop until ESCAPE is pressed
Loop Until Multikey( &h01 )
terminate = 1
ThreadWait( t )

End

Sub ScrnUpdate( byval n as any ptr )
  ' This loop just waits until we have verticle sync
  ' Then updates the screen (flips the screen pages)
  do
    ScreenSync
    ScreenLock
    Flip
    ScreenUnLock
    sleep 1, 1
  loop until terminate = 1

End Sub
It's a hack job, but it works

I hope I commented enough.

Oz~
h4tt3n
Posts: 698
Joined: Oct 22, 2005 21:12
Location: Denmark

Post by h4tt3n »

Thanks for your code snippets, Ikkejw and oz. They both work, but they still lower the framerate to about that of the screen. In other words: adding screensync directly to your code is still better. So we're still at point zero...
Oz
Posts: 586
Joined: Jul 02, 2005 14:21
Location: Waterloo, Ontario, Canada
Contact:

Post by Oz »

as a rule of thumb, you never need to slow down your frame rate.
you may want to look up "frame rate independence" if you're making a game. this will let you have a wicked fast frame rate, but keep your program working at a consistant speed.

I have a module for frame rate independence if you are interested in it; it works fine, at any frame rate (but it also has functionality to lower your frame rate to approximately what you want).

Oz
anonymous1337
Posts: 5494
Joined: Sep 12, 2005 20:06
Location: California

Post by anonymous1337 »

Oz wrote:I have a module for frame rate independence if you are interested in it; it works fine, at any frame rate (but it also has functionality to lower your frame rate to approximately what you want).
I have one, too. I call it: TIMER. Yes, time based movement goes as follows:

- Move variables by PixelsPerSecond * ( TIMER - LAST )
- Last = Timer

Very hard indeed (or not). Timer - Last = Difference between a frame's length. That's the amount of that second that's passed. If you move by pixels per second, it works out no matter what your speed is.
Post Reply