Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Problem toggling between Window and Fullscreen

This thread is locked; no one can reply to it. rss feed Print
 1   2 
Problem toggling between Window and Fullscreen
roger levy
Member #2,513
July 2002

Forth code with equivalent psuedocode


: fs?   display al_get_display_flags ALLEGRO_FULLSCREEN_WINDOW and 0<> ;

: w/f
   display ALLEGRO_FULLSCREEN_WINDOW fs? not 
      al_toggle_display_flag 
         0= abort" could not switch to fullscreen"
   fs? 0= if 
      display ALLEGRO_WINDOWED 1 al_toggle_display_flag drop
   then
;

\ ------------

function isfullscreen () { 
   return ( al_get_display_flags(display) & ALLEGRO_FULLSCREEN_WINDOW) != 0 ); 
}

function switchWF() {
   al_toggle_display_flag( display, ALLEGRO_FULLSCREEN_WINDOW, ! isfullscreen() );
   if ( ! isfullscreen() ) {
      al_toggle_display_flag( display, ALLEGRO_WINDOWED, 1 );
   }
}



Switching from windowed to fullscreen in this manner works, but switching back from fullscreen to windowed does not.

I had difficulty taking a screenshot. Basically what happens is the screen goes black and the game displays at the size of the windowed mode in the bottom left corner. I don't see a window or the desktop.

Anyone else have this problem? Is it a bug? Is there something I'm doing wrong? A step I've left out?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

<code>code goes here...</code> tags work.

See al_toggle_display_flag. It says only ALLEGRO_FULLSCREEN_WINDOW and ALLEGRO_NOFRAME are allowed after display creation. So just toggle ALLEGRO_FULLSCREEN_WINDOW. I just tested it today on Vista and it worked for me.

For example, this code worked just now :

#SelectExpand
1 2#include <stdio.h> 3#include <stdlib.h> 4#include <allegro5/allegro.h> 5 6int main(int argc, char **argv) 7{ 8 ALLEGRO_DISPLAY *display = NULL; 9 10 if(!al_init()) 11 { 12 fprintf(stderr, "failed to initialize allegro!\n"); 13 return -1; 14 } 15 16 17 al_install_keyboard(); 18 19 //al_set_new_display_flags(ALLEGRO_FULLSCREEN); 20 al_set_new_display_option(ALLEGRO_COLOR_SIZE , 32 , ALLEGRO_REQUIRE); 21 const int SCREEN_WIDTH = 800; 22 const int SCREEN_HEIGHT = 600; 23 24 bool fullscreen = false; 25 if (fullscreen) { 26 al_set_new_display_flags(ALLEGRO_FULLSCREEN); 27 } 28 29 display = al_create_display(SCREEN_WIDTH , SCREEN_HEIGHT); 30 if(!display) 31 { 32 fprintf(stderr, "failed to create display!\n"); 33 return -1; 34 } 35 36 ALLEGRO_EVENT_QUEUE* queue = al_create_event_queue(); 37 if (!queue) {printf("failed to create queue\n");} 38 39 al_register_event_source(queue , al_get_keyboard_event_source()); 40 al_register_event_source(queue , al_get_display_event_source(display)); 41 42 bool quit = false; 43 do { 44 45 al_clear_to_color(al_map_rgb(0,0,0)); 46 al_flip_display(); 47 48 do { 49 ALLEGRO_EVENT ev; 50 al_wait_for_event(queue , &ev); 51 52 if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {quit = true;} 53 if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE)) {quit = true;} 54 if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == ALLEGRO_KEY_F)) { 55 fullscreen = !fullscreen; 56 al_toggle_display_flag(display , ALLEGRO_FULLSCREEN_WINDOW , fullscreen); 57 58 } 59 60 } while (!al_is_event_queue_empty(queue)); 61 } while(!quit); 62 return 0; 63}

roger levy
Member #2,513
July 2002

I took out the line with ALLEGRO_WINDOWED but it's the same as before.

