Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Windows programming and changing resolutions

This thread is locked; no one can reply to it. rss feed Print
Windows programming and changing resolutions
Edgar Reynaldo
Member #8,592
May 2007
avatar

Hello everyone - hoping to find some advice / pointers to info on :

1. Does anyone know how/where I could get started programming with the Windows API so that I could write my own Windows Main function?

2. Been having problems changing graphics modes , specifically :
-Changing from fullscreen to windowed mode in this way;
from GFX_AUTODETECT_FULLSCREEN to GFX_AUTODETECT_WINDOWED and
from GFX_DIRECTX_ACCEL to GFX_DIRECTX_WIN.
-What happens is I get a window in the resolution size of my desktop and not in the resolution size I requested. It draws to the size requested but the rest of the window is filled with artifacts and smears when moved.
-Does anyone know how I can fix this?

-I also have problems changing to fullscreen after I have changed resolutions in windowed mode (which seems to work ok)

I have been programming with Allegro for a few months now and am using
WinXP with MingW in Code::Blocks

Thanks for you help.

Jakub Wasilewski
Member #3,653
June 2003
avatar

As for 2), please post some minimal code that exhibits the problems you described. It'll be much easier for us to help you this way.

Also, what version of Allegro are you using?

---------------------------
[ ChristmasHack! | My games ] :::: One CSS to style them all, One Javascript to script them, / One HTML to bring them all and in the browser bind them / In the Land of Fantasy where Standards mean something.

DanielH
Member #934
January 2001
avatar

1) Yes

Attached is a basic win32 project created from msvcnet.

Kris Asick
Member #1,424
July 2001

Someone else recently had similar problems. It might benefit you to read through this thread: http://www.allegro.cc/forums/thread/591194

As per writing a WinMain() instead of a regular main(), the book I learned to do that from was "Tricks of the Windows Game Programming Gurus", which is a 1000+ page book that covers many of the basics in detail without relying on libraries made by other people. (Like Allegro.)

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Edgar Reynaldo
Member #8,592
May 2007
avatar

Jakub -
Well , I was going to put up the code , but it looks really awful because I don't know how to put it in a scrollable window. Can anyone tell me how to do that first?

Nevermind , just had to push the help button.
http://www.allegro.cc/mockup.html
EDIT - code below

I am using Allegro 4.21

DanielH -
I checked out your attachment. I think I need to start somewhere a little more basic first that has function definitions and that tells me what I need to include.

Where do I find the headers and WIN32 API library? Does Microsoft offer the library and documentation? Will do a search through Microsoft and report back.

Kris -
Thanks for your suggestion, I will take a look at the book you recommended.

