GMS 2 Scaling game surface with different sized rooms

AndHeDrew

Member
Hello!
I've been trying to crack this problem for a while, and I haven't been able to find a solution.

I am adapting Pixelated Pope's scaling method to work with my game, and I'm stuck. Here's what I'm trying to do:

1. Determine the size of the monitor
2. Scale the application surface height to the biggest size that I can, while staying pixel perfect.
3. Adjust the view width to fit the screen size, so there's never any black bars on the sides.

Right. This all works, unless, in fullscreen, the room is shorter than the optimal height, or narrower than the optimal width. Then I get some distortion, and I haven't been able to figure out what's going wrong. I'm seeking the counsel of better programming minds than mine! Thank you for having a look. Do let me know if I can clarify anything.

Display Manager Object

Create Event:
Code:
//track if we've restarted rooms (for viewport tracking)
global.restart_room = true;

//disable automatic drawing of surface
application_surface_draw_enable(false);

//ideal game Height, empty variable for width
global.ideal_game_width = 0;
global.ideal_game_height = 306;

//get monitor dimensions
global.MonitorW = display_get_width();
global.MonitorH = display_get_height();

//get window dimensions
global.Window_Width = window_get_width();
global.Window_Height = window_get_height();

//offset variables
global.Xoffset= -1;
global.Yoffset= -1;

//loop to resize game (up to 10x) to fit monitor
for (var i=1; i<=10; i++)
{
   
game_scale = i; //checking -10 to see if the game can scale more
gameH_scaled = global.ideal_game_height*game_scale; //getting the height for a scaled version 

    if global.MonitorH >= gameH_scaled //if monitor height is greater than the scaled height of the game...
        {
            gameW_scaled = global.MonitorW;    //set the width to monitor width
            surface_resize(application_surface,gameW_scaled,gameH_scaled); //resize the application to scaled propotions
           
            display_set_gui_size(gameW_scaled, gameH_scaled); //resize the gui to the same size
           
            if !window_get_fullscreen()
                {
                    global.Xoffset=0; //calculate offsets
                    global.Yoffset=0;
                }
                else
                {
                    global.Xoffset=(global.MonitorW-gameW_scaled)/2; //calculate offsets
                    global.Yoffset=(global.MonitorH-gameH_scaled)/2;   
                }

           
            gameScaleFinal = game_scale; //save the final scale
            gameH_scaledFinal = gameH_scaled; //save the final height
            gameW_scaledFinal = gameW_scaled; //save the final width
        }

}

trueH = gameH_scaledFinal/gameScaleFinal; //calulate the un-scaled size of the fullscreen game
trueW = gameW_scaledFinal/gameScaleFinal;

global.gameScaleFinal = gameScaleFinal;

roomWidth_array = array_create(100, noone);
roomHeight_array = array_create(100, noone);



for (var i=1; i<=room_last; i++)
    {
        if(room_exists(i))
        {
       
            room_set_view_enabled(i, true);

            room_set_viewport(i, 0, true, 0, 0, trueW, trueH); //set all viewports to the un-scaled size of the fullscreen game
        }
}

room_goto(global.spawnRoom);
Room Start Event:
(This is where I try to adjust the room if the dimensions are too short/narrow)
Code:
if (room_width < trueW) && (room_height < trueH)
{
    room_set_viewport(room, 0, true, 0, 0, room_width, room_height);

    var room_scaled_width = room_width*gameScaleFinal;
    var room_scaled_height = room_height*gameScaleFinal;
       
    global.Xoffset = (global.MonitorW-room_scaled_width)/2;
    global.Yoffset = (global.MonitorH-room_scaled_height)/2;
   
    global.currant_scaled_width  =    room_scaled_width;
    global.currant_scaled_height =  room_scaled_height;
   
   
    //if in windowed mode, adjust accordingly
    if !window_get_fullscreen()
    {
    window_set_size(room_scaled_width,room_scaled_height);
       
    alarm[2] = 1;
    }



} else if room_width < trueW
{
    show_debug_message("triggered");
    room_set_viewport(room, 0, true, 0, 0, room_width, trueH);
    var room_scaled_width = room_width*gameScaleFinal;
       
       
    global.Xoffset=(global.MonitorW-room_scaled_width)/2;
    global.Yoffset=(global.MonitorH-gameH_scaledFinal)/2;
   
    global.currant_scaled_width  =    room_scaled_width;
    global.currant_scaled_height =  gameH_scaledFinal;
       
       
    //if in windowed mode, adjust accordingly
    if !window_get_fullscreen()
    {
    window_set_size(room_scaled_width,gameH_scaledFinal);
       
    alarm[2] = 1;
    }
   

} else if room_height < trueH 
    {
    room_set_viewport(room, 0, true, 0, 0, trueW, room_height);
    var room_scaled_height = room_height*gameScaleFinal;
   
    global.Xoffset=(global.MonitorW-gameW_scaledFinal)/2;
    global.Yoffset=(global.MonitorH-room_scaled_height)/2;
   
    global.currant_scaled_width  =    gameW_scaledFinal;
    global.currant_scaled_height =  room_scaled_height;
       
    //if in windowed mode, adjust accordingly
    if !window_get_fullscreen()
    {
    window_set_size(gameW_scaledFinal,room_scaled_height);
    alarm[2] = 1;
    }


} else {
        room_set_viewport(room, 0, true, 0, 0, trueW, trueH);
       
           
        global.Xoffset=(global.MonitorW-gameW_scaledFinal)/2;
        global.Yoffset=(global.MonitorH-gameH_scaledFinal)/2;
       
        //if in windowed mode, adjust accordingly
        if !window_get_fullscreen()
        {
        window_set_size(gameW_scaledFinal,gameH_scaledFinal);
        alarm[2] = 1;
        }
   
       
}
   
if global.restart_room
{
    global.restart_room = false;
    alarm[0] = 5; //this resets the "global.restart_room" variable
    room_restart();
   
}
Post-draw event:
Code:
//insure proper gui size
var sw = surface_get_width(application_surface);
var sh = surface_get_height(application_surface);
display_set_gui_size(sw,sh);


draw_sprite_tiled_ext(spr_thistle_pattern, 0, 0, 0, 1, 1, c_white, 1); //background pattern


//game maker needs this when manually drawing the surface
gpu_set_blendenable(false);

if !window_get_fullscreen()
{
//draw application surface
draw_surface_ext(application_surface,0,0,1,1,0,c_white,1);
}
else
{
//draw application surface
draw_surface_ext(application_surface,global.Xoffset,global.Yoffset,1,1,0,c_white,1);
}
   


   
   
//game maker needs this when manually drawing the surface
gpu_set_blendenable(true);
 
Top