Change screen orientation on the iPhone/iPad [SOLVED]

Previous topic - Next topic

Millerszone

If you have an iPad and you are a developer then you already know that an iPad app must be able to work in
all 4 orientations or at least 2, either in landscape or portrait modes. GLBasic does not do this automatically.

I'm currently using this procedure with my iPad games "Hit the Deck Baseball" and "Just Pong", and works flawlessly

I've included the code below to make your iPad/iPhone app orientate in either landscape or portrait modes.
I'm using OpenGL commands directly, so it is fast. I notice no slow downs in FPS.

To know what orientation the iPad/iPhone is in, use this code:
http://www.glbasic.com/forum/index.php?topic=4650.msg35088#msg35088

NOTE: besides the code below, you must also reverse BOTH X and Y mouse inputs.

Add this code to your main loop:
Code (glbasic) Select

SETSCREEN 1024, 768, TRUE
LOADBMP background$

FUNCTION upateGraphics:
    glPushMatrix()
        // use this code to flip 180 landscape (home button on left)
        glRotatef(180.0, 0.0, 0.0, 1.0)
        glTranslatef(-1024, -768, 0.0)  <-- change for iPhone

        //use this code to flip 180 portrait (home button on top)
        //glRotatef(90.0, 0.0, 0.0, 1.0)
        //glTranslatef(-768, -1024, 0.0)  <-- change for iPhone

        //      *** all your DRAW code goes here  ***
    glPopMatrix()
SHOWSCREEN
ENDFUNCTION


Add this OpenGL wrapper code to a new file in your project.
Code (glbasic) Select

// INLINE functions to use OpenGL functions by Gernot
// directly inside GLBasic

INLINE
#define OGL                ::
typedef float           GLfloat;
ENDINLINE