1 
2///
3const int scr_wid=640;
4const int scr_ht=480;
5const int scr_wid2=480;
6const int scr_ht2=360;
7int resolution_num = 0;
8int max_num_res = 2;
9int fullscreen = 0;
10const int preferred_colordepth = 32;
11double d_scrwid = static_cast<double>(scr_wid);
12double d_scrht = static_cast<double>(scr_ht);
13 
14 
15/// Mid program key check
16 
17 if ((key[KEY_ENTER_PAD]) && ( ((key[KEY_ALT]) || (key[KEY_ALTGR])) && (!((key[KEY_LCONTROL]) || (key[KEY_RCONTROL]))))) {
18 resolution_num++;
19 resolution_num = resolution_num % (max_num_res);
20 switch (resolution_num) {
21 case 0 :
22 if ((change_res(scr_wid , scr_ht , preferred_colordepth , fullscreen)) == 0) {
23 set_gfx_mode(GFX_TEXT , 0 , 0 , 0 , 0);
24 allegro_message(allegro_error);
25 goto MEMORY_DEALLOCATION;
26 } else {
27 d_scrwid = static_cast<double>(scr_wid);
28 d_scrht = static_cast<double>(scr_ht);
29 rest(250);
30 }
31 break;
32 case 1 :
33 if ((change_res(scr_wid2 , scr_ht2 , preferred_colordepth , fullscreen)) == 0) {
34 set_gfx_mode(GFX_TEXT , 0 , 0 , 0 , 0);
35 allegro_message(allegro_error);
36 goto MEMORY_DEALLOCATION;
37 } else {
38 d_scrwid = static_cast<double>(scr_wid2);
39 d_scrht = static_cast<double>(scr_ht2);
40 rest(250);
41 }
42 break;
43 }
44 }
45 
46 if ((key[KEY_ENTER_PAD]) && ( ((key[KEY_LCONTROL]) || (key[KEY_RCONTROL])) && (!((key[KEY_ALT]) || (key[KEY_ALTGR]))) )) {
47 fullscreen += 1;
48 fullscreen = fullscreen % 2;
49 
50 switch (resolution_num) {
51 case 0 :
52 if ((change_res(scr_wid , scr_ht , preferred_colordepth , fullscreen)) == 0) {
53 set_gfx_mode(GFX_TEXT , 0 , 0 , 0 , 0);
54 allegro_message(allegro_error);
55 goto MEMORY_DEALLOCATION;
56 } else {
57 d_scrwid = static_cast<double>(scr_wid);
58 d_scrht = static_cast<double>(scr_ht);
59 rest(250);
60 }
61 break;
62 case 1 :
63 if ((change_res(scr_wid2 , scr_ht2 , preferred_colordepth , fullscreen)) == 0) {
64 set_gfx_mode(GFX_TEXT , 0 , 0 , 0 , 0);
65 allegro_message(allegro_error);
66 goto MEMORY_DEALLOCATION;
67 } else {
68 d_scrwid = static_cast<double>(scr_wid2);
69 d_scrht = static_cast<double>(scr_ht2);
70 rest(250);
71 }
72 break;
73 }
74 }
75 
76 
77/// Here is my resolution changing function
78int change_res(int scr_w , int scr_h , int col_depth , int full_screen) {
79 int success = 0;
80 full_screen = full_screen % 2;
81 set_color_depth(col_depth);
82 if (full_screen == 0) {
83// set_gfx_mode(GFX_TEXT , 0 , 0 , 0 , 0);
84// if (set_gfx_mode(GFX_AUTODETECT_WINDOWED , scr_w , scr_h , scr_w , scr_h) == 0) {success = 1;}
85 if (set_gfx_mode(GFX_DIRECTX_WIN , scr_w , scr_h , scr_w , scr_h) == 0) {success = 1;}
86 }
87 if (full_screen == 1) {
88// if (set_gfx_mode(GFX_AUTODETECT_FULLSCREEN , scr_w , scr_h , scr_w , scr_h) == 0) {success = 1;}
89 if (set_gfx_mode(GFX_DIRECTX_ACCEL , scr_w , scr_h , scr_w , scr_h) == 0) {success = 1;}
90 }
91 return success;
92}

I will probably change from using constants for scr_wid and scr_ht to a small integer array so I can get rid of the switch statements ie ... (scr_wid[resolution_num]) and allow for more resolution choices (program can be processor intensive and I want it to work well for people with slower computers. Can you make values in an array const? If so how do you declare them? I will probably add error checking for the color resolution in case 32 doesn't work.

gnolam
Member #2,030
March 2002
avatar

Quote:

Well , I was going to put up the code , but it looks really awful because I don't know how to put it in a scrollable window. Can anyone tell me how to do that first?

Use code tags: [code][/code]

See the help icon above the reply box for more info.

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

Jakub Wasilewski
Member #3,653
June 2003
avatar

Try changing:

set_gfx_mode(WHATEVER, scr_w, scr_h, scr_w, scr_h);

to

set_gfx_mode(WHATEVER, scr_w, scr_h, 0, 0);

The 4th and 5th parameter have little to do with the actual resolution - they're the minimum required size of the so-called "virtual screen", and the support for that is kind of quirky nowadays (it's more of a remnant of Allegro DOS days). You can read more in the manual entry for set_gfx_mode.

---------------------------
[ ChristmasHack! | My games ] :::: One CSS to style them all, One Javascript to script them, / One HTML to bring them all and in the browser bind them / In the Land of Fantasy where Standards mean something.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Sorry Jakub - No luck setting v_w and v_h to 0 , I still have the same problem.
Funny thing is that If I change the resolution after changing my program from fullscreen to windowed mode ( to another resolution windowed mode ) then the window is properly drawn again (no artifacts or excess size). Maybe If I just set the resolution twice then it will work although that seems like cheating.

