• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Rotating entire game for vertical monitor

S

shrunkenmaster

Guest
I'm trying to rotate my entire Windows game for a vertical screen. I can use view_angle for the playfield, but I need the whole GUI rotated too.

I came across this post:


Would I call this like a regular script, and where would I call it from?

Could someone please help me implement this?



Code:
/// @description d3d - set orthographic
/// @param x       x of tl corner
/// @param y       y of tl corner
/// @param w       w of view
/// @param h       h of view
/// @param angle   rotation angle of the projection

var xx = argument0;
var yy = argument1;
var ww = argument2;
var hh = argument3;
var angle = argument4;

var mV = matrix_build_lookat( xx+ww/2, yy+hh/2, -16000,
                             xx+ww/2, yy+hh/2, 0,
                            dsin(-angle), dcos(-angle), 0 );
var mP = matrix_build_projection_ortho( ww, hh, 1, 32000 );

//camera_set_view_mat( global.__d3dCamera, mV );
//camera_set_proj_mat( global.__d3dCamera, mP );
//camera_apply( global.__d3dCamera );
camera_set_view_mat( camera_get_active(), mV );
camera_set_proj_mat( camera_get_active(), mP );
camera_apply( camera_get_active() );

[/CODE}
 

samspade

Member
I'm trying to rotate my entire Windows game for a vertical screen. I can use view_angle for the playfield, but I need the whole GUI rotated too.

I came across this post:


Would I call this like a regular script, and where would I call it from?

Could someone please help me implement this?



Code:
/// @description d3d - set orthographic
/// @param x       x of tl corner
/// @param y       y of tl corner
/// @param w       w of view
/// @param h       h of view
/// @param angle   rotation angle of the projection

var xx = argument0;
var yy = argument1;
var ww = argument2;
var hh = argument3;
var angle = argument4;

var mV = matrix_build_lookat( xx+ww/2, yy+hh/2, -16000,
                             xx+ww/2, yy+hh/2, 0,
                            dsin(-angle), dcos(-angle), 0 );
var mP = matrix_build_projection_ortho( ww, hh, 1, 32000 );

//camera_set_view_mat( global.__d3dCamera, mV );
//camera_set_proj_mat( global.__d3dCamera, mP );
//camera_apply( global.__d3dCamera );
camera_set_view_mat( camera_get_active(), mV );
camera_set_proj_mat( camera_get_active(), mP );
camera_apply( camera_get_active() );

[/CODE}
Does it always need to be rotated? If so, then I would simply design your game that way from the start. In other words, make the room and view portrait orientation in the room editor. You can then go into the android settings and lock it into portrait so that it cannot flip over to landscape.

