Blitz mods incompatibility issue with Full Screen

BlitzMax Forums/BlitzMax Programming/Blitz mods incompatibility issue with Full Screen

RobA(Posted 2011) [#1]
I have recently started interning for a company that uses BlitzMax/XML for their game. When I set up my environment, I downloaded the bare minimal amount of mods required to get the code to compile, and I pulled off the most up-to-date ones from the Internet.

When I did this and made a build, however, we suddenly lost full screen capability. In contrast, acquiring an old version of a programmer's mod folder (which has quite a bunch of random crap in it) allows me to make builds where full screen works perfectly.

In debugging this problem, I was able to find that the client reports an incorrect screen resolution that is off by a few pixels. In my case, I have a 1920 x 1080 and the height was off by 40 pixels, resulting in an incorrect report of 1920 x 1040. For another programmer who has the same issue with the latest mods, he was getting something like 1899 x 1279. Of course, these reports would cause issues because according to graphics.mod in brl.mod, the compatible parameters for a full screen are as follows (width, height, depth, hertz):

640 480 32 60
800 600 32 60
1024 768 32 60
1152 864 32 60
1280 720 32 60
1280 960 32 60
1280 1024 32 60
1366 768 32 60
1400 1050 32 60
1600 1024 32 60
640 480 16 60
800 600 16 60
1024 768 16 60
1152 864 16 60
1280 720 16 60
1280 960 16 60
1280 1024 16 60
1366 768 16 60
1400 1050 16 60
1600 1024 16 60
1920 1080 16 60
1920 1080 32 60

We think that somewhere along the line, something changed in the logic and there's a setting in the new, clean version of our mods that subtracts the size of the frame or something extra that it's not supposed to, causing the incorrect report. However, when I diff my brl.mod folder, graphics.mod folder, and graphics.bmx file, the only difference I can find is a space in between the ( and the first parameter of a function in the graphics.bmx file.

This single white space difference leads me to doubt that the brl.mod and graphics.mod are really the culprit here. In fact, when compiling the mods, if I only switch out the brl.mod folder, I still have the full screen broken issue. The biggest difference seems to be our blide.mod folders, where I only have fontmachine.mod, but he has a bunch of random crap and old folders, some renamed versions of other existing folders, which he inherited from the previous programmer who no longer works on this project.

I have spent a few days searching and messing around with this problem but I'm starting to run out of ideas on how to pinpoint this problem. Does anyone have a clue of what is going on or where I can track down this setting?

Thank you in advance.

[EDIT]: After much recompiling and testing, the maxgui.mod folder is the culprit folder. I will have to test its subfolders to pinpoint the problem.

Last edited 2011


GfK(Posted 2011) [#2]
Had the same problem. you can only go on what the system drivers are telling you. if you have the wrong gpu driver or a generic monitor driver then you'll get all sorts of weird resolutions reported that your system doesn't actually support.


RobA(Posted 2011) [#3]
The odd thing is that it works (on the same computer, with the same video card) if I just switch out my mods folder to the old, outdated one that the other programmer gave me. So, something in the mods folder is doing weird things to override my system drivers?


BlitzSupport(Posted 2011) [#4]
How are you retrieving the available resolutions? My only guess is that the code might somehow be taking the inner/client area of a full-screen-sized window as if it's the actual display size, before going into full-screen mode.


RobA(Posted 2011) [#5]
graphics.mod in brl.mod has a function called GraphicsModes() that allows me to loop through and print the available graphics modes.

I've been bashing my head against the computer compiling and recompiling individual mods and sub-mods to test what the culprit mod is. So far I've narrowed it down to being affected by the subfolders in maxgui.mod called ftlkmaxgui.mod, win32maxguiex.mod, and possibly maxgui.mod subfolder. When messing with some combination of those, the full screen capability breaks / unbreaks.

I am too tired and not quite thinking clearly now, so I cannot pinpoint the issue right now, but I've been getting inconsistent results between replacing those individual folders and I only know that with some combination of them (mainly ftlkmaxgui.mod and win32maxguiex.mod), the full screen breaks/unbreaks.

I notice that sometimes, when mixing the mod versions, the older mod does not compile. There is something called "Localize" that isn't recognized depending on which folder I'm using in combination. And my new mods folder has something called localization.mod, although the existence/lack of presence of that mod does not make or break the full screen.


Czar Flavius(Posted 2011) [#6]
Depending what you are doing, it's common for games to support only a fix set of the most common resolutions and/or give a custom resolution option for advanced users.


RobA(Posted 2011) [#7]
I'm looking at the code in the new win32maxguiex.bmx. Some lines interest me:

Method ClientHeight()
Local Rect[4]
If Super.ClientHeight() = height And SystemParametersInfoW( SPI_GETWORKAREA, 0, Int Byte Ptr Rect, 0 )
Return Rect[3]-Rect[1]
Else
Return Super.ClientHeight()
EndIf
EndMethod

Method ClientWidth()
Local Rect[4]
If Super.ClientWidth() = width And SystemParametersInfoW( SPI_GETWORKAREA, 0, Int Byte Ptr Rect, 0 )
Return Rect[2]-Rect[0]
Else
Return Super.ClientWidth()
EndIf
EndMethod

These methods are new in the newer version, they do not exist in the old version (which works).

I'm mostly interested in this call:

SystemParametersInfoW( SPI_GETWORKAREA, 0, Int Byte Ptr Rect, 0 )

What is this constant SPI_GETWORKAREA? Is it the thing that's defining the client height / width stuff? Is it modifying the returned display size in some weird way?

Maybe our code is using an outdated way of retrieving the client width/height that we want, which worked with the old mod, but not with the new one.

I'll note that I'm comparing version 0.73 (new) to version 0.64 (the one where full screen works).

Last edited 2011


Htbaa(Posted 2011) [#8]
You are looking at maxgui.mod, but is your project actually using maxgui? As in: Import maxgui.drivers? If not that MaxGUI can't be of any influence.


RobA(Posted 2011) [#9]
Yes, we are using maxgui.mod and importing maxgui.drivers.

Having learned the stuff that I have today while debugging, I'm 100% sure that the issue is incompatibilities between two versions of the mod. We got the project working a long time ago with the old version. We lose full screen with the latest mods. When using the ClientWidth() and ClientHeight() from MaxGUI, the old version returns the correct values, while the new version does not.

So, I believe something changed with the implementation of those functions and that either I need to change the way I retrieve the values or I need to apply some corrective code in our project in order to undo the offset caused by the new version of the mod.

Last edited 2011


RobA(Posted 2011) [#10]
I just found this...

SPI_GETWORKAREA
0x0030

Retrieves the size of the work area on the primary display monitor. The work area is the portion of the screen not obscured by the system taskbar or by application desktop toolbars. The pvParam parameter must point to a RECT structure that receives the coordinates of the work area, expressed in virtual screen coordinates.

To get the work area of a monitor other than the primary display monitor, call the GetMonitorInfo function.

And in the mod, inside winimports.bmx file, it has the value:
Const SPI_GETWORKAREA = 48

So the height is being changed because the toolbar is being subtracted from the height it sounds like...

So, does this mean I can use GetMonitorInfo to get the full size without subtracting toolbar? I must try this out now.

Last edited 2011


kfprimm(Posted 2011) [#11]
What does DesktopWidth/DesktopHeight return?

They should return the full resolution.

Also, I believe you should get the same result with GadgetWidth/GadgetHeight using Desktop(). Perhaps you are using ClientWidth/ClientHeight instead?

Oh, and the graphics modes are enumerated by whatever graphics driver is current (Look in BRL.DXGraphics and BRL.GLGraphics). BRL.Graphics is just a generic interface.

Last edited 2011


BlitzSupport(Posted 2011) [#12]
This shows the different results you should get -- ClientWidth is indeed the 'inner' area of the desktop minus any 'appbars' such as the Taskbar:


Import maxgui.drivers

Print ClientWidth (Desktop ())
Print ClientHeight (Desktop ())

Print ""

Print GadgetWidth (Desktop ())
Print GadgetHeight (Desktop ())


For me, that outputs:


1920
1034

1920
1080



However, my understanding is that Windows, behind the scenes, will resize the desktop to the actual display size while a full-screen app is open, eg. try this:

Import maxgui.drivers

Graphics 640, 480, 32

Print ClientWidth (Desktop ())
Print ClientHeight (Desktop ())

Print ""

Print GadgetWidth (Desktop ())
Print GadgetHeight (Desktop ())


... which gives me:


640
434

1920
1080



If I drag the Taskbar from the bottom of the screen to the left edge, I get:


566
480

1920
1080



So, I believe ClientWidth is returning the size that the desktop 'inner area' is currently set to, having been resized (by Windows) to fit into the current display resolution, while GadgetWidth is retrieving the user's configured desktop size (ie. the size it "should" be), which is normally restored on program end, Alt-Tab, etc. (That's why some programs will leave your desktop all messed up if they exit abruptly.)

If none of this explains what you're seeing, can you post a small runnable sample that shows the problem happening?

Last edited 2011


RobA(Posted 2011) [#13]
Ohhhh wow, you guys are right! Thank you so much. I was looking at the ClientWidth code and found that the returned Rectangle was being set by this call in the mod:

SystemParametersInfoW(SPI_GETWORKAREA, 0, Int Byte Ptr Rect, 0)

This was very discouraging because SPI_GETWORKAREA forces the value to be the area not including the toolbar, which skews the actual desktop size.

I did not realize that GadgetWidth() and GadgetHeight() could be used. I will switch over our ClientWidth/Height() calls to GadgetWidth/Height() calls and hopefully that will do it. I'm outputting the expected correct numbers that you guys are stating by using the Gadget instead of the Client.

I have just started working on this project, so I am very unfamiliar with Blitz mods and all the functions. You have been very helpful. Thank you!

[EDIT]: I switched over the calls and I can invoke full screen again :) Thank you...

[EDIT2]: I just found a comment in our code: ' ClientWidth/Height is used because GadgetWidth/Height returns the entire width of the desktop in dual screen setups.

I guess that's why we used ClientWidth/Height. But nowadays, that won't work because ClientWidth/Height subtract toolbars and such from the "correct" resolution. Is there a workaround to this problem or has that issue already been resolved and that comment out of date?

Maybe the Desktop().width / Desktop().height suggested above? Or is that the same as GadgetWidth/Height (Desktop())... Hmm.

Last edited 2011


BlitzSupport(Posted 2011) [#14]
Actually, I learned something myself, as I recently found I had to use BlitzMax's (non-MaxGUI) DesktopWidth/DesktopHeight before going into a graphics mode, and this explains why we shouldn't have to...

(In fact, I've just posted this in the hope that Mark might update it at some point!)


BlitzSupport(Posted 2011) [#15]

I can invoke full screen again :) Thank you...


Cool!


ClientWidth/Height is used because GadgetWidth/Height returns the entire width of the desktop in dual screen setups


I suspect that will be dependent on OS/driver settings, since dual screens on Windows can be set up to spread one desktop over both screens (what you have), duplicate the primary display on the secondary display (which would probably return the 'correct' first monitor's display width), etc.

What does this do on the dual-screen setup?

Extern "win32"
	
	Const SM_CXSCREEN:Int = 0
	Const SM_CYSCREEN:Int = 1
	
	Function GetSystemMetrics (index:Int)
	
End Extern

Print GetSystemMetrics (SM_CXSCREEN)
Print GetSystemMetrics (SM_CYSCREEN)


This 'should' work, as this page says it refers specifically to the primary display.


RobA(Posted 2011) [#16]
Thank you! I will need to figure out what I need to do there, because I do not have a dual screen and cannot physically test it myself. And submitting code blindly scares me, so I might need to get one of our artists (I bet they have dual screen) to help test. So it will be a bit before I can validate whether that works.

Just to clarify... am I correct in assuming that GadgetWidth(Desktop()) is interchangeable with Desktop().width, or is there a situational preference with using one or the other? I have tried both and they both seem to work, but I'm not aware of any subtleties or caveats associated with using either.

Last edited 2011


BlitzSupport(Posted 2011) [#17]
OK, the above won't do it, as it also uses the physical resolution, so is wrong in full-screen mode, ie. returning display size, not desktop size. Experimenting...


BlitzSupport(Posted 2011) [#18]
Still experimenting in the linked thread, but, as likely as it appears to anyone, including me, I'm almost certain you can't retrieve the (Windows) desktop resolution while running, short of storing it before changing the display mode, via Graphics, etc, as it appears to be updated on the fly according to the current display mode.

In short, just call DesktopWidth/Height at the start of your program, and assume you can't update this information while your program is running.

If anyone, anywhere, can prove otherwise, please do! I will be pleased rather than upset at being proven wrong!

Consider it a challenge if necessary...

Last edited 2011