The only difference to your code is that I start the game in windowed mode while your code starts in fullscreen. Does your code still work if you start in windowed?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I don't think you're toggling the actual flag. If you don't toggle the flag it will never change.

Edit
Perhaps I should restate - the semantics of al_toggle_display_flag are not to actually toggle the flag you passed in, but to set that flag to the value you passed to it.

Thomas Fjellstrom
Member #476
June 2000
avatar

IIRC ALLEGRO_FULLSCREEN_WINDOW is a modifier for ALLEGRO_WINDOWED. I don't think you want to mix ALLEGRO_FULLSCREEN and ALLEGRO_FULLSCREEN_WINDOW.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

roger levy
Member #2,513
July 2002

I am definitely using it the way you describe - passing in the state I want. I even made double-sure by using a variable that I toggle myself, just like your code. When I pass in a 0 it becomes a small display in the corner of a black screen, when it is !0 again it becomes fullscreen again.

edit: my bad, looking at your code again i see you set fullscreen to false so your program should be starting in windowed like mine. btw, I am using ALLEGRO_FULLSCREEN_WINDOW and ALLEGRO_WINDOWED only, never ALLEGRO_FULLSCREEN.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Well, think you can get a print screen? And you should post your specs - OS, compiler and version of Allegro.

Edit
@Tomasu
Oh yeah! Sorry, that was scraps from an earlier bit of code but it does the right thing even if it looks wrong

roger levy
Member #2,513
July 2002

I cannot take a screenshot. When running the game in fullscreen, CTRL+Printscreen takes a screenshot of a section of a different window for some reason.

It's pretty easy to imagine. Black screen. Game is displayed on bottom left corner, small.

OS: Windows 8, Allegro version 5.1.9

What compiler version do you need? What I used to compile Allegro or my Forth compiler? (Not sure how that would help you)

i made a simulation of how it looks, in mspaint. This is AFTER trying to toggle from fullscreen back to windowed. Fullscreen looks fine.