Kris Asick
Member #1,424
July 2001

Did you look over the contents of the thread I pointed you to? I think the key thing you should check is if setting the display switching mode immediately after setting a resolution at any time (both the first time and on each change thereafter) to SWITCH_BACKGROUND (windowed) or SWITCH_BACKAMNESIA (fullscreen) solves the problem. The person who was having crashes with changing resolutions, upon running my own game which had a nearly identical display switching method, didn't experience them, and that was the only real difference I could see that might matter.

Plus, you must set the display switching mode to a background mode if you plan on using Allegro with your own custom window, otherwise numerous things can go wrong. (Using your own WinMain entry point is fine. You only want to make a custom window if you want to add your own Windows event handling or if you need to override some of Allegro's built-in capabilities... and after swearing enough times at my computer I can tell you it's not easy...)

Regardless of what you do, leave the virtual x and y values at 0 in set_gfx_mode(). You're only supposed to set them if you want to set up a virtual screen, which is pointless to do in anything but DOS.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Marco Radaelli
Member #3,028
December 2002
avatar

Edgar Reynaldo said:

1. Does anyone know how/where I could get started programming with the Windows API so that I could write my own Windows Main function?

I f a book is what you're looking for, I found the Petzold very nice. Consider it talks about pure Win32 API programming, nothing about the newer technologies (Windows.Forms, WPF, ...).

Edgar Reynaldo
Member #8,592
May 2007
avatar

I found more information on the WIN32 API :
After sifting around at microsoft.com I found their Platform Software Development Kits which they were mailing out on CD for free(plus S&H).
Here's the relevant pages , hopefully the PSDK's can get me started.
Download details: Microsoft Windows SDK for Windows Vista
About halfway down this page there is a link to ordering legacy SDK's on CD's here http://www.qmedia.ca/launch/psdk.htm
I ordered one for Vista and one for Windows Server 2003(which should include from XP SP2 back to Windows 2000) had to read carefully.

Marco , will take a look at your book , thanks for the pointer.

Okay Kris , I've been working on implementing set_display_switch_mode and here's what I've come up with.

The call to set_display_switch_mode(switch_pause) works generally when changing from resolution to resolution , however when changing from fullscreen to windowed mode , switch_pause and switch_background failed and only switch_backamnesia worked
(switch_mode_success = -2 , changeres returned -2)

All five tests conducted using GFX_DIRECTX_ACCEL for fullscreen and
GFX_DIRECTX_WIN for windowed mode.
All five tests conducted using two different resolutions to change between
(640X480 and 480X320)

Test 1
Best results
Test conditions : This happened while using set_display_switch mode and using GFX_TEXT mode to display the value of switch_mode_success before using set_gfx_mode(graphics mode,,,,) I used allegro_message(outputstring) while in text mode to display value of switch_mode_success.

Switch_pause works when changing between resolutions in windowed mode.

Switch_pause fails and Switch_background fails when changing from fullscreen mode to windowed mode within same resolution.
However Switch_backamnesia works and there is no excess screen or screen contents.

Change_res function code (Used in Test 1)

1int change_res(int scr_w , int scr_h , int col_depth , int full_screen , BITMAP *scrn) {
2 
3 int x = 0;
4 char outputstring[200];
5 for (x = 0; x < 200 ; x++) {outputstring[x] = '\0';}
6 char numberstring[50];
7 for (x = 0; x < 50 ; x++) {numberstring[x] = '\0';}
8 
9 int switch_mode_success = 1;
10 int success = 0;
11 
12 if ((set_display_switch_mode(SWITCH_PAUSE)) == -1) {
13 switch_mode_success = -1;
14 if ((set_display_switch_mode(SWITCH_BACKGROUND)) == -1) {
15 switch_mode_success = -2;
16 if ((set_display_switch_mode(SWITCH_BACKAMNESIA)) == -1) {
17 switch_mode_success = -3;
18 }
19 }
20 }
21 strcpy(outputstring , "Switch_mode_success = ");
22 itoa(switch_mode_success , numberstring , 10);
23 strcat(outputstring , numberstring);
24 
25 set_gfx_mode(GFX_TEXT , 0 , 0 , 0 , 0);
26 allegro_message(outputstring);
27 
28 rest(1000);
29 
30 if (switch_mode_success == -3) {
31 return switch_mode_success;
32 }
33 
34 full_screen = full_screen % 2;
35
36 set_color_depth(col_depth);
37 if (full_screen == 0) {
38// set_gfx_mode(GFX_TEXT , 0 , 0 , 0 , 0);
39// if (set_gfx_mode(GFX_AUTODETECT_WINDOWED , scr_w , scr_h , scr_w , scr_h) == 0) {success = 1;}
40 if (set_gfx_mode(GFX_DIRECTX_WIN , scr_w , scr_h , 0 , 0) == 0) {success = 1;}
41 }
42 if (full_screen == 1) {
43// if (set_gfx_mode(GFX_AUTODETECT_FULLSCREEN , scr_w , scr_h , scr_w , scr_h) == 0) {success = 1;}
44 if (set_gfx_mode(GFX_DIRECTX_ACCEL , scr_w , scr_h , 0 , 0) == 0) {success = 1;}
45 }
46// return (success*switch_mode_success);
47 return success;
48}

