mirror of
https://github.com/thes3m/XNI
synced 2024-12-26 13:26:06 +01:00
202 lines
6.1 KiB
Objective-C
202 lines
6.1 KiB
Objective-C
//
|
|
// GameWindow.m
|
|
// XNI
|
|
//
|
|
// Created by Matej Jan on 20.7.10.
|
|
// Copyright 2010 Retronator. All rights reserved.
|
|
//
|
|
|
|
#import "GameWindow.h"
|
|
#import "GameWindow+Internal.h"
|
|
|
|
#import "Retronator.Xni.Framework.h"
|
|
#import "GameViewController.h"
|
|
#import "GameView.h"
|
|
#import "TouchPanel+Internal.h"
|
|
|
|
@interface GameWindow() {
|
|
BOOL fakeLandscapeBounds;
|
|
}
|
|
|
|
- (Rectangle*) calculateClientBounds;
|
|
|
|
@end
|
|
|
|
|
|
@implementation GameWindow
|
|
|
|
- (id) init {
|
|
if (self = [super init]) {
|
|
clientSizeChanged = [[Event alloc] init];
|
|
orientationChanged = [[Event alloc] init];
|
|
|
|
clientBounds = [[Rectangle rectangleWithCGRect:[[UIScreen mainScreen] bounds]] retain];
|
|
float scale = [UIScreen mainScreen].scale;
|
|
clientBounds.width *= scale;
|
|
clientBounds.height *= scale;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
// PROPERTIES
|
|
|
|
@synthesize clientBounds;
|
|
@synthesize clientSizeChanged;
|
|
@synthesize orientationChanged;
|
|
|
|
- (DisplayOrientation) currentOrientation {
|
|
return [GameViewController getDisplayOrientationForInterfaceOrientation:gameViewController.interfaceOrientation];
|
|
}
|
|
|
|
- (UIWindow*) window {
|
|
return window;
|
|
}
|
|
|
|
- (GameViewController *) gameViewController {
|
|
return gameViewController;
|
|
}
|
|
|
|
- (id) handle {
|
|
return (id)gameViewController.view.layer;
|
|
}
|
|
|
|
// METHODS
|
|
|
|
- (void) beginScreenDeviceChangeWithFullscreen:(BOOL)willBeFullscreen {
|
|
gameViewController.wantsFullScreenLayout = willBeFullscreen;
|
|
[[UIApplication sharedApplication] setStatusBarHidden:willBeFullscreen];
|
|
}
|
|
|
|
- (void) endScreenDeviceChangeWithClientWidth:(int)clientWidth clientHeight:(int)clientHeight {
|
|
|
|
// Before iOS 6.0 the orientation is handled with a different set of functions. Get version so we can act acordingly.
|
|
float version = [[[UIDevice currentDevice] systemVersion] floatValue];
|
|
|
|
CGRect realFrame = [UIScreen mainScreen].applicationFrame;
|
|
float realScale = [UIScreen mainScreen].scale;
|
|
|
|
// Set target view frame to full screen frame to determine orientation.
|
|
gameViewController.view.frame = realFrame;
|
|
|
|
CGRect orientedFrame = gameViewController.view.bounds;
|
|
NSLog(@"%f, %f", orientedFrame.size.width, orientedFrame.size.height);
|
|
BOOL deviceIsLandscape = orientedFrame.size.width > orientedFrame.size.height;
|
|
|
|
BOOL clientWantsOnlyLandscape = !(gameViewController.supportedOrientations & DisplayOrientationPortrait);
|
|
|
|
if (deviceIsLandscape || clientWantsOnlyLandscape) {
|
|
int height = clientHeight;
|
|
clientHeight = clientWidth;
|
|
clientWidth = height;
|
|
}
|
|
|
|
float realAspectRatio = realFrame.size.width / realFrame.size.height;
|
|
|
|
if (clientWidth == 0) {
|
|
clientWidth = realFrame.size.width * realScale;
|
|
}
|
|
|
|
if (clientHeight == 0) {
|
|
clientHeight = realFrame.size.height * realScale;
|
|
}
|
|
|
|
double targetAspectRatio = (float)clientWidth/(float)clientHeight;
|
|
CGRect targetFrame;
|
|
|
|
if (targetAspectRatio >= realAspectRatio) {
|
|
// Add black borders on top and bottom.
|
|
targetFrame.size.width = realFrame.size.width ;
|
|
targetFrame.size.height = roundf(targetFrame.size.width / targetAspectRatio);
|
|
} else {
|
|
// Add black borders on left and right.
|
|
targetFrame.size.height = realFrame.size.height;
|
|
targetFrame.size.width = roundf(targetFrame.size.height * targetAspectRatio);
|
|
}
|
|
|
|
// Center the window.
|
|
targetFrame.origin.x = realFrame.origin.x + (realFrame.size.width - targetFrame.size.width) / 2;
|
|
targetFrame.origin.y = realFrame.origin.y + (realFrame.size.height - targetFrame.size.height) / 2;
|
|
|
|
// Resize the target view.
|
|
gameViewController.view.frame = targetFrame;
|
|
|
|
// Set scale factor.
|
|
if (targetAspectRatio >= realAspectRatio) {
|
|
gameViewController.gameView.scale = clientWidth / realFrame.size.width;
|
|
} else {
|
|
gameViewController.gameView.scale = clientHeight / realFrame.size.height;
|
|
}
|
|
|
|
// Recalculate client bounds.
|
|
[clientBounds release];
|
|
clientBounds = [[self calculateClientBounds] retain];
|
|
|
|
if (version < 6) {
|
|
// If the user requested a landscape backbuffer and our view is still reporting a portrait orientation,
|
|
// this will change with a later call, so we should manually adjust the (incorrect) bounds for now.
|
|
// Also, don't switch the orientation if it is already correctly in landscape.
|
|
if (clientWantsOnlyLandscape && clientBounds.width < clientBounds.height) {
|
|
int height = clientBounds.height;
|
|
clientBounds.height = clientBounds.width;
|
|
clientBounds.width = height;
|
|
fakeLandscapeBounds = YES;
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void) initialize {
|
|
// Create UI window.
|
|
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
|
|
|
// Create game view controller.
|
|
gameViewController = [[GameViewController alloc] initWithGameWindow:self];
|
|
|
|
[((GameView*)gameViewController.view).viewSizeChanged
|
|
subscribeDelegate:[Delegate delegateWithTarget:self Method:@selector(gameViewSizeChanged)]];
|
|
|
|
// Add the game view to the window.
|
|
[window addSubview: gameViewController.view];
|
|
window.rootViewController = gameViewController;
|
|
|
|
// Report view to TouchPanel.
|
|
[[TouchPanel getInstance] setView:gameViewController.gameView];
|
|
|
|
// Present the window.
|
|
[window makeKeyAndVisible];
|
|
}
|
|
|
|
- (void) setSupportedOrientations:(DisplayOrientation)orientations {
|
|
gameViewController.supportedOrientations = orientations;
|
|
}
|
|
|
|
- (void) gameViewSizeChanged {
|
|
Rectangle *newClientBounds = [self calculateClientBounds];
|
|
if (![newClientBounds equals:clientBounds]) {
|
|
[clientBounds release];
|
|
clientBounds = [newClientBounds retain];
|
|
[clientSizeChanged raiseWithSender:self];
|
|
} else if (fakeLandscapeBounds) {
|
|
// Still call client size changed, since the actual screen was in portrait mode before.
|
|
fakeLandscapeBounds = NO;
|
|
[clientSizeChanged raiseWithSender:self];
|
|
}
|
|
}
|
|
|
|
- (Rectangle*) calculateClientBounds {
|
|
Rectangle *bounds = [Rectangle rectangleWithCGRect:gameViewController.view.bounds];
|
|
float scale = gameViewController.gameView.scale;
|
|
bounds.width *= scale;
|
|
bounds.height *= scale;
|
|
return bounds;
|
|
}
|
|
|
|
- (void) dealloc
|
|
{
|
|
[clientBounds release];
|
|
[gameViewController release];
|
|
[window release];
|
|
[super dealloc];
|
|
}
|
|
|
|
@end
|