Monitor Refresh Rate Question

BlitzMax Forums/BlitzMax Programming/Monitor Refresh Rate Question

mulawa1(Posted 2008) [#1]
I'm struggling to find a way to successfully have a Fullscreen display across a variety of laptops and desktop crts (all Windows at the moment - not ready to go Mac yet!) without screen flicker or tearing. I've read and re-read all the posts here and have learnt a lot!

But ...

The main thing I've learnt is that BlitzMax cannot tell you the monitor refresh rate so if you want to match the current desktop setting you'll have to calculate it yourself.

So my question is ... why does this code not work? I find it returns a wide variety of values although most are near the refresh rate.

<update>I've just tried this on an old laptop set to 60Hz but my program reports 30!</update>

Strict
Graphics 800,600
Repeat
Cls
DrawText refresh_rate(),10,10
Flip
Delay 1000
Until KeyHit(KEY_ESCAPE)
End

Function refresh_rate()
	Local ms,fps
	Flip(1)
	ms=MilliSecs()
	Flip(1)
	fps=1000/(MilliSecs()-ms)
	Return fps
End Function


Peter


Yan(Posted 2008) [#2]
Strict

?Win32
	Import Pub.Win32
	
	Extern "Win32"
		Function ReleaseDC(hWnd, hdc)
	End Extern
	
	Local hWnd = GetDesktopWindow()
	Local hdc = GetDC(hWnd)
	If hdc = Null Then End
	
	Print
	Print "Desktop Refresh Rate = " + GetDeviceCaps(hdc, VREFRESH)
	
	ReleaseDC(hWnd, hdc)
?

End



sswift(Posted 2008) [#3]
Using millisecs will never give you the true refresh rate for many many reasons. But if you want a few, here they are:

A) Your system is multitasking so you can never be sure the same line of code will execute in the same amount of time.

B) The refresh rate rarely will divide evenly into 1000 milliseconds. For example, at 60hz, the number of milliseconds per frame is 16.6666~.

C) Just because the screen refresh rate is 60hz doesn't mean it draws exactly 60 times a second every time. Your monitor isn't run by an atomic clock. :-)

In short, there's a lot of little time differences and timer accuracy issues which mean you'll never be able to read the HZ using the millisecond timer.

Though if you averaged it over a long enough period, I suppose you could get close. But you'll probably still end up with like 59.9999hz or something.


Czar Flavius(Posted 2008) [#4]
Tearing is caused by VSync, you can change this by using Flip 1 or Flip 0. Although the refresh rate is involved in whether the screen will tear or not, tearing can happen on any refresh rate, whether it is 60hz or 85hz.

Full screen programs will usually use whatever the desktop refresh rate last was for that mode. For example, if your program is 800x600 32-bit colour, set Windows desktop to that exact resolution. Now change the refresh rate to a desired level, and change the desktop back to your normal resolution. I THINK all fullscreen programs (that don't set the rate themselves) will use that refresh rate from now on for that exact mode.

A more complicated or perhaps better solution is to simply ask your user what he wants. Use the command to find you the list of supported resolutions and refresh rates, and ask the user to pick. Then if he wants to use 75hz he can, 60hz he can etc.


Otus(Posted 2008) [#5]
If you use GraphicsModes, you should get a mode with a good refresh rate.


mulawa1(Posted 2008) [#6]
Thank you all for taking the time to reply.

Yan, that code certainly delivered the answer - thank you!

sswift, I appreciate all the points you raise but that hardly explains the old laptop that consistently said "30" for "60" !

Sure I can use GraphicsModes - I came up with the idea of using the highest refresh rate for the resolution I wanted but the catch is it is the adapter reporting here and on one laptop the monitor wasn't up to the refresh rate and tearing resulted.

On the other hand if I use the default 60 as many have suggested elsewhere I get flickering on the crt that normally uses 75.

Allowing the user to choose is neat but my work is being used for disabled folk and for folk in care facilities.

Once again ... many thanks ... I'll try Yan's approach and worry about the Mac when I start working in that environment.

I'll add to this thread if I encounter any further issues.

Peter


ImaginaryHuman(Posted 2008) [#7]
There is a small module by dbug `desktopext` which provides cross-platform access to the desktop's dimensions, client area, bit depth, hz rate, etc.


Czar Flavius(Posted 2008) [#8]
Your plan assumes that the desktop refresh rate of the computers is already set up to an appriopriate level. Who ensures that?

I'm assuming someone that at least knows what he is doing will install your program on the computers. The setup program should ask what default rate to use and store it in a file.

As for tearing, did you try flip 1 and flip 0? I can't remember which is which but I think one forces VSync which reduces tearing.


Taron(Posted 2008) [#9]
Ah, how bizarre, I just ran into that for the first time myself. My previous compiles somehow never showed that kind of trouble.

It appears as though there's some sort of backbuffer trouble. It's very strange, since openGL and directX act as if they have specific modes that crisscross allow or deny backbuffers. (at least by the looks of it?!). More fascinating to me is the idea that I wasn't running into that earlier! I'm compiling with the SVN, if that could make any difference, but it might be that I wasn't using full res earlier?!?

However, I can claim that I've tried a lot of things and still can't come to a conclusion. Flip 0 ignornes the vblank, but ignoring it or not, that's not the problem as far as I can tell. Some laptops don't like flip 1 with openGL either, still ignoring the vblank.

Anyway... I wasn't helping, I know! :oP


mulawa1(Posted 2008) [#10]
IH - thanks for the cross platform heads up - will check that out

CF - my "plan" is a suite of programs - I want each to be standalone and capable of setting the res itself - I know I could use ini files but in the environment in which I'm working that's not the best approach.

If the desktop hertz is wrong already then all programs will be flickering and either this doesn't bother the user or someone will fix it!

I spent a lot of time experimenting with the flip flag - I felt it was being ignored on at least one old machine.

I'm very happy with Yan's code and have implemented it with complete success so I'm one happy camper at the moment.

Peter

P.S. Taron - sorry to hear that you're moving into the area I was in only yesterday!


MGE(Posted 2008) [#11]
Bottom line after lengthy research, etc, etc, yada, yada, yada..

Use Flip(1) all the time, and get used to it. This forces vsync which every game should do. Regardless if your game runs at 15fps or 75fps. The only reason to use Flip(0) is to test how fast your main loop is capable of.

Other Flip() parameters seem to be there to provide support for jurassic coders who want to code their game at 60fps on any monitor hz, and not have to use delta, tweening, etc. Avoid this line of thinking.

>> If your game runs faster then monitor refresh with Flip(1) then your GPU driver settings are set to ignore vsync.

>> If your GPU settings ARE set to vsync, and you use Flip(1) and still get tearing or high frame rates, then reinstall your drivers, something is broke. I've had peeps from day 1, play games with tearing and think it's "normal" then when they see the same games on their system with proper drivers installed and VSYNC is working, it's like night and day. ;)

Graphics(width,height,mode,hz)

>> Default for "hz" is 60, so if you ignore this parameter, in full screen mode BlitzMax will attempt to setup a 60hz refresh rate.

>> If you pass a parameter that is not supported by the driver, the driver will setup a default hz.

I would recommend passing 0 and letting the internals of the system setup a hz for you. Then in your game, use fixed logic, tweening, delta timing, etc, for your logic/render needs. ;)


ImaginaryHuman(Posted 2008) [#12]
I pretty much agree with MGE. A lot of people are using Flip -1 thinking that it will provide tear-free flipping, but it doesn't, especially I notieced it on my Mac, I had to change various examples to Flip 1 in order to properly sync with the vertical blank. I would recommend using Flip 1 all the time unless you want maximum/variable framerate in which case use Flip 0. You should be using some kind of dynamic logic timing (fixed rate, delta etc) regardless because the hardware may not be able to keep up with the amount of work you're asking it to do. On a lower end/mid-range machine, if there is too much work to do the framerate will drop even if it's vsync'd and then you have to deal with logic slowing down.


Taron(Posted 2009) [#13]
With my games I'm using Flip 1 for a while now, which is fantastic, particularely under directX, which shows some consistency across most gfxboards.
However, with my funny happy trees it has the wild problem that I would have to somehow alter the routines to execute the growing outside of the vsync loop, because they benefit greatly from faster machines, while the vsync would slow it down. No drama, naturally.

However, I can't yet confirm that the flip choice is responsible for the flickering, since even flip 1 flickers in the case of fullscreen on the laptop!

I had something extremely esotheric happening when I managed to have no flickers on the laptop, where it appeared like it was drawing empty colored boxes on the screen as opposed to the chosen images. I can't even begin to tell what might cause that?! Particularely because a windowed version nor the flickering fullscreen wouldn't show that.


ImaginaryHuman(Posted 2009) [#14]
It's possible that your driver/gfx card simply does not `report` the vertical blank properly/at all. Not all hardware supports that.


Grey Alien(Posted 2009) [#15]
I agree with MGE, I mean I practically set the standard (after a ton of research couple of years back) ;-p They key is Flip 1 AND some decent game timing so if Vysnc is forced off in the GPU drivers, your game still runs at a normal speed.


Yan(Posted 2009) [#16]
Yeah, that 'extensive research' must have really taken it out of you...

http://www.blitzbasic.com/Community/posts.php?topic=57862#643780


;op


Yan(Posted 2009) [#17]
oops


Grey Alien(Posted 2009) [#18]
haha, I did spend a long time reading up about it and running tests and posting test apps online, and then refining my timing method for MBax etc, so it sure feels like a ton of research to me :-)


MGE(Posted 2009) [#19]
Yo.. if you research anything with "frame rate" , "hz" , "fixed logic" , etc, etc, chance are GA's going to show up. So yah...I would say he's put in the hours. :)


Taron(Posted 2009) [#20]
@ ImaginaryHuman
Yep, but only for openGL, funny enough. DirectX reports proper Vblank normally.

@ the rest
I would testify to the flip 1 solution, particularely with using directX. It's very reliable and produces beautifully smooth performance. As far as I can tell, I didn't even have to bother with anything else, especially no delta timing mess. I might have been lucky with my last game, but it feels fine on either machine (8core and laptop). Only the above mentioned remains a problem (openGL troubles on mobiles).


Grey Alien(Posted 2009) [#21]
Actually I was just making a silly comment for fun so don't wanna make a big deal of it :)


Taron(Posted 2009) [#22]
I had to look for your comment to get what you're saying there, hehe, but I actually mean it in regards to flip 1 and successfully being lazy. I have no idea what happens when a system has vsync turned off, but it led to my first successful smooth running game. (running maxgui)

I'd still like to know, if anyone had ever run into the wacky phenomenon, where either pixmaps don't seem to be generated, or images somehow can't get their content on the screen. (I should best show it, I know...)

And, naturally, the backbuffer/flicker weirdness in fullscreen modes. Does anyone know what this is or could be? (especially under directX (7))

ONE more thing... drawpixmap and grabimage... I found that with openGL and fullscreen a drawn pixmap may not be grabbed as image, but had to be drawn as image( loadimage...drawimage), while the circumstances are horribly ambiguous. If I started off drawing a pixmap to then go into the loop and grab image, it wouldn't get it, while during the loops, miraculously it will. Anything funky with memory dealings? There may well be stuff I havn't understood yet in regards to where an image ends up in memory and where it gets taken from again or how it ends up on the gfx memory and where grabimage actually takes it from?

Questions over questions...


MGE(Posted 2009) [#23]
I remember someone posting problems with grabimage in OGL. A search of the forum might help. Also "As far as I can tell, I didn't even have to bother with anything else, especially no delta timing mess. " well...that works ok when your game is running on capable hardware, but if running on lower end spec, or when your pc system has quirks, your game would run very choppy, have slow downs, etc, etc. And then if the system has vsync off, well your frame rate would be all over the place. ;) I've been running some recent ideas on a brand new Vaio pc with a nice Nvidia card, window games are choppy as hell, even my low end intel runs games better in window mode.


Grey Alien(Posted 2009) [#24]
@Taron: Maybe you are simply failing to Cls and Flip each frame? Or yeah GrabPixmap doesn't work in OpenGL the same as for DirectX, I posted that on the bug forum a few months back but it has not been fixed. Guess it's low priority...


Derron(Posted 2009) [#25]


I'd still like to know, if anyone had ever run into the wacky phenomenon, where either pixmaps don't seem to be generated, or images somehow can't get their content on the screen. (I should best show it, I know...)


checked variables against NULL ? Or did you mean "draws nothing" - the "can't get their content on the screen" is a bit hm undefined.



And, naturally, the backbuffer/flicker weirdness in fullscreen modes.


Thought there is no real backbuffer-system in Bmax, only the one and only surface you are working with. So what do you mean with "flicker" - tearing? black-screens?...


Questions over questions...


questions upon questions...
no word by word translation from German to English please ;D


bye MB


Taron(Posted 2009) [#26]
It draws the box of the image in the chosen color with the chosen alpha, but non of the pixel values it should contain.

Yes there is a backbuffer system in Bmax, in fact that's the most commonly used ( flip, flipping the buffers. You always draw on the backbuffer and then flip it to the front! How far that's not a "real" backbuffer system I can't tell!)

Thanks for your lecture on the english language. Even after 10 years in L.A. I screw up some phrazes here and there. Try telling someone not to paint the devil on the wall! ;)


ImaginaryHuman(Posted 2009) [#27]
If you are finding that grabpixmap doesn't work in OpenGL, try calling glReadPixels yourself to download a rectangular area of pixels and store it in a pre-created pixmap.


MGE(Posted 2009) [#28]
"Yes there is a backbuffer system in Bmax, in fact that's the most commonly used ( flip, flipping the buffers. You always draw on the backbuffer and then flip it to the front! How far that's not a "real" backbuffer system I can't tell!)"

Correct. :)


Derron(Posted 2009) [#29]
But not like in the old days with double buffering or even triple buffering. you only can draw on one buffer at one time (ok, RTT is something very similar but its not included in a normal BMax-installation).

short: there is no SetBuffer (or SetTarget).



Garbage-Grabbing: Try using the method ImaginaryHuman suggests or give GrabImage a chance and grab your pixmap from there (this way it works for me even in OGL).



bye MB


Yan(Posted 2009) [#30]
Actually I was just making a silly comment for fun...
As was I. :o)

Still, looking on the bright side. It seems you've pulled. ;o)


Yo.. if you research anything with "frame rate" , "hz" , "fixed logic" , etc, etc, chance are GA's going to show up.
Yeah, I know. I was there. ;o)

I think GA is well used to my light hearted, if oft-sarcastic, leg pulling by now. :o)


Taron(Posted 2009) [#31]
Um, I'm using grabimage and then past the img.pixmap[0] into my pixmap! I noticed that grabpixmap didn't work very early on. Guess I forgot to mention that.

However, it's not the grabimage that really appears to fail. It's literally the drawimage of the images that goes wrong somehow...

I also did run into a few weird things with the image.pixmap[0] option. It also seems that creating an image doesn't allocate a pixmap until something is loaded into it, is that correct?


Grey Alien(Posted 2009) [#32]
I think GA is well used to my light hearted, if oft-sarcastic, leg pulling by now. :o)
so much so my leg is a little loose.

paint the devil on the wall
Heard that in a Megadeth song...


Defoc8(Posted 2009) [#33]
As far as i know flip(1) is simply a request to vsync - driver options
can override this + if you dont specify a hz value for
refresh you get a default/safe value?... If a user has disabled vsync in
there driver options..you may have trouble detecting this - i dont think
there are any bmax system commands to test for this?...


Derron(Posted 2009) [#34]
Taron - did you lockImage your Timage before working on it or its childelements (pixmaps)?

Maybe that helps.


bye MB


Taron(Posted 2009) [#35]
Hmmm, nope, I didn't lock them, but I also don't have any troubles on my machine with them. Could it be that this effects only certain setups?

I've started to use Loadimage rather than lock and paste in order to get my pixmaps into the timages. Seems to work fine on my machine, but then I don't know if that could act differently on others?! (sorry for repeating myself there.)

I'll have a check for sure! Thanks!


Tachyon(Posted 2009) [#36]
Sorry for digging up an old thread...

MGE said:
Use Flip(1) all the time, and get used to it.

When I used Flip(1) one of my CPUs runs at nearly 100% under Vista.

If I use Flip(-1), its at a much more respectable 4-6%.

I don't notice a difference between the two otherwise. Should I still use Flip(1)?


ImaginaryHuman(Posted 2009) [#37]
Flip 1 has to sit in a loop waiting for a vertical blank event to occur, using CPU time. You might be better off using flip 1 in combination with a delay - ie at the start of your frame loop take note of the millisecs(), then when you are done rendering and are about to flip, check how many milliseconds have passed. If there is a significant enough amount of milliseconds left before the frame is likely to flip (16.6ms are available for a 60fps framerate) then do a Delay to let the o/s use up the remaining time - give yourself some room to make sure the flip gets fired ahead of time, but not too early, then do your flip. Cus it sounds to me that if your Flip -1 loop is only using 5% cpu time then you aren't doing a whole lot of processing in your loop and could be giving all that time back to the o/s.


BlitzSupport(Posted 2009) [#38]
I didn't see this thread until it got bumped, but thought I'd rain on the parade a little bit regarding GetDeviceCaps -- from the MSDN docs:

VREFRESH - Windows NT only


I never found a way to get the refresh rate 'officially' from Windows 9x last time I tried.

Just depends whether you care about your app working on 98 or not, though... Max doesn't officially support anything older.


mulawa1(Posted 2009) [#39]
Thanks for that James - may explain why my new stuff failed on a Win98 box recently :(

Peter


mulawa1(Posted 2009) [#40]
There is a small module by dbug `desktopext` which provides cross-platform access to the desktop's dimensions, client area, bit depth, hz rate, etc.


Well I've bitten the bullet and finally bought an eMac!

So now I desperately need a way to retain the refresh rate on a Mac.

@IH Can you tell me how to follow up on your suggestion?

@everyone ... or is there now a standard solution to this problem?

Peter


mulawa1(Posted 2009) [#41]
Found it myself - now to try using a 3rd party module for the first time.

http://www.chaos-interactive.de/en/desktopextension/

Peter


mulawa1(Posted 2009) [#42]
Need some help! I downloaded the above zip file which contains

desktopext.bmx
macscreen.c

I can see how it works - it even uses the "Import pub.win32" approach for Windows which I am already using.

BUT I can't see how to make use of what I've downloaded to enable me to find the refresh rate in OS X.

Peter


d-bug(Posted 2009) [#43]
You have to copy the complete folder structure to your BlitzMaxPath/mod folder. Then rebuild modules wich means you must have installed XCode on MacOS machines and MinGW on Windows machines first. I recommend to rebuild documentation too, to get the docs for desktopext. If all is going well, add the following code at the beginning of your main-code file:
Import chaos.desktopext

After that you should be able to access the refresh rate of your desktop with the function DesktopHertz ()


mulawa1(Posted 2009) [#44]
So easy when you know how!

Worked perfectly on my eMac.

I was surprised when it came up with 89 Hertz but when I checked that is indeed what it is set to.

Many thanks! You have saved the eyesight of at least one of my Mac players!

Keep up the good work!

Peter


mulawa1(Posted 2009) [#45]
Hmmm ... I'm beginning to think it's all too hard!

Here's what I'm trying to do - my game starts in 800x600 but a user can switch to 1024x768 on the fly - both fullscreen.

Main problem is to get a suitable refresh rate so there is no flicker.

My idea of getting the user's refresh rate and sticking to it works fine on all the boxes I've tried it on. But with my eMac the refresh rate seems tied to the resolution. eg my usual setting is 1024,768,32,89 but if I then try 800,600,32,89 it's not acceptable - it wants 800,600,32,112

So back to the drawing board and I try checking what combinations are available and choose the greatest refresh rate. Works fine on the eMac but then falls over on one of my Windows boxes because the adapter offers 800,600,32,120 but the old monitor can't handle 120hz!

I know there have been many other posts on this issue so I'm looking for the best compromise. My problem is that I only have a small set of test boxes.

I should also mention that most of my players are not very computer literate.

Peter


mulawa1(Posted 2009) [#46]
I'm tempted to:

* Use the "keep the user's refresh rate" approach on Windows boxes.

* Use the "max acceptable refresh rate" approach on Mac boxes.

Any comments on this idea?

Peter


_JIM(Posted 2009) [#47]
Sounds like a good idea. You choose what's best for each platform.


ImaginaryHuman(Posted 2009) [#48]
Each screen `mode` has its own set of supported resolutions. It's based on what the hardware can display/output. So if your graphics card/monitor cannot handle a 1024 x 768 mode at 89Hz it simple won't allow you to open a screen with those settings. It'll use something `close`, like the 112.

Using Flip 1 the refresh will always be smooth, but it'll also always be synchronized to the display refresh, ie 89 or 112.


Czar Flavius(Posted 2009) [#49]
Why don't you select the greatest refresh rate below a certain threshold? The human eye can't really distinguish changes of refresh rate after about 80Hz, so there is little point in using 120Hz, just because it's available.

The monitor should tell the card what refresh rates it supports, so it's a bit worrying it selects one too high, though if it's an old monitor I guess it might not plug-and-play well.

I think you should just buy an LCD ;)


mulawa1(Posted 2009) [#50]
Thanks for the thoughts.

@IH: I'm religiously using flip(1)

@Czar: Are you suggesting I buy an LCD for each of my many players? :o)

I was toying with the threshold idea - catch is that on my eMac it seems to insist on 112 if I choose 800x600.

Another idea I'm playing with is if all else fails used windowed mode - here of course there are no refresh rate issues. My idea is that if confronted by a blank screen or a poor display the user can press the W key. I will then offer this permanently on the Options screen so they don't have to do this each time.

Peter


xlsior(Posted 2009) [#51]
It's a double-edged sword: if you have a monitor or LCD that doesn't play nice, then the computer may list screenmodes that don't really work.

Old LCD's may not support anything over 60Hz (and most new ones still won't do anything over 75Hz), while a CRT can drive you absolutely nuts at 60Hz.

the desktop resolution and refreshrate is pretty much the only combination that's guaranteed to work, with the exception that there may not be enough video memory on a low-end machine if the desktop runs at a high resolution/bitrate. :-?

No matter what you pick, there's always a chance of failure...


mulawa1(Posted 2009) [#52]
Ok ... here's my consolidation of all I've learnt.

This test program opens in 800x600 fullscreen if it can.
It displays what Blitz thinks are the settings with black text on a white screen.

"F" will toggle between 800x600 and 1024x768
"W" will toggle Windowed mode ON/OFF

Here are the exe's - maybe you could try it for me on your boxes?

Windows
http://mulawa.net/special/wip/monitor_test.exe
Mac OS X
http://mulawa.net/special/wip/monitor_test.dmg

Strict
?Win32
	Import Pub.Win32
	Extern "Win32"
		Function ReleaseDC(hWnd, hdc)
	End Extern
	Global grefresh_rate=0
	Local hWnd = GetDesktopWindow()
	Local hdc = GetDC(hWnd)
	If hdc <> Null Then grefresh_rate=GetDeviceCaps(hdc, VREFRESH)
	ReleaseDC(hWnd, hdc)
?

Global gwindow=False
If graphics_set(800,600)=False Then Notify("Unable to set graphics mode 800x600");End
Global gbig_screen=False

Repeat
	display()
	Flip(1)
	WaitEvent()
	Local ed=EventData()
	Select EventID()
		Case EVENT_APPTERMINATE;End '****
		Case EVENT_KEYDOWN
			Select ed
				Case KEY_ESCAPE;End
				Case KEY_F;gbig_screen=Not gbig_screen;screen_set()
				Case KEY_W;gwindow=Not gwindow;screen_set()
			End Select
	End Select
Forever
End 

?MacOS
' use the maximum acceptable refresh rate
Function graphics_set(w,h)
	Local mode:TGraphicsMode,fmax=0,d
	If gwindow
		Graphics(w,h);Return True'****
	Else
		d=32 ' try depth 32 first
		For mode:TGraphicsMode=EachIn GraphicsModes()
			If mode.width=w And mode.height=h And mode.depth=d
				If mode.hertz>fmax Then fmax=mode.hertz
			End If
		Next
		If fmax=0
			' no luck so try depth 16
			d=16
			For mode:TGraphicsMode=EachIn GraphicsModes()
				If mode.width=w And mode.height=h And mode.depth=d
					If mode.hertz>fmax Then fmax=mode.hertz
				End If
			Next
		End If
		If fmax=0
			Return False'****
		Else
			Graphics(w,h,d,fmax);Return True'****
		End If
	End If
End Function
?Win32
' use the same refresh rate as the desktop if available
Function graphics_set(w,h)
	Local d,f,mode:TGraphicsMode
	If gwindow
		Graphics(w,h);Return True'****
	Else
		If grefresh_rate ' current refresh rate retrieved at start of program
			For mode:TGraphicsMode=EachIn GraphicsModes()
				d=mode.depth;f=mode.hertz
				If mode.width=w And mode.height=h And d=32 And f=grefresh_rate ' try 32 first
					Graphics w,h,d,f; Return True '****
				End If
			Next
			For mode:TGraphicsMode=EachIn GraphicsModes()
				d=mode.depth;f=mode.hertz
				If mode.width=w And mode.height=h  And d=16 And f=grefresh_rate ' now try 16
					Graphics w,h,d,f; Return True '****
				End If
			Next
		Else ' default to depth 16 and 60 Hz
			For mode:TGraphicsMode=EachIn GraphicsModes()
				d=mode.depth
				If mode.width=w And mode.height=h  And d=16
					Graphics w,h,d; Return True '****
				End If
			Next
		End If	
		Return False '****
	End If
End Function
?
	
Function display()
	Local s$
	SetClsColor 255,255,255;Cls;SetColor 0,0,0
	s$="width:"+GraphicsWidth()+" height:"+GraphicsHeight()
	s$=s$+" depth:"+GraphicsDepth()+" freq:"+GraphicsHertz()
	DrawText s$,10,10
End Function

Function screen_set()
	If gbig_screen
		graphics_set(1024,768)
	Else
		graphics_set(800,600)
	End If
End Function



xlsior(Posted 2009) [#53]
OK ... here's my consolidation of all I've learnt.


One other thing to take into consideration: there won't be many (yet), but you're bound to run into *some* computers that won't support either one of these resolutions... you may want to look at the list of available video modes as returned by blitz, and initiate a screen in the next size up as a fallback. (e.g. 1366x768)


mulawa1(Posted 2009) [#54]
Quite true Marc - I've already encountered that and it sometimes ends up with distortion.

For the moment I think the Windowed mode is the best fallback.

Peter


ImaginaryHuman(Posted 2009) [#55]
Choosing screen modes, resolutions, refresh rates and all that is all really tied into how you intend to update your game display - ie your `timing` solution.

If there only ever was one widely supported resolution with a given specific refresh rate, let's say like VGA 640x480 at 60hz (I think that's VGA right?) ... and everyone was using that mode, and everyone's computers and monitors supported it, you could just say okay, I know how fast the refresh will be and at what resolution, so that's what I will design my game around. Every time you Flip 1, you know your game will be running at 60hz, provided it isn't using more than 100% of the computer's resources. However, those days are long gone for the pc. Perhaps it's still true of the game consoles or handhelds, where you have a small set of supported resolutions and refresh rates, so you can predict it pretty easy, but in the pc world anything goes.

That means that if you plan to make game software for mac/windows/linux, then you really should consider decoupling your game's logic rate from the graphics update rate. You should expect the graphics must be redrawn and flipped once every display cycle, so if the display is at 60hz you know you have to draw 60 graphics frames per second, and if it's 120, you gotta draw that many in the same amount of time. You have to make your logic dynamic and flexible based on how many `frames per second` must be drawn. So if you design for 60hz and the display happens to be 120, you know you gotta do 2.0 logic updates per frame. But you can't fix it at 2.0 cus you might get other resolutions/refreshes.

Then if there isn't enough processing power to churn out 1 graphic frame for every refresh cycle, you know frames will be dropped, and then you have to compensate with your timing code. These are common workarounds for todays multi-resolution multi-hz-rate displays.

When it comes to choosing modes for displays to open, I recommend you use Blitz's list of available modes. They should in most cases be supported by the monitor (right?). Note that sometimes the hz rate is returned as 0 - it is on my Mac, so sometimes you have to guess at a hz rate. Blitz automatically chooses a `close` mode for you.

What I do is if I want the mode to be close to something, I will go through the list and prioritize display characteristics in the order of width, height, depth and hz rate. I first try to find modes with a width that is at least as big as what I want, then out of those a suitable height, then finally depth and hz. You also could scrap all 16-bit modes first if you really want 32-bit only. This is about the best you can do. Either let the user choose the mode or try to find one that is close.


mulawa1(Posted 2009) [#56]
I appreciate what you're saying but most of it is not applicable to my games - for example my main project is my Jigsaw Engine - all we have to keep up with is how fast the user moves a piece across the screen - not a big ask! So my main concern remains - no tearing and no flicker - both of which seem to be well addressed by the code above.

Peter
http://mulawa.net


Czar Flavius(Posted 2009) [#57]
@Czar: Are you suggesting I buy an LCD for each of my many players? :o)
It's Christmas soon, so yes :D

Old LCD's may not support anything over 60Hz
Unless I'm mistaken (which is possible as this topic is a bit confusing for me) the big problem is screen flicker and tearing, the former of which is due to the way a CRT works. So it wouldn't matter if an LCD was at 60Hz or not for the purposes of screen flicker.


xlsior(Posted 2009) [#58]
I know -- but where it does matter, is that if you were to *force* an 85Hz refreshrate, you may end up with a 'signal out of range' error on older LCDs.


ImaginaryHuman(Posted 2009) [#59]
I don't know if you CAN `force` modes, Blitz seems to only let you set modes which it can find in its `graphicsmodes` list, and presumably may not list ones which are not supported per the o/s? I know on my Mac it will not list stretched modes, e.g. 1024x768 at a 16:10 aspect ratio. So there is definitely some filtering going on somewhere.


theHand(Posted 2009) [#60]
It doesn't seem like this can be completely resolved. I blame ATI (half-kidding).
Edit: removed the rest of the stuff I previously wrote, most was pretentious. :(
But, it's still a good idea to use GraphicsModeExists() (in a loop), especially if your game will allow the user to switch between different resolution / refresh rate combinations. d-bug had already done what I was talking about, but for those who want real control over display (unless d-bug will maintain desktopext), you'll most likely have to get your hands dirty with C.


mulawa1(Posted 2009) [#61]
I'm happy with my code above - it works on all my problem systems ok - but I'd be even happier if as many of you as possible would try it for me. :o)

Peter


theHand(Posted 2009) [#62]
Well, it is already done for you!
Wow, I feel stupid! Ha ha ha!
CountGraphicsModes()
Hee hee, looks like BlitzMax is not the only one that "suffers" from this...I smell proprietism (give me a better word for the state of being proprietary and I'll correct it)...

Also, mulawa, it reported correctly here. Good job.


MGE(Posted 2009) [#63]
Never EVER change the computer's monitor refresh rate. That is soooo old school. Now days by either tweening or delta timing, that's how you compensate for fluctuating refresh rates. tsk,tsk.


Czar Flavius(Posted 2009) [#64]
It's not (just) for timing, it's to reduce eye strain on CRTs.


Muttley(Posted 2009) [#65]
Ideally you really shouldn't tie your game to any specific resolution, use the projection matrix to ensure your game displays the same at any resolution.

When your game starts either start windowed, or start full-screen at the identical resolution, depth and frequency as the user's current desktop settings, and always (I repeat ALWAYS) let the user change the display settings to whatever they prefer.


ImaginaryHuman(Posted 2009) [#66]
I don't see why it's a problem to change the monitor refresh rate. so long as it is returned as a rate in the list of available modes, why not do it if the user wants to. I know on windows there used to be some crappy thing where changing resolutions/rates/modes would sometimes not revert back properly after your app finished - typical windows rubbish ;-D ... but it's certainly not an issue on the Mac, for example.