Test 2
Test conditions : This test was conducted using set_display_switch mode and NOT calling set_gfx_mode(GFX_TEXT,,,,) before calling set_gfx_mode(graphics_mode,,,,).

At least one of the switching modes worked because my program would have deallocated memory and quit if it hadn't.

However , when changing from fullscreen mode to windowed mode in either res(640X480 or 480X320) the window was not the proper size (ie desktop resolution sized and not the called resolution with desktop screen artifacts.

Test 3
Test conditions : This test was conducted using set_gfx_mode(GFX_TEXT,,,,)
before calling set_gfx_mode(graphics_mode,,,,) and NOT using set_display_switch mode except for an initial call which was successful for set_display_switch_mode(switch_pause).

Changing between resolutions in windowed mode worked successfully but while changing from fullscreen to windowed about 1/4th of the time , it resulted in the improperly sized window (desktop sized resolution with desktop leftovers). The other 3/4ths of the time the window worked successfully.

Test 4
Worst Results
Test conditions : This test was conducted using just the calls to set_gfx_mode(graphics_mode,,,,) ie... without using set_display_switch_mode except for an initial call which resulted in success for switch_pause and without using set_gfx_mode(GFX_TEXT,,,,) either.

Changing between resolutions in windowed mode worked fine and changing between resolutions in fullscreen mode worked ok.

However , when changing from fullscreen to windowed mode in either resolution there was 100% failure to properly size the window(the window was in a desktop sized resolution drawing to the size set
(640X480 in a 1024X768 window or 480X320 in a 1024X768 window, both drawing to the upper left of the window) with leftovers from my desktop on the bottom and right and bottom right sides(original problem and original code).

Test 5
I tried Test 1 again this time without calling allegro_message(outputstring) and didn't work as well this time. About 50% failure rate for changing from fullscreen to windowed mode (desktop sized window with artifacts again).
Again , anytime I changed from a windowed mode to another windowed mode it worked fine and accepted switch_pause for the switching mode.
Also had some funny quirks this time when online and with task manager running minimized. The notification area icons for being online and processor usage from task manager would periodically flash on screen.

I tried Test 1 again this time with calling allegro_message(outputstring) to display switch_mode_success and this time didn't have any errors (when changing from fullscreen to windowed mode it worked fine).

So to sum up
Changing from a windowed mode to another mode worked and accepted switch_pause.

However when changing from any fullscreen mode to any other mode (another fullscreen res or a windowed res same size) switch_pause failed , switch_background failed , and then switch_backamnesia worked.

The only time changing from a fullscreen mode to a windowed mode worked all the time was using {
set_display_switch_mode( try switch_pause 1st , switch_background 2nd ,
switch_backamnesia 3rd) ,
calling set_gfx_mode(GFX_TEXT,,,,) before calling set_gfx_mode(Graphic_mode,,,,)
, and
calling allegro_message(outputstring) after setting GFX_TEXT mode and before
setting Graphic_mode.
}

So everythings working for now , will have to try using more resolutions to change between. I still don't understand why it does and does not work though.
Question 1
What does setting GFX_TEXT mode do that changing from fullscreen to windowed mode does not? And why does it only work some of the times?
Question 2
Why doesn't switch_pause or switch_background work when changing from fullscreen to windowed mode?
Question 3
Why would using allegro_message make any difference at all?

Derrrrrr. Confusion.
???:-/???

Kris Asick
Member #1,424
July 2001

A few things:

1. You need to set the display switch mode immediately after calling set_gfx_mode(). Calling it right before changing resolutions means it might not be properly set up by the time the switch occurs. (Not sure about this one actually, but considering the multi-threaded nature of Allegro, it couldn't hurt.)

2. In fullscreen, the only two valid switching modes are SWITCH_AMNESIA and SWITCH_BACKAMNESIA. In windowed, the only two valid switching modes are SWITCH_PAUSE and SWITCH_BACKGROUND.

3. When you run full-screen, set the switching to SWITCH_BACKAMNESIA. When you run windowed, set the switching to SWITCH_BACKGROUND. Make sure you set the switching mode after any call to set_gfx_mode(). This should prevent the problems you're having.

4. Use GFX_AUTODETECT_WINDOWED and GFX_AUTODETECT_FULLSCREEN for best results.

5. PLEASE look at the large chunk of code I posted in the thread I pointed you to. It will make things a lot easier for you by showing you the order in which you should be calling the functions. The link again is: http://www.allegro.cc/forums/thread/591194

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Edgar Reynaldo
Member #8,592
May 2007
avatar

Sorry Kris , but my program is picky.
I changed things around so that when my change_res function is called , it does this. (Failed)
1. Call set_gfx_mode(GFX_TEXT,0,0,0,0) first
2. Change to specified resolution and fullscreen/windowed mode.
I went back to using GFX_AUTODETECT_FULLSCREEN and GFX_AUTODETECT_WINDOWED modes.
3. Call set_display_switch_mode(switch_pause); for windowed modes and call set_display_switch_mode(switch_backamnesia); for full modes.
Got 100% failure to properly size the window.

Then as soon as I added
allegro_message(outputstring); right after set_gfx_mode(GFX_TEXT,0,0,0,0);
It all started working without fail.:-/???
(outputstring tells user which graphics mode is being attempted)

There is something really bizarre going on here.
I don't really mind telling the user what graphics mode they are switching into but this doesn't make any sense to me.

By the way, what parts of Allegro are multi-threaded? Keyboard and timer and mouse?

Kris Asick
Member #1,424
July 2001

With your code exactly as you described it, try removing the call to set_gfx_mode(GFX_TEXT,0,0,0,0). That might solve all your problems. And don't forget to also set the switching mode after your very first call to set_gfx_mode too, in case you're not using your resolution changing routine exclusively to set video modes.

As per the multi-threading, Allegro's extra threads aren't always present, but here they are:

Event Thread: Handles Windows messages and I/O, if you're not using a custom window.
Input Thread: Handles I/O, but only if you're using a custom window.
Timer Thread: Handles timers as soon as one is required by the user or by Allegro.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Edgar Reynaldo
Member #8,592
May 2007
avatar

I tried removing the call to set_gfx_mode(GFX_TEXT,0,0,0,0) which also takes out allegro_message(outputstring) which left me with this.

Note: Only change_res is called to change graphics modes.
So change_res is now doing this:
1. Call set_gfx_mode(selected mode , wid , ht , 0 , 0), if it fails return 0(which quits)
2. Call set_display_switch_mode(SWITCH_PAUSE) for windowed modes and
call set_display_switch_mode(SWITCH_BACKAMNESIA) for fullscreen modes.

Without adding back in set_gfx_mode(GFX_TEXT,0,0,0,0) and allegro_message(outputstring) my program just refuses to change from fullscreen to windowed mode without ending up in a desktop-sized resolution drawing to the top left corner with a bunch of desktop artifacts around it.

In any case my program is working correctly when changing between the two resolutions I am using and the two GFX_AUTODETECT modes. I am going to add in more resolutions now and see if it still works.

Question : Do the resolutions all have to be smaller than the size of the user's desktop?

Thanks for all your help Kris and all.

Kris Asick
Member #1,424
July 2001

Quote:

When you run windowed, set the switching to SWITCH_BACKGROUND.

Try that.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Go to: