Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Window resizing

This thread is locked; no one can reply to it. rss feed Print
Window resizing
Kevlar Games
Member #7,757
September 2006

Hi,

In my game, I have a main menu that is 800x600 and I want the game to play in 640x480. How do I change to that resolution?

Matthew Leverton
Supreme Loser
January 1999
avatar

Kevlar Games
Member #7,757
September 2006

I tried that and it works but the screen goes crazy. It starts flickering and gives me the standard "Program has encountered an error and needs to close" message.

Here's my code for resizing it:

set_color_depth(32);
set_gfx_mode(GFX_AUTODETECT_WINDOWED,640,480,0,0);
buffer = create_bitmap(640,480);

What am I doing wrong?

Matt Smith
Member #783
November 2000

This is a bug/limitation in Allegro unfortunately. It probably won't get fixed in the immediate future as we are short of good Windows devs. It's another remnant of Allegro originally being full-screen only (for DOS) so the window is actually created by the startup code, and then sized by set_gfx_mode(), so 2 calls to set_gfx_mode(*_WINDOWED,,,) causes problems.

You might have more luck switching between fullscreen modes, but this has similar problems on various other platforms.

You have 3 proper solutions

1) Stick to 1 resolution

2) Write a hybrid WinAPI/allegro prog that opens its own window and uses blit_to_hdc() to output allegro gfx

3) Help fix this part of Allegro, or put your whole project on hold until someone else does.

EDIT: I assumed you are using MSWindows, but GFX_AUTODETECT_WINDOWED could also mean X11 or MacOS. The same problem exists there really, so the solutions remain valid.


EDIT 2: It can help if you set_gfx_mode(GFX_TEXT,0,0,0,0); before setting the new size, as this gives the screen driver a chance to clean up the old settings and release the old screen BITMAP.

Kevlar Games
Member #7,757
September 2006

Thanks, I'll try that.

EDIT: Going to text mode first didn't work either. I'm not really good with the WinAPI, so I don't think that's an option. I could try making the main menu 640x480. That wouldn't be a problem.

Kris Asick
Member #1,424
July 2001

Quote:

EDIT 2: It can help if you set_gfx_mode(GFX_TEXT,0,0,0,0); before setting the new size, as this gives the screen driver a chance to clean up the old settings and release the old screen BITMAP.

This is what I do in my games. Works like a charm.

However, if you switch video modes while in Windows, there's two very important things you have to remember.

1: All contents of all bitmaps made with create_video_bitmap() will be lost. (The bitmap pointers and memory will still be intact, just nothing inside them.)

2: If you change the colour depth too, you have to reload all of your graphics so that they can be formatted to the current colour depth properly.

EDIT: Waitaminute... I just looked at my code and realized I'm not doing this, yet it works perfectly on every system I've tested on...

Download PixelShips Retro and try pushing F9 to change screen modes. If that works for you, let me know because I can post the code that's doing the change and you can see if perhaps there's a solution for you in there.

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

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

Kevlar Games
Member #7,757
September 2006

PixelShips resizes perfectly when I press F9.

P.S. Are you selling a lot of copies? I'm thinking of getting into the shareware business.

Kris Asick
Member #1,424
July 2001

Quote:

PixelShips resizes perfectly when I press F9.

Alrighty then. Here's the code I use to do the switching. I didn't post it at first because there's a TON of it:

