Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » A5 Fullscreen Vs Windowed

This thread is locked; no one can reply to it. rss feed Print
 1   2 
A5 Fullscreen Vs Windowed
AceBlkwell
Member #13,038
July 2011
avatar

All,

Is there a way of switching to full screen other than just making my display 1920,XXX? In A4 there is WINDOWED and FULLSCREEN. Does A5 have something comparable?

Thanks

*UPDATE* I tried
al_set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, !(al_get_display_flags(display) & ALLEGRO_FULLSCREEN_WINDOW));

but it just makes the program screen bigger. It doesn't change the resolution so my game pieces are the same size and to upper left of the screen. This line was also supposed to allow toggling, (something I'm not looking for yet) but without the title bar, I'm not sure how you are supposed to do that.

DanielH
Member #934
January 2001
avatar

Per the documents, Prefer using ALLEGRO_FULLSCREEN_WINDOW as it typically provides a better user experience as the monitor doesn’t change resolution and switching away from your game via Alt-Tab works smoothly. ALLEGRO_FULLSCREEN is typically less well supported compared to ALLEGRO_FULLSCREEN_WINDOW.

Otherwise, destroy current display, toggle flag, then make a new display.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

DanielH
Member #934
January 2001
avatar

He's doesn't want full screen window, but full screen.

Better to just have your stuff stretch to fill the larger full screen window.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

AceBlkwell
Member #13,038
July 2011
avatar

Sorry for the delay in getting back to everyone.

Here is the init code for the game.