INLINE
} extern "C" { void __stdcall glTranslatef( GLfloat x , GLfloat y , GLfloat z );; }; namespace __GLBASIC__ {
ENDINLINE
FUNCTION glTranslatef: x, y, z
    INLINE
        OGL glTranslatef(x, y, z);
    ENDINLINE
ENDFUNCTION

INLINE
} extern "C" { void __stdcall glRotatef( GLfloat angle , GLfloat x , GLfloat y , GLfloat z );; }; namespace __GLBASIC__ {
ENDINLINE
FUNCTION glRotatef: angle, x, y, z
    INLINE
        OGL glRotatef(angle, x, y, z);
    ENDINLINE
ENDFUNCTION

INLINE
} extern "C" { void __stdcall glPushMatrix( void );; }; namespace __GLBASIC__ {
ENDINLINE
FUNCTION glPushMatrix:
    INLINE
        OGL glPushMatrix();
    ENDINLINE
ENDFUNCTION

INLINE
} extern "C" { void __stdcall glPopMatrix( void );; }; namespace __GLBASIC__ {
ENDINLINE
FUNCTION glPopMatrix:
    INLINE
        OGL glPopMatrix();
    ENDINLINE
ENDFUNCTION


EDIT: Found a solution and updated the code.
Hardware: iMac 27", MacBook Air, PC 3.5Ghz Quad
Developing Tools: GLBasic SDK, Gideros Studio, PureBasic
Developing for: iOS, Android, Windows, OS X, webOS, HTML5

matchy

Draw on a (createscreen) sprite and rotosprite draw it according to the joyx.  :zzz:

Slydog

QuoteDraw on a (createscreen) sprite and rotosprite draw it according to the joyx.

But wouldn't all the touch input will be at the default orientation?
I guess you could handle that in code, but may get a little messy.

Is rotating that difficult for GLBasic? (on iPhones)
It would be so much easier if GLBasic handled the rotation for us (and rotated the input accordingly).

Like the links above (I never checked them), is there not some last minute camera matrix rotation that can be done by Gernot, based on a (new) rotation/orientation command?

It would be nice even if it simply used matchy's suggestion and called ROTOSPRITE for us.
It may not be the fastest solution, but it would at least work and keep our code consistent, and ready for a better solution if Gernot finds one (after an update).

Just wondering, as I have to tackle this myself eventually!
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Millerszone

Quote from: Slydog on 2010-Nov-02
It would be so much easier if GLBasic handled the rotation for us (and rotated the input accordingly).
That would be nice!
I purchased Gernot Dr. Shiver HD game for the iPad, it rotates in all orientations, and very smooth.

I'm trying the CREATESCREEN and ROTOSPRITE that "matchy" suggested, but I'm not having much luck.
I got the screen to do a 180, but nothing moves. ( warning: I'm still learning. )
Here is a example of what I'm doing...

CREATESCREEN 1,10,1024,768
USESCREEN 1

// main loop
   WHILE TRUE

// *** MY GAME CODE HERE *** at 1024x768

   USESCREEN -1
   ROTOSPRITE 10, 0, 0, 180
   SHOWSCREEN
WEND

Hardware: iMac 27", MacBook Air, PC 3.5Ghz Quad
Developing Tools: GLBasic SDK, Gideros Studio, PureBasic
Developing for: iOS, Android, Windows, OS X, webOS, HTML5

matchy

Almost got it and there's more examples on the forum is you care to search for it.  ;)

This sample shows how to do it easily, not efficiently although the extra steps to draw to a createscreen sprite isn't much to worry about is it?  :sick:
Code (glbasic) Select

CREATESCREEN 1,10,1024,1024 // <-----rotating a square might help/be easier
// main loop
   WHILE TRUE
    USESCREEN 1 // <---------must be in loop

    /// *** invert mouse according to angle 0,90,180,270
    /// example: http://www.glbasic.com/forum/index.php?topic=4806.msg36640#msg36640
    /// more: http://www.glbasic.com/forum/index.php?topic=4650.msg35088#msg35088


// *** MY GAME CODE HERE *** at 1024x768

   USESCREEN -1
   ROTOSPRITE 10, 0, 0, 180
   SHOWSCREEN
WEND

Millerszone

O.K by moving the USESCREEN 1 inside the main loop, my objects are moving, everything
looks good but the objects aren't erasing each frame, they are leaving streaks behind them.
I'm using LOADBMP for my background.

Yes, I already had these in my code:
http://www.glbasic.com/forum/index.php?topic=4806.msg36640#msg36640
http://www.glbasic.com/forum/index.php?topic=4650.msg35088#msg35088

NOTE: I read this in the forum.
http://www.glbasic.com/forum/index.php?topic=4459
On iPhone once we set the project screen it can't be changed, so for changing the screen
between portrait and landscape in the same application we can only do currently a CREATE/USESCREEN.
This effectively draws what we want, but it can't be used really on iPhone, the simple sentence:
USESCREEN 0
USESCREEN -1
drops automatically game FPS from 60 to 40 doing nothing inside, and drawing into one screen
other than -1 is much worse.

Thanks for the help, I'm getting closer!

Hardware: iMac 27", MacBook Air, PC 3.5Ghz Quad
Developing Tools: GLBasic SDK, Gideros Studio, PureBasic
Developing for: iOS, Android, Windows, OS X, webOS, HTML5

Slydog

I'm guessing that you can't use 'LOADBMP' if you also want to implement orientation.
The background sprite is baked into 'USESCREEN -1' (back buffer), and 'CREATESCREEN 1' / 'USESCREEN 1' can't access the background.  You will have to create a normal sprite for the background instead, and draw that sprite first each frame (on screen '1').

And I was worried there may be a drop in FPS, and that's why I was wondering if the screen can be rotated at the OpenGL level, using a Matrix (and hopefully automatic!  =D)
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Millerszone

Quote from: Slydog link=topic=5298.msg41263#msg41263 date=
I'm guessing that you can't use 'LOADBMP' if you also want to implement orientation.
The background sprite is baked into 'USESCREEN -1' (back buffer), and 'CREATESCREEN 1' / 'USESCREEN 1' can't access the background.  You will have to create a normal sprite for the background instead, and draw that sprite first each frame (on screen '1').
That's what I thought I was going to have to do. If I have to use a DRAWSPRITE for my background pic at 1024x768 for each frame then my FPS drops from 60 to 35 on the iPad.

Quote
And I was worried there may be a drop in FPS, and that's why I was wondering if the screen can be rotated at the OpenGL level, using a Matrix (and hopefully automatic!  =D)
It seems like these commands ( glPushMatrix, glTranslatef, glRotatef, glPopMatrix ) from those links I posted shouldn't be very hard to make work with GLBasic.




Hardware: iMac 27", MacBook Air, PC 3.5Ghz Quad
Developing Tools: GLBasic SDK, Gideros Studio, PureBasic
Developing for: iOS, Android, Windows, OS X, webOS, HTML5

matchy

You'll have to clearscreen for <>0 screens. Also, if the device angle is zero, then there is no need to rotosprite..thus getting original fps.  :P


ampos

Just create a rotated background in PS and do the following:

Code (glbasic) Select
If angle=0
   loadbmp "back1.png"
else
   loadbmp "back2.png"
endif


Or more flexible, on the point you check if the screen is rotated or not:
Code (glbasic) Select

if angle=0
  bk$="back1.png"
else
  bk$="back2.png"
endif
...
loadbmp bk$


Another option (if angle=0 or 180)
Code (glbasic) Select

load "back"+angle+".png"


and name your backgrounds as "back0.png" & "back180.png"
check my web and/or my blog :D
http://diniplay.blogspot.com (devblog)
http://www.ampostata.org
http://ampostata.blogspot.com
I own PC-Win, MacBook 13", iPhone 3G/3GS/4G and iPAC-WinCE

matchy

Changing the background doesn't deal with reversing the mouse inputs and draw positions.

ampos

I was a answer to the "last" problem (rotated loadbmp), rotating the background, as the other rotating problems "seems" resolved with rotosprite.

BTW, I liked more your first answer  :P

Quoteampos, that's such a simplistic yet perfect solution without losing fps.  :good:
So I should point out that the screen doesn't need to literately animate the rotation.

Of course, the nice way is:

Code (glbasic) Select
if hasrotated=true
   grabsprite 1,0,0,1024,768
   backscreen
   for a=0 to 180 step 5
      rotosprite 1,somewherex,somewherey,a
      showscreen
   next
endif
...continue yuor program


To make a rotating screen effect
check my web and/or my blog :D
http://diniplay.blogspot.com (devblog)
http://www.ampostata.org
http://ampostata.blogspot.com
I own PC-Win, MacBook 13", iPhone 3G/3GS/4G and iPAC-WinCE

matchy

 :D :D :D This issue has me thinking and changing my mind.

When animated rotating, I use a square 1024x1024/480x480 because it hides the background (near the corners). Anyhow, what I have found in the overall process is how the application design. For example, I have an accepted app that rotates a square like menu only because there's no orientation for the actually app interface which stay still. Not sure about the design of menus that are on a 45' angle in the corner.

Most important, there is also a button structure that shifts the portrait/landscape (all four orientations) corner buttons to there appropriate place and I've had to include all these new features to an existing app.

I think I will still to landscape only games. ;)

erico

what if...

let's say you want your game to work one orientation only, portrait, and when you rotate to landscape, the game pauses and display game statistics and options? :S

that way the app works on all orientation right?

Ian Price

Quotelet's say you want your game to work one orientation only, portrait, and when you rotate to landscape, the game pauses and display game statistics and options? :S

Monkey Island does that - and it's fecking annoying. If you don't hold the device almost perfectly still the game pauses and the Load/Save screen pops up. Aaarggghhhh! (done in a pirate voice, obviously!).
I came. I saw. I played.