If you are asking how to set it up so that you can switch from landscape to portrait and back you wouldn't be rotating your camera. You would simply be changing your camera's (and gui layer's) dimensions.
 
S

shrunkenmaster

Guest
Does it always need to be rotated? If so, then I would simply design your game that way from the start. In other words, make the room and view portrait orientation in the room editor. You can then go into the android settings and lock it into portrait so that it cannot flip over to landscape.

If you are asking how to set it up so that you can switch from landscape to portrait and back you wouldn't be rotating your camera. You would simply be changing your camera's (and gui layer's) dimensions.
Hi Sam, thanks for the reply. The game is for Windows, not Android. Essentially it's a vertical/portrait game only, so I need to rotate the whole thing 90 degrees to display on a rotated monitor. When I started making the game (my first) I didn't look into this, so I hope I'm not stuck here!
 
S

shrunkenmaster

Guest
Unless I'm very much mistaken, I don't think those functions will be able to determine my crt tv's size...

Did you take a peek at that code above? Apparently in previous GM versions you could use "d3d_set_projection_ortho" to rotate the GUI.
 

samspade

Member
It's very possible I misunderstand what you want to do, but the code you provided and the other post you referenced are about the ability to rotate the view to different angles—e.g. 28.5—not go from portrait to landscape and back. Unless you want continuous rotation so that as you rotate your monitor the game rotates smoothly from 0-90 (which I'm not even sure that's possible on a windows computer) you don't need anything that complicated. All you need is to determine what the proportions of the screen are (which you can do with display get width/height) and then size the view and gui layer accordingly.
 
S

shrunkenmaster

Guest
It's very possible I misunderstand what you want to do, but the code you provided and the other post you referenced are about the ability to rotate the view to different angles—e.g. 28.5—not go from portrait to landscape and back. Unless you want continuous rotation so that as you rotate your monitor the game rotates smoothly from 0-90 (which I'm not even sure that's possible on a windows computer) you don't need anything that complicated. All you need is to determine what the proportions of the screen are (which you can do with display get width/height) and then size the view and gui layer accordingly.
OK, I'll try to clarify!
I only need to rotate the whole game once.
I don't need to go from portrait and landscape and back.
The monitor does not rotate, it is just physically turned 90 degrees, as an arcade game monitor would be for a vertical shmup.

This is how I've made the game:

ray_normal.jpg

This is how I want it:
ray_allgood.jpg

This is what I'm stuck with (all I've done is set camera_set_view_angle to 90):
ray_viewrotated.JPG

As you can see, I need to rotate the GUI to match the view. Apologies if I didn't explain this properly and thanks for your input and patience, it's much appreciated.
 
S

shrunkenmaster

Guest
Well, turns out that script I posted at the start does exactly what I want (I tried it on a new project with just some GUI text and it works) - unfortunately it does not work with my camera, so I'll need to look into that.
 

NightFrost

Member
Could you give me any advice with this? I'm brand new to surfaces.
You set your room / view / GUI / application surface size as you would when you draw the game in portrait fashion. However you take over the draw operation and handle it yourself. In whatever object you have that sets up your display properties, also add to Create event an application_surface_draw_enable(false); call, which turns off automatic drawing. Then, in Post Draw event, add draw_surface_ext() command. The source surface for that command will be application_surface. Importantly, you set rotation to 90 degrees, so the surface will be drawn to screen sideways as you wanted. The surface rotates by upper left corner, so you must set the command's x/y positioning to lower left corner so it is visible after rotating.

(Application surface is the default, automatically generated and maintained surface on which GMS normally draws everything before sending it to display device during Post Draw. You are taking over the last part of the automation here and performing the draw yourself, rotated.)
 
S

shrunkenmaster

Guest
You set your room / view / GUI / application surface size as you would when you draw the game in portrait fashion. However you take over the draw operation and handle it yourself. In whatever object you have that sets up your display properties, also add to Create event an application_surface_draw_enable(false); call, which turns off automatic drawing. Then, in Post Draw event, add draw_surface_ext() command. The source surface for that command will be application_surface. Importantly, you set rotation to 90 degrees, so the surface will be drawn to screen sideways as you wanted. The surface rotates by upper left corner, so you must set the command's x/y positioning to lower left corner so it is visible after rotating.

(Application surface is the default, automatically generated and maintained surface on which GMS normally draws everything before sending it to display device during Post Draw. You are taking over the last part of the automation here and performing the draw yourself, rotated.)
Firstly, thank you for such a concise and clear post, that's really helped me! I can now get the game oriented correctly, but not the GUI as well. It still seems like the camera is interfering somehow.

If you have a minute to look over this I'd be very grateful - here's how I have things set up:

oRoomInit : Create (initial setup room)
Code:
window_scale=3;
display_set_gui_size(240*window_scale,320*window_scale);
oCamera : Create
Code:
view_width=240;
view_height=320;
window_scale=3;

window_set_size (view_height*window_scale, view_width*window_scale);
alarm[0] = 1; //window center

surface_resize(application_surface,view_width*window_scale ,view_height*window_scale);
       
var app = application_get_position();
var w = (app[2]-app[0]) / (view_width*window_scale);
var h = (app[3]-app[1]) / (view_height*window_scale);
display_set_gui_maximize(w,h,app[0],app[1]);

application_surface_draw_enable(false);
oCamera : End Step
Code:
#macro view view_camera [0]
camera_set_view_size(view, view_width, view_height);

#region start camera
if (room=rm_start) {
    global._x = clamp(view_width/2,0,room_width-view_width);
    global._y = clamp(view_height/2,0,room_height-view_height);
                 
    camera_set_view_pos(view,global._x,global._y);
}
#endregion

(plus other camera views for different rooms)
oCamera : Room Start
Code:
view_enabled = true;
view_visible[0] = true;
oCamera : Post Draw
Code:
draw_surface_ext (application_surface, 0, 720, 1 ,1, 90, c_white, 0.5);
oGame : Draw GUI Begin (game controller object where I draw the GUI)
Code:
tatescript (0,0,240,320,90)
The tatescript code for GUI rotation:
Code:
/// @description d3d - set orthographic
/// @param x       x of tl corner
/// @param y       y of tl corner
/// @param w       w of view
/// @param h       h of view
/// @param angle   rotation angle of the projection

var xx = argument0;
var yy = argument1;
var ww = argument2;
var hh = argument3;
var angle = argument4;

var mV = matrix_build_lookat( xx+ww/2, yy+hh/2, -16000,
                             xx+ww/2, yy+hh/2, 0,
                            dsin(-angle), dcos(-angle), 0 );
var mP = matrix_build_projection_ortho( ww, hh, 1, 32000 );

//camera_set_view_mat( global.__d3dCamera, mV );
//camera_set_proj_mat( global.__d3dCamera, mP );
//camera_apply( global.__d3dCamera );
camera_set_view_mat( camera_get_active(), mV );
camera_set_proj_mat( camera_get_active(), mP );
camera_apply( camera_get_active() );
I don't know if these images with help, but this is with the (oCamera : Room Start) code disabled:
view_disabled.jpg

And with it enabled:
view_enabled.jpg

I'm pulling my hair out here!!
 
Last edited by a moderator:
S

shrunkenmaster

Guest
Well, after a lot of messing about I finally solved this by drawing the GUI to a new surface and rotating that.
 
Top