#SelectExpand
1void a_init() 2{ 3 init_confirm(al_init(), "allegro"); 4 init_confirm(al_install_keyboard(), "keyboard"); 5 init_confirm(al_install_mouse(), "mouse"); 6 init_confirm(al_init_font_addon(), "font_addon"); 7 init_confirm(al_init_ttf_addon(), "ttf_addon"); 8 init_confirm(al_init_primitives_addon(), "primitives"); 9 init_confirm(al_init_image_addon(), "image addon"); 10 11 titlescr = al_load_bitmap("Title Screen.png"); 12 init_confirm(titlescr, "Title Screen"); 13 14 timer = al_create_timer(1.0 / 30.0); 15 init_confirm(timer, "timer"); 16 17 queue = al_create_event_queue(); 18 init_confirm(queue, "queue"); 19 20 disp = al_create_display(640, 560); 21 init_confirm(disp, "display"); 22 al_set_display_flag(disp, ALLEGRO_FULLSCREEN_WINDOW, !(al_get_display_flags(disp) & ALLEGRO_FULLSCREEN_WINDOW)); // added code for fullscreen 23 24 font = al_load_font("PressStart2P.ttf",24,0); 25 init_confirm(font, "font"); 26 27 err_font = al_load_font("PressStart2P.ttf",18,0); 28 init_confirm(err_font, "Error font"); 29 30 scr_font = al_load_font("PressStart2P.ttf",36,0); 31 init_confirm(scr_font, "Screen Font"); 32 33 34 al_register_event_source(queue, al_get_keyboard_event_source()); 35 al_register_event_source(queue, al_get_mouse_event_source()); 36 al_register_event_source(queue, al_get_display_event_source(disp)); 37 al_register_event_source(queue, al_get_timer_event_source(timer)); 38 39} /* End a_init() */

I've added the before and after screen shots. You can see the display size does get bigger but the components of the screen remain the same size.
On an A4 game (as I remember) I changed my game from WINDOWED to FULLSCREEN and the writing / images changed with the screen size. Again, I believe it reset the screen resolution so the 640x480 was full screen or a window on a 1920 x 1200 screen.

Thanks

DanielH
Member #934
January 2001
avatar

ALLEGRO_FULLSCREEN_WINDOWED makes your display the size of the screen. It won't change the size of anything else. As I said earlier, if you want everything else to scale to the larger or smaller sizes, you have to scale them.

Here is what I like to do:

#SelectExpand
1ALLEGRO_DISPLAY* display = nullptr; 2ALLEGRO_BITMAP* buffer = nullptr; 3 4int init() 5{ 6 // init allegro, etc 7 8 // start display windowed and able to be resized 9 al_set_new_display_flag(ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE): 10 11 // don't need the default double buffer if I'm drawing to my own buffer 12 al_set_new_display_option(ALLEGRO_SINGLE_BUFFER, 1, ALLEGRO_SUGGEST); 13 display = al_create_displayp(1024, 960); 14 if (!display) return -1; 15 16 // create buffer to a dedicated size. What ever you need. 17 buffer = al_create_bitmap(640, 480); 18 if (!buffer) return -1; 19 20 // more init stuff 21 22 return 0; 23} 24 25void draw() 26{ 27 // get current target so we can restore when we're done drawing 28 ALLEGRO_BITMAP* target = al_get_target_bitmap(); 29 30 //set our buffer to be the drawing target 31 al_set_target_bitmap(buffer); 32 33 // do my drawing 34 35 // restore the previous target buffer 36 al_set_target_bitmap(target); 37 38 // draw and scale our buffer to size of display 39 al_draw_scaled_bitmap(buffer, 0, 0, al_get_bitmap_width(buffer), al_get_bitmap_height(buffer), 0, 0, al_get_display_width(display), al_get_display_height(display), 0); 40 41 // draw display to screen 42 al_flip_display();

It's off the top of my head, so maybe bugs.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

AceBlkwell
Member #13,038
July 2011
avatar

I think I figured out the difference in the A4 and A5 setup in my programs. In A4, I wasn't altering the screen size, I was changing the resolution of the monitor. This allows the components of the game screen to change proportionally.

See the game screen from my A4 game and you'll notice the screen items didn't remain the same size when the screen was in full screen mode.

A4 used this command.
set_gfx_mode(GFX_AUTODETECT,640, 480, 0, 0); //Fullscreen. Could have used GFX_AUTODETECT_FULLSCREEN as well

or
set_gfx_mode(GFX_AUTODETECT_WINDOWED,640, 480, 0, 0); // for window screen

In A5 I was using

al_set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, !(al_get_display_flags(display) & ALLEGRO_FULLSCREEN_WINDOW)); // It does make the game full screen but doesn't change the content of the screen proportionally .

So back to my original question is there any equivalent in A5 of the A4 set_gfx_mode? Thanks

DanielH
Member #934
January 2001
avatar

Like we said before: you have to destroy the current display, change the new display flags, create the new display

Don't do this if you have a bunch of events. Make sure all events are cleared first. Or if you do, then immediately flush event queue. Might have events using previous display and we don't want that.

Here, I made it slightly easier

#SelectExpand
1// toggles fullscreen/windowed 2DISPLAY* al_toggle_display_mode(ALLEGRO_DISPLAY* display); 3 4// call it like this 5my_display = al_toggle_display_mode(my_display); 6 7 8DISPLAY* al_toggle_display_mode(ALLEGRO_DISPLAY* display) 9{ 10 // get current display's flags 11 int flags = al_get_display_flags(display); 12 13 // toggle fullscreen/windowed mode 14 if (flags & ALLEGRO_FULLSCREEN) 15 { 16 flags = flags | ALLEGRO_WINDOWED ^ ALLEGRO_FULLSCREEN; 17 } 18 else 19 { 20 flags = flags | ALLEGRO_FULLSCREEN ^ ALLEGRO_WINDOWED; 21 } 22 23 // destroy current display 24 al_destroy_display(display); 25 26 // change new display flags 27 al_set_new_display_flags(flags); 28 29 // recreate display 30 return al_create_display(width, height); 31}

Or how about you set what you want

#SelectExpand
1DISPLAY* al_set_display_mode(ALLEGRO_DISPLAY* display, bool fullscreen) 2{ 3 // get current display's flags 4 int flags = al_get_display_flags(display); 5 6 // don't do anything if already set 7 if ((fullscreen && (flags & ALLEGRO_FULLSCREEN)) || (!fullscreen && (flags & ALLEGRO_WINDOWED)) 8 { 9 return display; 10 } 11 12 // remove both windowed and/or fullscreen mode 13 flags &= ~int(ALLEGRO_WINDOWED | ALLEGRO_FULLSCREEN); 14 15 // set windowed or fullscreen 16 flags |= (fullscreen ? ALLEGRO_FULLSCREEN : ALLEGRO_WINDOWED); 17 18 // destroy current display 19 al_destroy_display(display); 20 21 // change new display flags 22 al_set_new_display_flags(flags); 23 24 // recreate display 25 return al_create_display(width, height); 26}

AceBlkwell
Member #13,038
July 2011
avatar

Daniel,

The code looks good. I'll copy it so I can goof around with it. Thanks.

I may have been a little misleading. I'm not looking at toggling back and forth or resizing windows. I was trying to take an easy way out.

Currently my game is in a 640,480 window. My grandson asked if I could make it bigger. The blocks on the screen are say 40x80 with say 20 pixels between. I was trying to get out of making them all 80X120 and then recalculating all the X/Y starting points, move all the verbiage down the screen XX amount of pixels (IE trial and error) I was hoping the game would just change screen modes to 640,480 (full screen) and I wouldn't have to rewrite the graphics. Sounds like in A5 it's not as easy as A4.

Of course by now I could have rewrote it ;D. Thanks again for your help.

DanielH
Member #934
January 2001
avatar

Sounds like in A5 it's not as easy as A4.

Yes and no. It's a hurdle you have to jump. I find it superior to A4 even if a little more cumbersome. It helped that I was already pretty fluent with A4 and had been using for years. I was on the fence and decided to switch to A5. To do that, I remade a game I made in A4 to A5 as a learning tool.

Points:
A4 is not updated.
A5 has been out for over a decade now. Has OpenGl/Direct3D builtin which give you hardware accelerated drawing from the start.

As to your issue:

Stretch it.

Make a buffer 640,480. Draw all things to buffer unstretched.
Stretch buffer to display. Then it doesn't matter if fullscreen or windowed and you can use allegro_fullscreen_windowed.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

640x480 fullscreen resolutions are probably deprecated in Windoze by now. You need at least 800x600 or 1024,768 and HDMI is 1920x1080. 4K is out now as well. It really depends on whether or not your monitor is an ancient piece of poo or not. I'm guessing it's a CRT? Even a decade ago a decent CRT could do 1600x1200.

AceBlkwell
Member #13,038
July 2011
avatar

;D Edgar,

I just chose 640x480 when I was experimenting with writing in A5. After I got the program working well enough along with my grandson's request, I wanted to go larger. I just didn't want to re-write the graphic locations, sizes, and mouse reaction locations. So I was hoping, like A4, I could set the graphics mode instead. Given that's not easily possible and the game is pretty simple, I'll just re-write. I was really just thinking of the future should I get in a similar situation.

Daniel gave me some good direction, that I may hold on to for the future but may be a little complicated for such a simple game. Thanks anyways Daniel.

I did try al_set_new_display_flags(ALLEGRO_FULLSCREEN) but it stops the display from initializing. If I do RESIZABLE or FULLSCREEN_WINDOW it functions fine, just doesn't do what I was hoping it would do.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

amelia
Member #23,824
September 2023

To toggle fullscreen and windowed modes in Allegro 5, use al_set_display_flag with ALLEGRO_FULLSCREEN_WINDOW. Remember to adjust your display's resolution and adapt your drawing logic accordingly for each mode to maintain proper rendering of game elements. Implement a UI element for user-initiated mode changes. you can learn more at: https://fifaapk.com/

AceBlkwell
Member #13,038
July 2011
avatar

Daniel mentioned something about stretching. What do I do, write to a 640x480 (in this example) buffer then from buffer to a 1600x1000 display?

Honestly I didn't know you could blit in A5? I've been al_draw(ing) and flipping. Thanks.

DanielH
Member #934
January 2001
avatar

Use the function al_draw_scaled_bitmap to apply the proper transforms.

// buffer is your bitmap (640,480 or whatever you need)
// target is current target which should be display's backbuffer.

al_draw_scaled_bitmap(buffer, 0, 0, al_get_bitmap_width(buffer), al_get_bitmap_height(buffer), 0, 0, al_get_bitmap_width(target), al_get_bitmap_height(target), 0);

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

AceBlkwell
Member #13,038
July 2011
avatar

Hey amelia, I missed your input. I'll check it out. Thanks

Edgar, why read the manual when you can talk directly with the people who wrote the manual ;D. Seriously, I could do a better job of reading up. However, I do often "google" my problem first, but MAN pages giving a description of what a command does isn't nearly as helpful as a brief tutorial approach to a command.

Example,
al_flip_display

void al_flip_display(void). Copies or updates the front and back (doesn't tell how) buffers so that what has been drawn previously on the currently selected display becomes visible on screen. Pointers to the special back and front buffer bitmaps remain valid and retain their semantics as back and front buffers respectively, although their contents may have changed.
Several display options change how this function behaves: etc etc.

See also: al_set_new_display_flags, al_set_new_display_option. I can start down this rabbit hole of links to links to further links.

My question that it doesn't answer is will this command allow me to chose which display I want to flip?
Like maybe al_flip_display(BUFFER)' or al_flip_display(DISP);

My confusion with Daniel's example is I don't al_draw_ to a given ALLEGRO_DISPLAY*. Since I was only using one, I assumed all my al_draw commands were drawing to the only game in town. Now that I'm generating a second one as a buffer, how to I draw to buffer, al_draw_scaled_bitmap from buffer to disp and flip the disp (not the buffer)?

You have a valid point in my case, I do often go to the path of least resistance, but in my defense, Some of the MAN pages aren't written for novices. IMHO

DanielH
Member #934
January 2001
avatar

#SelectExpand
1void draw() 2{ 3 // grab current target bitmap 4 ALLEGRO_BITMAP* target = al_get_target_bitmap(); 5 6 // set our buffer bitmap as target 7 al_set_target_bitmap(buffer); 8 9 // do all drawing 10 al_clear_to_color(color::map(0xffffffff)); 11 // other drawing 12 13 // restore previous target bitmap 14 al_set_target_bitmap(target); 15 16 // draw our buffer bitmap to display stretching to fit 17 al_draw_scaled_bitmap(buffer, 18 0.0f, 0.0f, 19 al_get_bitmap_width(buffer), 20 al_get_bitmap_height(buffer), 21 0.0f, 0.0f, 22 al_get_display_width(display), 23 al_get_display_height(display), 0); 24 25 // flip display 26 al_flip_display(); 27}

AceBlkwell
Member #13,038
July 2011
avatar

Now your talking Daniel. So simple even I can follow. Of course that doesn't mean I won't have further questions on the topic ::)

** UPDATE ** See told you. I'm at a loss on "target" I understand target is a bitmap and buffer is a bitmap and display is a display. However, if we are not drawing to target, why is it needed or why do I need to switch back and forth? Can't I just draw to buffer, send it to display and then flip?

DanielH
Member #934
January 2001
avatar

All drawing is done to the current target. ALL drawing.

If you want to draw to a different target (like a buffer bitmap) then you have to set it. Then you have to reset it back to the display's back buffer to draw the buffer to the display.

In my example, I am preserving whatever is the current target. Usually the display's back buffer. You don't have to do it that either. You could just set target to display's back buffer.

AceBlkwell
Member #13,038
July 2011
avatar

Thanks Daniel. I get it now, or at least in my trial and error. You can't al_draw_scaled_bitmap a bitmap that is still the target. I couldn't get it to work until I did as you said and created a second bitmap to revert back to prior to my al_draw_scaled_bitmap command.

It visually works fine. The down side is my mouse positions are way off. Example, I have a "Play" button at 489 x 343 to 575 x 379. My program looks for the mouse to be somewhere within that boundary while the mouse button is down. With the stretching, my "Play" button is closer to 1300 x 700 to 1380 x 736 . So while I've solved my graphics enlarging issue, I still have the mouse Key Down location issue. Still it's been educational. Thanks for all the help.

DanielH
Member #934
January 2001
avatar

#SelectExpand
1// ** warning ** I pulled this from my github repository and removed all parts not needed. 2// So may have introduced errors or bugs. 3// these are stored in my class, but could make them global if needed. 4float aspect_x = 0.0f; 5float aspect_y = 0.0f; 6float mouse_x = 0.0f; 7float mouse_y = 0.0f; 8 9// during init, but after both display and buffer are created. I set the current aspects 10aspect_x = static_cast<float>(al_get_bitmap_width(buffer)) / static_cast<float>(al_get_display_width(display)); 11aspect_y = static_cast<float>(al_get_bitmap_height(buffer)) / static_cast<float>(al_get_display_height(display)); 12 13 14// while processing events 15case ALLEGRO_EVENT_DISPLAY_RESIZE: 16{ 17 al_acknowledge_resize(event.display.source); 18 aspect_x = static_cast<float>(al_get_bitmap_width(buffer)) / static_cast<float>(al_get_display_width(event.display.source)); 19 aspect_y = static_cast<float>(al_get_bitmap_height(buffer)) / static_cast<float>(al_get_display_height(event.display.source)); 20} break; 21 22 23case ALLEGRO_EVENT_MOUSE_AXES: 24{ 25 mouse_x = static_cast<float>(event.mouse.x) * aspect_x; 26 mouse_y = static_cast<float>(event.mouse.y) * aspect_y; 27} break;

 1   2 


Go to: