Screen Resolution Question
DrazeSwift

I'm back again! (I promise I really am trying to debug things myself and I really do appreciate the help) I have been doing some reading and realized that creating the screen you are drawing too is a lot more complex because of different monitor sizes and resolutions of people that will be using your program. I am working on a game that I would like to be full screen. I have been using:

ALLEGRO_DISPLAY *display = NULL;
//other allegro stuff
//...
al_set_new_display_flags(ALLEGRO_FULLSCREEN);
display = al_create_display(WIDTH, HEIGHT);      
if(!display)        //test display object
{
al_show_native_message_box(display, "Error", "Error", "Display window could not be shown", NULL, NULL);
fout << "Display Failed!" << endl; cout << "Display Failed!" << endl;
    return -1;
  }

But I have seen functions like this more commonly on the forums and stuff:

set_color_depth(16);
if(set_gfx_mode(GFX_AUTODETECT_WINDOWED, 1024, 768, 0, 0) != 0){
allegro_message("gfx mode with selected color depth is not available");
exit(-1);

So my questions are:

What is the difference and is one better?
How do I actually make a program work in full screen on any system (and I guess I would work with a widescreen and put black bars if I was on a non widescreen?)

Thanks, maybe I am missing something easy here and making this way more complicated than it is.

Neil Roy

First, use

<code>

and

</code>

. ;)

In your first example, that is Allegro 5 code. In the bottom example with the set_gfx_mode(), that is older Allegro 4 code that you're seeing.

You are right though, if you wish to support full screen you will need to add in black bars or pick a resolution like 800x600 and just do window mode.

I had this same problem when Matthew Leverton helped me with this function which will do what you want. It basically uses ALLEGRO_TRANSFORM to fit the resolution you wish to the user's desktop resolution and stretches it up to fit rather than setting a new resolution.

This is a copy and paste of the function from my own game... feel free to use it.

Just pass this function the desktop resolution and the buffer width and height of your screen to be scaled up...

a5_scale_screen.c

#SelectExpand
1// Scale Screen: 2// Sets up transforms in order to fit any resolution 3// onto an ALLEGRO_FULLSCREEN_WINDOW. 4// 5// (Special thanks to Matthew Leverton for help with this!) 6 7#include "a5_scale_screen.h" 8 9 10 11// Use to get mouse position on scaled screen 12float scale_x = 1; 13float scale_y = 1; 14int offset_x = 0; 15int offset_y = 0; 16 17 18 19// usage: a5_scale_screen(BUFFER_WIDTH, BUFFER_HEIGHT, display_width, display_height); 20void a5_scale_screen(int bw, int bh, int dw, int dh) 21{ 22 ALLEGRO_TRANSFORM t; 23 24 // Calculate the horizontal and vertial aspect ratios 25 const float HAR = dw / (float)bw; 26 const float VAR = dh / (float)bh; 27 28 // The aspect ratio, x-offset and y-offset (in pixels) 29 float ar, ox, oy; 30 31 if(bw == dw && bh == dh) { 32 // 1:1, just reset everything 33 al_identity_transform(&t); 34 al_use_transform(&t); 35 al_set_clipping_rectangle(0, 0, bw, bh); 36 scale_x = 1; 37 scale_y = 1; 38 offset_x = 0; 39 offset_y = 0; 40 al_clear_to_color(al_map_rgb(0, 0, 0)); 41 al_flip_display(); 42 } 43 else { 44 // Choose the smaller aspect ratio 45 if(HAR < VAR) { 46 // horizontal bars on the top and bottom 47 ar = HAR; 48 ox = 0; 49 oy = (dh - (ar * bh)) / 2.0; 50 } 51 else { 52 // vertical bars on the left and right 53 ar = VAR; 54 ox = (dw - (ar * bw)) / 2.0; 55 oy = 0; 56 } 57 58 // set the global scale/offset so the mouse coords can be inverted 59 // use the following code to get the proper mouse position 60 // mouse_x = (event.mouse.x - offset_x) / scale_x; 61 // mouse_y = (event.mouse.y - offset_y) / scale_y; 62 scale_x = ar; 63 scale_y = ar; 64 offset_x = ox; 65 offset_y = oy; 66 67 // set up the transformation to scale and translate 68 al_build_transform(&t, ox, oy, ar, ar, 0); 69 al_use_transform(&t); 70 71 // clear out the screen before setting the clipping 72 al_set_clipping_rectangle(0, 0, dw, dh); 73 al_clear_to_color(al_map_rgb(0, 0, 0)); 74 al_flip_display(); 75 76 // make sure nothing is drawn into the black bars 77 al_set_clipping_rectangle(ox, oy, ar * bw, ar * bh); 78 } 79}

and the header file I use...

a5_scale_screen.h

#ifndef _a5_scale_screen_h_
#define _a5_scale_screen_h_

#include <allegro5/allegro.h>

extern float scale_x;
extern float scale_y;
extern int offset_x;
extern int offset_y;

// usage: a5_scale_screen(BUFFER_WIDTH, BUFFER_HEIGHT, display_width, display_height);
void a5_scale_screen(int bw, int bh, int dw, int dh);

#endif

Kris Asick

The simplest approach is to create a buffer that's larger than a typical screen size, render everything to this buffer, then scale it to match the screen size of the end user. A good resolution to go with for wide-screen, scalable rendering is 2560x1440, since this scales nicely to 1280x720 (720p) and 1920x1080 (1080p) so long as you don't use any really thin lines in your scaling or such, plus it also assures that your game will run OK and look spectacular in the future when 1440p becomes the standard.

If you want to continue to support standard 4:3 aspect and/or 16:10 resolutions like 1680x1050, you have two options: Scale you wide-screen game to fit in such resolutions with black bars around the outer edges, or design your UI to work with multiple aspect ratios, which is a lot trickier to accomplish since you won't be able to rely on full-screen background images for UI layouts and everything UI related will need to be capable of floating into logical positions, but ensures your game can fill the full screen at any aspect ratio. 8-)

DrazeSwift

Fixed the code sorry about that!

So I would create a buffer of 2560x1440 draw to that call

a5_scale_screen(2560, 1440, ?, ?);

How would you find out the current resolution that the user is using? because that is what you are passing in for the 3rd and 4th ints right? and it will scale according to that? Thanks for posting the source, I found it helpful!

Neil Roy

So I would create a buffer of 2560x1440 draw to that calla5_scale_screen(2560, 1440, ?, ?);How would you find out the current resolution that the user is using? because that is what you are passing in for the 3rd and 4th ints right? and it will scale according to that? Thanks for posting the source, I found it helpful!

That resolution for a buffer seems a tad large to me. Don't forget the memory that will be required to render to that and the possible speed requirements needed. You'll have to think of your target audience and what system requirements they will need to run this. Do you wish to support people with older systems or only newer etc...

Anyhow, here you go...

#SelectExpand
1 #define WIDTH 800 2 #define HEIGHT 600 3 4 al_set_new_bitmap_flags(ALLEGRO_MAG_LINEAR); 5 al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); 6 al_set_new_display_option(ALLEGRO_SINGLE_BUFFER, 1, ALLEGRO_REQUIRE); 7 al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); 8 9 // Allegro picks the desktop resolution automatically with 10 // ALLEGRO_FULLSCREEN_WINDOW flag set. 11 myscreen = al_create_display(WIDTH, HEIGHT); 12 13 int desktop_w = al_get_display_width(myscreen); 14 int desktop_h = al_get_display_height(myscreen); 15 16 a5_scale_screen(WIDTH, HEIGHT, desktop_w, desktop_h);

Edit: changed it to look like my code that I know works. Alter as needed ;)

Thread #613077. Printed from Allegro.cc