{"name":"sim.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/e\/aeaf2778e7e21895d1fb0d34a35e9ad1.png","w":1680,"h":1050,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/e\/aeaf2778e7e21895d1fb0d34a35e9ad1"}sim.png

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Neil Roy
Member #2,229
April 2002
avatar

I had a similar problem just yesterday. After creating functions that properly destroyed all video memory bitmaps and display, it then sets up a new display and reloads the bitmaps with no problem. I start my game in Windowed mode which is the default if you don't set anything. What happens is that if I switch to either of the two fullscreen modes (which worked fine) then go to switch back, I get the black screen with no window. Well, this was because I never set the windowed mode in the first place because it is the default. The solution is to simply set the mode to windowed mode from the get go, don't assume a default.

I simply added in the line al_set_new_display_flags(ALLEGRO_WINDOWED); so the default mode is set manually, then I switch one of the fullscreen modes if that is what is set up.

If you're like me you probably never bothered with al_set_new_display_flags(ALLEGRO_WINDOWED); because it is the default. Anyhow, that fixed it.

Edit: This is my function (with all the code that loads in bitmaps removed):
WIDTH = 800
HEIGHT = 600
setting.fullscreen = 0 for windowed, 1 for fullscreen window and 2 for fullscreen.
Bitmaps and fonts are normally loaded here as well, I have a separate function for destroying the display and bitmaps which I call when I want to reset the display before calling this.

#SelectExpand
1void init_display() 2{ 3 // Vsync 1 means force on, 2 means forced off. 4 if(setting.vsync) al_set_new_display_option(ALLEGRO_VSYNC, setting.vsync, ALLEGRO_SUGGEST); 5 6 if(setting.opengl) al_set_new_display_flags(ALLEGRO_OPENGL|ALLEGRO_WINDOWED); 7 else al_set_new_display_flags(ALLEGRO_WINDOWED); 8 9 if(setting.fullscreen == 1) { // Regular Fullscreen mode (0 = window) 10 if(setting.opengl) al_set_new_display_flags(ALLEGRO_FULLSCREEN | ALLEGRO_OPENGL); 11 else al_set_new_display_flags(ALLEGRO_FULLSCREEN); 12 13 if(setting.frequency) al_set_new_display_refresh_rate(setting.frequency); 14 } 15 else if(setting.fullscreen == 2) { // Fullscreen Window (0 = window) 16 if(setting.opengl) al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW | ALLEGRO_OPENGL); 17 else al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); 18 19 if(setting.frequency) al_set_new_display_refresh_rate(setting.frequency); 20 } 21 22 al_set_new_bitmap_flags(ALLEGRO_MAG_LINEAR); 23 al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); 24 25 al_set_new_display_option(ALLEGRO_SINGLE_BUFFER, 1, ALLEGRO_REQUIRE); 26 27 // Allegro picks the desktop resolution automatically with ALLEGRO_FULLSCREEN_WINDOW flag set. 28 setting.screen = al_create_display(WIDTH, HEIGHT); 29 if(!setting.screen) { 30 a5_error(AT, setting.screen, "Create display failed."); 31 shut_down(); 32 exit(1); 33 } 34 35 setting.w = al_get_display_width(setting.screen); 36 setting.h = al_get_display_height(setting.screen); 37 38 // Call scale screen to fit our fullscreen window on screen. 39 if(setting.fullscreen == 2) a5_scale_screen(WIDTH, HEIGHT, setting.w, setting.h); 40 41 // Load fonts and bitmaps here (removed code) 42 43 // reset the target bitmap back to the display 44 al_set_target_bitmap(al_get_backbuffer(setting.screen)); 45}

---
“I love you too.” - last words of Wanda Roy

roger levy
Member #2,513
July 2002

@Edgar MinGW gcc 4.8.1

@NiteHackr The flags I set at program start are:
ALLEGRO_OPENGL
ALLEGRO_WINDOWED
ALLEGRO_RESIZABLE

Neil Roy
Member #2,229
April 2002
avatar

I just edited my last post with my code. I don't use "ALLEGRO_RESIZABLE" at all and most of the time I do not use OpenGl, although the option is there for it and it works.

Edit: Oh, and I personally use Allegro 5.1.7 (precompiled) and GCC 4.7.0, as well as Windows 7.

---
“I love you too.” - last words of Wanda Roy

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I'm not sure what to tell you except to wait for someone who knows more. It could be a change made to Windows 8 that broke something, but I don't know because window creation should be the same on every windows version but somebody correct me if I'm wrong.

roger levy
Member #2,513
July 2002

Indeed I just discovered that by removing ALLEGRO_OPENGL the issue is gone. The game still seems to run at full speed, so I'm guessing it's running in D3D mode? I guess I found a bug in the OpenGL implementation.

This is fine as a temporary fix but I need OpenGL, all my advanced graphics modules are in OpenGL (fast quads, shaders, 3d models, render to texture, etc).

Neil Roy
Member #2,229
April 2002
avatar

Ah, yeah, after reading your post I just tried my own game out with OPENGL enabled (OpenGL 4 on my system) and it crashed, where as it works perfectly fine without it.

"Assertion failed: 0, file d:\Libraries\build\allegro\src\allegro-git\allegro-git
\src\opengl\ogl_bitmap.c, line 357"
(I am using Allegro 5.1.7, GCC 4.7.0 on Windows 7)

After further testing, this only happens in ALLEGRO_FULLSCREEN mode, it doesn't happen in an ALLEGRO_WINDOWED or ALLEGRO_FULLSCREEN_WINDOW.

---
“I love you too.” - last words of Wanda Roy

roger levy
Member #2,513
July 2002

Kris Asick
Member #1,424
July 2001

When I first switched to using Windows 8, I noticed that ALLEGRO_WINDOWED and ALLEGRO_FULLSCREEN_WINDOW were producing stuttering in the framerates of the game I'm working on, where the framerate will be fine for a moment, then stutter for a moment, then be fine for a moment, stutter for a moment, fine for a moment, etc. etc.

However, this only affects the first ALLEGRO_DISPLAY object created. Destroying that display and creating another eliminates the stuttering issue, even if the new display is identical to the first one in every way.

As a workaround to this, I'm moving all video configuration options into a startup window running ALLEGRO_WINDOWED, where a little bit of stuttering isn't going to make a huge difference. Not sure if it's strictly OpenGL related or not as my game uses GLSL fragment shaders so I pretty much have to use OpenGL exclusively for the moment.

However...

1. I have not run into the problem described from the start of this thread. I can make multiple screen setting switches without running into a missing desktop. That said...

2. ...if I switch into one video mode then try immediately to switch into another without really doing anything, this causes some extremely nasty glitching to occur, forcing me to perform a hard-reset of the entire system.

For reference, I never use al_toggle_display_flag() as I was taught from the early days of game coding that you NEVER "adjust" existing displays. The best approach is to close out the display completely (loaded textures and all) and start a new one in order to ensure you're not breaking anything in the process, since altering an existing display context can be an extremely temperamental process that is likely going to perform differently on every OS and video card combination out there. :P

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

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I can confirm that it doesn't work to change back to windowed mode from a fullscreen window with opengl. I'm using latest 5.1 from GIT, MinGW 4.5.0 and I'm on Vista.

Edit
I can also confirm that completely re-creating the display fixes the problem in both directx and opengl modes.

Neil Roy
Member #2,229
April 2002
avatar

I didn't have a problem creating displays for OpenGL, my problem was with the following line totally crashing my game:

al_draw_scaled_bitmap(al_get_backbuffer(setting.screen), offset_x, offset_y, WIDTH*scale_x, HEIGHT*scale_y, 0, 0, WIDTH, HEIGHT, 0);

This line works perfectly with DirectX in Windowed, Fullscreen Windowed and Fullscreen.
It works perfectly with OpenGL in Windowed and Fullscreen Windowed.

It only crashes in OpenGL Fullscreen mode. It copies the game screen to a buffer of size WIDTHxHEIGHT which is created with all error checks in place, so I figure my only option at this point is to remove OpenGL support, at least in that mode anyhow, which will make my game Windows only, or at least not have a fullscreen/OpenGL option on other platforms.

---
“I love you too.” - last words of Wanda Roy

Slartibartfast
Member #8,789
June 2007
avatar

pkrcel
Member #14,001
February 2012

He probably sets a different taget bitmap before the instruction, I guess.

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

Slartibartfast
Member #8,789
June 2007
avatar

pkrcel said:

He probably sets a different taget bitmap before the instruction, I guess.

I see. Still doing it wrong though ;)

Quote:

al_get_backbuffer

ALLEGRO_BITMAP *al_get_backbuffer(ALLEGRO_DISPLAY *display)

Return a special bitmap representing the back-buffer of the display.

Care should be taken when using the backbuffer bitmap (and its sub-bitmaps) as the source bitmap (e.g as the bitmap argument to al_draw_bitmap). Only untransformed operations are hardware accelerated. This consists of al_draw_bitmap and al_draw_bitmap_region when the current transformation is the identity. If the tranformation is not the identity, or some other drawing operation is used, the call will be routed through the memory bitmap routines, which are slow. If you need those operations to be accelerated, then first copy a region of the backbuffer into a temporary bitmap (via the al_draw_bitmap and al_draw_bitmap_region), and then use that temporary bitmap as the source bitmap.

Not sure if that would fix the crash, but it should at least adhere better to the documentation :)

pkrcel
Member #14,001
February 2012

I see, that "scaled" is a major issue then, surely a crash is STILL a downer since it was only expected to be "slow".

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

Slartibartfast
Member #8,789
June 2007
avatar

pkrcel said:

I see, that "scaled" is a major issue then, surely a crash is STILL a downer since it was only expected to be "slow".

Indeed, though it is likely that the crash is caused because of a bug leading to the "fast" code path being used when the "slow" code path should be used, thus fixing that call to be fast may just fix the crash for his current code and version of allegro.

pkrcel
Member #14,001
February 2012

Now, NH should answer, but I got the impression that the scaled version is fundamental in maintaining the aspect ratio?

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

 1   2 


Go to: