Game Development Community

iT2D 1.4.1 preview - iPad portrait mode not supported - FIXED

by Conor O'Kane · in iTorque 2D · 03/05/2011 (6:59 pm) · 10 replies

iPad portrait mode games stall at the loading screen in iT2D 1.4.1 preview.

Steps to recreate:
Make a new project in iT2D and set it to iPad portrait mode. Put some text in the level. Run it to build .dsos.
Open the Xcode project, upgrade it to iPad, device specific.
Build and run the iPad target on the device in release mode (or debug mode).

The default.png splash screen loads but the game does not proceed any further. Canvas.cs is the last script to load.

#1
03/06/2011 (2:51 pm)
I ran into this last week on 1.4.0 and found the problem. When checking to see if the canvas was larger than the max, it did not take the orientation of the device into consideration. This may or may not be the same issue in 1.4.1 (I have yet to upgrade), but since you mentioned Canvas I am assuming that is it.

open platformiphone/iPhoneWindow.mm

find the initWindow function

Move the following two lines up above where it checks max screens size.
//Get screen orientation prefs //Based on 0 Landscape, 1 Portrait
 	 	158	        gScreenOrientation = Con::getIntVariable( "$pref::iDevice::ScreenOrientation" );
 	 	159	        gScreenUpsideDown = Con::getBoolVariable( "$pref::iPhone::ScreenUpsideDown" );

Replace the max screen size check with the following code:

int xMax = IPHONE_MAX_RESOLUTION_X;
 	 	163	        int yMax = IPHONE_MAX_RESOLUTION_Y;
 	 	164	        if(gScreenOrientation==1)
 	 	165	        {
 	 	166	                // If we are portrait, swap maxes for checking bounds
 	 	167	                xMax = IPHONE_MAX_RESOLUTION_Y;
 	 	168	                yMax = IPHONE_MAX_RESOLUTION_X;
 	 	169	        }
 	 	170	        
 	 	171	        if( initialSize.x < xMax || initialSize.y < yMax ) {
158	172	                Platform::AlertOK( "Invalid Initial window size", "initalSize is less than or equal to 0, using default resolution" );
 	 	173	        } else  if( initialSize.x > xMax || initialSize.y > yMax ) {
160	174	                Platform::AlertOK( "Invalid Initial window size", "initalSize is greater than max supported size, using default resolution." );
 	161	175	        } else {
 	 	176	        
162	177	                platState.windowSize = initialSize;
 	163	178	        }





#2
03/06/2011 (7:59 pm)
Nicely done Mark. Hopefully this can get integrated into 1.4.1 before its final release.
#3
03/07/2011 (9:28 am)
Cheers! Just re-read my post. Ignore line 159. I copied this from a code review and that line was old and replaced by 173... (checking to see if I can remove it in my post above so it will be less confusing to those who read this later).
#4
03/12/2011 (2:39 pm)
Added this code to the 1.4.1 build. Works like a charm. Thanks Mark. This will make it into the final release.
#5
03/12/2011 (10:45 pm)
Except one problem. This caused an infinite loop when trying to run an iOS project using 480x320 resolution. I should have noticed it just by looking at the code. The premise is right, but the code has to be modified to handle everything. Regardless, taken care of for 1.4.1 final
#6
03/13/2011 (11:27 am)
I still need to test my code changes, but as far as I can tell the following check is almost pointless:

if( initialSize.x < MIN_RESOLUTION_X || initialSize.y < MIN_RESOLUTION_Y ) {
		Platform::AlertOK( "Invalid Initial window size", "initalSize is less than or equal to 0, using default resolution" );
	} else 	if( initialSize.x > IPHONE_MAX_RESOLUTION_X || initialSize.y > IPHONE_MAX_RESOLUTION_Y ) {
		Platform::AlertOK( "Invalid Initial window size", "initalSize is greater than max supported size, using default resolution." );
	} else {
		platState.windowSize = initialSize;
	}

I'm tracing the code and from what I can tell there is not a way to actually create a bad resolution on an iOS device unless you are manually hard coding the values. Walk through this with me.

1. Your game is launched and the following function is called from script:

createCanvas(...)

2. From this function, a resolution is determined and passed into the function where your modifications were made:

void Platform::initWindow(const Point2I &initialSize, const char *name)

3. When createCanvas is called on iOS, the following preprocessor command is true

#ifdef TORQUE_OS_IPHONE

4. Inside of that block is where the iOS resolution is determined, based on the following three variables variables grabbed from script:

iDeviceType = Con::getIntVariable("$pref::iDevice::DeviceType");
iDeviceRes = Con::getIntVariable("$pref::iDevice::ScreenResolution");
iDeviceOrientation = Con::getIntVariable("$pref::iDevice::ScreenOrientation");

5. The variable startRes (which is a Point2I) is passed into initWindow(...):

Platform::initWindow(startRes, argv[1]);

6. Nowhere in that code is a user allowed to manually set the startRes value in createCanvas or initialSize in initWindow, which leads me to my original theory that the following check is essentially pointless:

if( initialSize.x < MIN_RESOLUTION_X || initialSize.y < MIN_RESOLUTION_Y ) {
		Platform::AlertOK( "Invalid Initial window size", "initalSize is less than or equal to 0, using default resolution" );
	} else 	if( initialSize.x > IPHONE_MAX_RESOLUTION_X || initialSize.y > IPHONE_MAX_RESOLUTION_Y ) {
		Platform::AlertOK( "Invalid Initial window size", "initalSize is greater than max supported size, using default resolution." );
	} else {
		platState.windowSize = initialSize;
	}

With your modifications, the game runs into an infinite while loop when trying to run using an iPhone resolution by entering the Platform::AlertOK function. Without the modification, iPad portrait mode does not work.

I'm going to comment that block out and try the multiple resolutions and orientations to see what the outcome is. There is still probably room for some safety check and the ability to support future resolutions more elegantly, but for 1.4.1 I think this will be good enough.

I've said it before, but there is no predicting Apple hardware. They could release an iPad 3 with a resolution of 940x2340 if they want, so all this hard coding of resolution limits needs to stop.

Edited the post to remove some misinterpreted code statements
#7
03/13/2011 (11:36 am)
Now, there is still a way for a developer to shoot his/her own foot with camera tweaking. The editor still allows for camera resolution changing, but again one would have to manually set the values. If said developer manually enters 1020 for the width and 740 for the height, the came is not going to look right.

There is room for some kind of usability improvement like displaying a message box saying something along the lines of "iOS devices do not support these resolutions, just so you know". Still, if you are making an iOS game you should know the constraints of the the device.
#8
03/15/2011 (7:53 am)
My code worked. This is resolved for 1.4.1.
#9
03/16/2011 (11:41 am)
Fixed in 1.4.1 Final.
#10
03/16/2011 (11:41 am)
Fixed in 1.4.1 Final.

It's so important the site felt it needed to be said twice.
#11
05/07/2011 (9:56 pm)
@Michael

I posted a comment in another thread at
www.garagegames.com/community/forums/viewthread/125576

where I followed the same code execution described here. This is regarding Retina Display. It seems to me that all it should be needed to get Retina is just a one line of code in Platform::initWindow, as in

if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2)  
            glView.contentScaleFactor = 2;

Do you have any comments on this? Thanks.