1// This routine does the actual switch.
2int Switch_To_Graphics_Mode (int windowedMode, int width, int height)
3{
4 // First, attempt to initialize the requested mode. Return 0 on failure.
5 if (windowedMode != 0)
6 {
7 set_color_depth(8);
8 if (set_gfx_mode(GFX_AUTODETECT_WINDOWED,width,height,0,0) != 0) return 0;
9 }
10 else
11 {
12 set_color_depth(8);
13 if (set_gfx_mode(GFX_AUTODETECT_FULLSCREEN,width,height,0,0) != 0) return 0;
14 }
15 
16 // Next, clear the screen.
17 clear_bitmap(screen);
18 
19 screenx = width; screeny = height;
20 
21 if (windowedMode)
22 {
23 show_os_cursor(MOUSE_CURSOR_ARROW);
24 if (set_display_switch_mode(SWITCH_BACKGROUND))
25 {
26 if (set_display_switch_mode(SWITCH_AMNESIA))
27 {
28 set_display_switch_mode(SWITCH_NONE);
29 set_display_switch_callback(SWITCH_IN,SwitchIn_Restore);
30 }
31 else
32 {
33 set_display_switch_callback(SWITCH_IN,SwitchIn_Restore);
34 if (set_display_switch_callback(SWITCH_OUT,SwitchOut_Standby))
35 {
36 set_display_switch_mode(SWITCH_NONE);
37 set_display_switch_callback(SWITCH_IN,SwitchIn_Restore);
38 }
39 }
40 }
41 else
42 {
43 set_display_switch_callback(SWITCH_IN,SwitchIn_Restore);
44 if (set_display_switch_callback(SWITCH_OUT,SwitchOut_Standby))
45 {
46 set_display_switch_mode(SWITCH_NONE);
47 set_display_switch_callback(SWITCH_IN,SwitchIn_Restore);
48 }
49 }
50 }
51 else
52 {
53 if (set_display_switch_mode(SWITCH_BACKAMNESIA))
54 {
55 set_display_switch_mode(SWITCH_NONE);
56 set_display_switch_callback(SWITCH_IN,SwitchIn_Restore);
57 }
58 else
59 {
60 set_display_switch_callback(SWITCH_IN,SwitchIn_Restore);
61 if (set_display_switch_callback(SWITCH_OUT,SwitchOut_Standby))
62 {
63 set_display_switch_mode(SWITCH_NONE);
64 set_display_switch_callback(SWITCH_IN,SwitchIn_Restore);
65 }
66 }
67 }
68 
69 return 1;
70}
71 
72// This routine is called immediately after pressing F9.
73void FunctionMenu_CycleWindowed (void)
74{
75 // Here's how this process works:
76 // 1. Set a variable to indicate if the current mode is windowed or not.
77 // 2. Increase the windowed variable by 1.
78 // 3. Re-init the video mode.
79 // 4. If successful, return to game.
80 // 5. Check if the new value equals the stored value. If it does, quit with an error message.
81 // 6. If the new value is greater than 0, set to -1.
82 // 7. Return to step 2.
83 
84 int prev_windowed = 0;
85 int failure;
86 
87 if (!options.windowed) prev_windowed = 1;
88 
89 do {
90 options.windowed++;
91 failure = 0;
92 if (options.windowed)
93 {
94 if (!Switch_To_Graphics_Mode(options.windowed,320*options.windowed,240*options.windowed)) failure = 1;
95 }
96 else
97 {
98 if (!Switch_To_Graphics_Mode(options.windowed,320,240))
99 if (!Switch_To_Graphics_Mode(options.windowed,640,480)) failure = 1;
100 }
101 if (failure)
102 {
103 if (options.windowed == prev_windowed) CallErrorHandler(4);
104 if (options.windowed > 0) options.windowed = -1;
105 }
106 } while (failure);
107 
108 if (rwdata != NULL) set_palette((PALETTE&)rwdata[Default_Palette].dat);
109 Set_VSync_Value(options.vsync);
110}

F9 essentially cycles through a list of video modes in PixelShips Retro. The list is as follows:

  • FullScreen 320x240x8bpp

  • FullScreen 640x480x8bpp (Only if 320x240x8bpp fails.)

  • Windowed 320x240x8bpp

  • Windowed 640x480x8bpp

  • Windowed 960x720x8bpp

  • (As many more multiples of 320x240 that will fit within the current desktop res.)

If the list does one complete loop and is unable to reset the original mode before pressing F9, the game aborts, otherwise it settles on whatever comes next that doesn't fail.

Now, there is the fact going that I'm only using 8bpp, not 32, however, I think the problem may be related to my setting the display switch mode to allow the game to continue running in the background. I have to do this to properly cancel out the music on a switch, however, I've recently discovered that a realm of issues with Allegro are solved when you take it out of its default pausing mode and set it into a background mode. So you might want to try that first. (Just remember that the moment you make another call to set_gfx_mode(), all display switching settings are forgotten, including callbacks!)

Quote:

P.S. Are you selling a lot of copies? I'm thinking of getting into the shareware business.

That's not a fair question to ask someone. If my business is in the slums, answering as such would turn people away. If my business is booming, answering as such would seem like flagrant advertising.

All I can recommend if you want to get into shareware is to do your homework and to not expect to be an overnight success story. Shareware is ultimately 10% programming and 90% marketing. Going into it just to make a quick buck won't leave you with much. There are a lot of resources on the net for people who want to get started. Read them and obey them, because any moment when you say, "That's not how I want to do shareware," is another 20%-80% off your sales.

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

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

James Stanley
Member #7,275
May 2006
avatar

Try keeping it in 800x600 and stretch_blitting to the screen ;D. Might work, but will most probably look really nasty...

Kevlar Games
Member #7,757
September 2006

Quote:

Quote:

Quote:
P.S. Are you selling a lot of copies? I'm thinking of getting into the shareware business.

That's not a fair question to ask someone.

Yeah, sorry. I was just wondering, though. I just figured that an indie game other than a match-3 or Tetris clone would do really well.

I'll try your code and see if it works.

Thanks.

Go to: