49 if (isGameRunning() == NO) |
49 if (isGameRunning() == NO) |
50 return (interfaceOrientation == (UIInterfaceOrientation) self.initialOrientation); |
50 return (interfaceOrientation == (UIInterfaceOrientation) self.initialOrientation); |
51 return rotationManager(interfaceOrientation); |
51 return rotationManager(interfaceOrientation); |
52 } |
52 } |
53 |
53 |
54 // pause the game and remove objc menus so that animation is smoother |
54 // while in dual head the above rotation functions are not called |
55 -(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation) toInterfaceOrientation duration:(NSTimeInterval) duration{ |
55 -(void) handleRotationEvent:(NSNotification *)notification { |
56 if (isGameRunning() == NO) |
56 if (isGameRunning() == NO) |
57 return; |
57 return; |
58 |
58 |
59 HW_pause(); |
|
60 [self dismissPopover]; |
|
61 |
|
62 if (self.amvc.isVisible && IS_DUALHEAD() == NO) { |
|
63 [self.amvc disappear]; |
|
64 wasVisible = YES; |
|
65 } else |
|
66 wasVisible = NO; |
|
67 |
|
68 [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; |
|
69 |
|
70 UIView *sdlView = [[[UIApplication sharedApplication] keyWindow] viewWithTag:SDL_VIEW_TAG]; |
|
71 switch (toInterfaceOrientation) { |
|
72 case UIDeviceOrientationLandscapeLeft: |
|
73 sdlView.transform = CGAffineTransformMakeRotation(degreesToRadians(a)); |
|
74 break; |
|
75 case UIDeviceOrientationLandscapeRight: |
|
76 sdlView.transform = CGAffineTransformMakeRotation(degreesToRadians(b)); |
|
77 break; |
|
78 default: |
|
79 // a debug log would spam too much |
|
80 break; |
|
81 } |
|
82 } |
|
83 |
|
84 // now restore previous state |
|
85 -(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation) fromInterfaceOrientation { |
|
86 if (isGameRunning() == NO) |
|
87 return; |
|
88 |
|
89 if (wasVisible || IS_DUALHEAD()) |
|
90 [self.amvc appearInView:self.view]; |
|
91 HW_pauseToggle(); |
|
92 |
|
93 [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; |
|
94 } |
|
95 |
|
96 // while in dual head the above rotation functions are not called |
|
97 -(void) dualHeadRotation:(NSNotification *)notification { |
|
98 if (isGameRunning() == NO) |
|
99 return; |
|
100 |
|
101 UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; |
59 UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; |
102 UIView *sdlView = [[[UIApplication sharedApplication] keyWindow] viewWithTag:SDL_VIEW_TAG]; |
60 UIView *sdlView = [[[UIApplication sharedApplication] keyWindow] viewWithTag:SDL_VIEW_TAG]; |
103 |
61 NSInteger angle_left = (self.initialOrientation == UIInterfaceOrientationLandscapeLeft) ? 180 : 0; |
104 [UIView beginAnimations:@"rotation" context:NULL]; |
62 NSInteger angle_right = (self.initialOrientation == UIInterfaceOrientationLandscapeLeft) ? 0 : 180; |
105 [UIView setAnimationDuration:0.7]; |
63 |
|
64 if (IS_VERY_POWERFUL()) { |
|
65 [UIView beginAnimations:@"overlay rotation" context:NULL]; |
|
66 [UIView setAnimationDuration:0.7]; |
|
67 } |
106 switch (orientation) { |
68 switch (orientation) { |
107 case UIDeviceOrientationLandscapeLeft: |
69 case UIDeviceOrientationLandscapeLeft: |
108 self.view.frame = [[UIScreen mainScreen] bounds]; |
70 self.view.frame = [[UIScreen mainScreen] bounds]; |
109 self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(90)); |
71 self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(90)); |
110 sdlView.transform = CGAffineTransformMakeRotation(degreesToRadians(a)); |
72 if (IS_DUALHEAD() == NO) |
|
73 sdlView.transform = CGAffineTransformMakeRotation(degreesToRadians(angle_left)); |
111 break; |
74 break; |
112 case UIDeviceOrientationLandscapeRight: |
75 case UIDeviceOrientationLandscapeRight: |
113 self.view.frame = [[UIScreen mainScreen] bounds]; |
76 self.view.frame = [[UIScreen mainScreen] bounds]; |
114 self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(-90)); |
77 self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(-90)); |
115 sdlView.transform = CGAffineTransformMakeRotation(degreesToRadians(b)); |
78 if (IS_DUALHEAD() == NO) |
|
79 sdlView.transform = CGAffineTransformMakeRotation(degreesToRadians(angle_right)); |
116 break; |
80 break; |
117 default: |
81 default: |
118 // a debug log would spam too much |
82 // a debug log would spam too much |
119 break; |
83 break; |
120 } |
84 } |
121 [UIView commitAnimations]; |
85 if (IS_VERY_POWERFUL()) |
|
86 [UIView commitAnimations]; |
122 } |
87 } |
123 |
88 |
124 #pragma mark - |
89 #pragma mark - |
125 #pragma mark View Management |
90 #pragma mark View Management |
126 -(id) initWithCoder:(NSCoder *)aDecoder { |
91 -(id) initWithCoder:(NSCoder *)aDecoder { |
127 if ((self = [super initWithCoder:aDecoder])) { |
92 if ((self = [super initWithCoder:aDecoder])) { |
128 objcExportsInit(); |
93 objcExportsInit(); |
129 isAttacking = NO; |
94 isAttacking = NO; |
130 wasVisible = NO; |
95 isPopoverVisible = NO; |
131 isPopoverVisible = NO; // it is called "popover" even on the iphone |
96 initialScreenCount = (IS_DUALHEAD() ? 2 : 1); |
|
97 initialOrientation = 0; |
132 } |
98 } |
133 return self; |
99 return self; |
134 } |
100 } |
135 |
101 |
136 -(void) viewDidLoad { |
102 -(void) viewDidLoad { |
137 CGRect screenRect = [[UIScreen mainScreen] bounds]; |
103 CGRect screenRect = [[UIScreen mainScreen] bounds]; |
138 self.view.frame = CGRectMake(0, 0, screenRect.size.height, screenRect.size.width); |
104 self.view.frame = CGRectMake(0, 0, screenRect.size.height, screenRect.size.width); |
139 self.view.center = CGPointMake(self.view.frame.size.height/2, self.view.frame.size.width/2); |
105 self.view.center = CGPointMake(self.view.frame.size.height/2, self.view.frame.size.width/2); |
140 self.view.alpha = 0; |
|
141 |
|
142 // detrmine the quanitiy and direction of the rotation |
|
143 if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft) { |
|
144 a = 180; |
|
145 b = 0; |
|
146 } else { |
|
147 a = 0; |
|
148 b = 180; |
|
149 } |
|
150 |
|
151 // get the number of screens to know the previous state whan a display is connected or detached |
|
152 if ([UIScreen respondsToSelector:@selector(screens)]) |
|
153 initialScreenCount = [[UIScreen screens] count]; |
|
154 else |
|
155 initialScreenCount = 1; |
|
156 |
106 |
157 // set initial orientation of the controller orientation |
107 // set initial orientation of the controller orientation |
158 switch (self.interfaceOrientation) { |
108 switch (self.interfaceOrientation) { |
159 case UIDeviceOrientationLandscapeLeft: |
109 case UIDeviceOrientationLandscapeLeft: |
160 self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(90)); |
110 self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(90)); |
161 break; |
111 break; |
162 case UIDeviceOrientationLandscapeRight: |
112 case UIDeviceOrientationLandscapeRight: |
163 self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(-90)); |
113 self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(-90)); |
164 break; |
114 break; |
165 default: |
115 default: |
166 DLog(@"Nope"); |
116 DLog(@"Nope"); |
167 break; |
117 break; |
168 } |
118 } |
169 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; |
119 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; |
170 [[NSNotificationCenter defaultCenter] addObserver:self |
120 [[NSNotificationCenter defaultCenter] addObserver:self |
171 selector:@selector(dualHeadRotation:) |
121 selector:@selector(handleRotationEvent:) |
172 name:UIDeviceOrientationDidChangeNotification |
122 name:UIDeviceOrientationDidChangeNotification |
173 object:nil]; |
123 object:nil]; |
174 |
124 |
175 // the timer used to dim the overlay |
125 // the timer used to dim the overlay |
176 dimTimer = [[NSTimer alloc] initWithFireDate:(IS_DUALHEAD()) ? HIDING_TIME_NEVER : [NSDate dateWithTimeIntervalSinceNow:6] |
126 dimTimer = [[NSTimer alloc] initWithFireDate:(IS_DUALHEAD()) ? HIDING_TIME_NEVER : [NSDate dateWithTimeIntervalSinceNow:6] |
177 interval:1000 |
127 interval:1000 |
178 target:self |
128 target:self |
179 selector:@selector(dimOverlay) |
129 selector:@selector(dimOverlay) |
200 name:UIScreenDidDisconnectNotification |
150 name:UIScreenDidDisconnectNotification |
201 object:nil]; |
151 object:nil]; |
202 } |
152 } |
203 |
153 |
204 // present the overlay |
154 // present the overlay |
|
155 self.view.alpha = 0; |
205 [UIView beginAnimations:@"showing overlay" context:NULL]; |
156 [UIView beginAnimations:@"showing overlay" context:NULL]; |
206 [UIView setAnimationDuration:2]; |
157 [UIView setAnimationDuration:2]; |
207 self.view.alpha = 1; |
158 self.view.alpha = 1; |
208 [UIView commitAnimations]; |
159 [UIView commitAnimations]; |
209 } |
160 } |
210 |
161 |
211 -(void) numberOfScreensIncreased { |
162 -(void) viewDidUnload { |
212 if (initialScreenCount == 1) { |
163 [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; |
213 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"New display detected" |
164 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
214 message:NSLocalizedString(@"Hedgewars supports multi-monitor configurations, but the screen has to be connected before launching the game.",@"") |
165 |
215 delegate:nil |
166 [NSObject cancelPreviousPerformRequestsWithTarget:self |
216 cancelButtonTitle:@"Ok" |
167 selector:@selector(unsetPreciseStatus) |
217 otherButtonTitles:nil]; |
168 object:nil]; |
218 [alert show]; |
169 |
219 [alert release]; |
170 // only objects initialized in viewDidLoad should be here |
220 HW_pause(); |
171 dimTimer = nil; |
221 } |
172 self.helpPage = nil; |
222 } |
173 [self dismissPopover]; |
223 |
174 self.popoverController = nil; |
224 -(void) numberOfScreensDecreased { |
175 self.amvc = nil; |
225 if (initialScreenCount == 2) { |
176 MSG_DIDUNLOAD(); |
226 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Oh noes! Display disconnected" |
177 [super viewDidUnload]; |
227 message:NSLocalizedString(@"A monitor has been disconnected while playing and this has ended the match! You need to restart the game if you wish to use the second display again.",@"") |
|
228 delegate:nil |
|
229 cancelButtonTitle:@"Ok" |
|
230 otherButtonTitles:nil]; |
|
231 [alert show]; |
|
232 [alert release]; |
|
233 HW_terminate(NO); |
|
234 } |
|
235 } |
|
236 |
|
237 |
|
238 -(void) showHelp:(id) sender { |
|
239 if (self.helpPage == nil) { |
|
240 NSString *xibName = (IS_IPAD() ? @"HelpPageInGameViewController-iPad" : @"HelpPageInGameViewController-iPhone"); |
|
241 self.helpPage = [[HelpPageViewController alloc] initWithNibName:xibName bundle:nil]; |
|
242 } |
|
243 self.helpPage.view.alpha = 0; |
|
244 [self.view addSubview:helpPage.view]; |
|
245 [UIView beginAnimations:@"helpingame" context:NULL]; |
|
246 self.helpPage.view.alpha = 1; |
|
247 [UIView commitAnimations]; |
|
248 doNotDim(); |
|
249 } |
|
250 |
|
251 -(void) removeOverlay { |
|
252 [self.popupMenu performSelectorOnMainThread:@selector(dismiss) withObject:nil waitUntilDone:YES]; |
|
253 [self.popoverController performSelectorOnMainThread:@selector(dismissPopoverAnimated:) withObject:nil waitUntilDone:YES]; |
|
254 [self.view performSelectorOnMainThread:@selector(removeFromSuperview) withObject:nil waitUntilDone:YES]; |
|
255 } |
178 } |
256 |
179 |
257 -(void) didReceiveMemoryWarning { |
180 -(void) didReceiveMemoryWarning { |
258 if (self.popupMenu.view.superview == nil) |
181 if (self.popupMenu.view.superview == nil) |
259 self.popupMenu = nil; |
182 self.popupMenu = nil; |
267 |
190 |
268 MSG_MEMCLEAN(); |
191 MSG_MEMCLEAN(); |
269 [super didReceiveMemoryWarning]; |
192 [super didReceiveMemoryWarning]; |
270 } |
193 } |
271 |
194 |
272 -(void) viewDidUnload { |
|
273 // only objects initialized in viewDidLoad should be here |
|
274 if (IS_DUALHEAD()) |
|
275 [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; |
|
276 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
|
277 [NSObject cancelPreviousPerformRequestsWithTarget:self |
|
278 selector:@selector(unsetPreciseStatus) |
|
279 object:nil]; |
|
280 dimTimer = nil; |
|
281 self.helpPage = nil; |
|
282 [self dismissPopover]; |
|
283 self.popoverController = nil; |
|
284 self.amvc = nil; |
|
285 MSG_DIDUNLOAD(); |
|
286 [super viewDidUnload]; |
|
287 } |
|
288 |
|
289 -(void) dealloc { |
195 -(void) dealloc { |
290 [popupMenu release]; |
196 [popupMenu release]; |
291 [helpPage release]; |
197 [helpPage release]; |
292 [popoverController release]; |
198 [popoverController release]; |
293 [amvc release]; |
199 [amvc release]; |
294 // dimTimer is autoreleased |
200 // dimTimer is autoreleased |
295 [super dealloc]; |
201 [super dealloc]; |
296 } |
202 } |
297 |
203 |
|
204 -(void) numberOfScreensIncreased { |
|
205 if (self.initialScreenCount == 1) { |
|
206 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"New display detected" |
|
207 message:NSLocalizedString(@"Hedgewars supports multi-monitor configurations, but the screen has to be connected before launching the game.",@"") |
|
208 delegate:nil |
|
209 cancelButtonTitle:@"Ok" |
|
210 otherButtonTitles:nil]; |
|
211 [alert show]; |
|
212 [alert release]; |
|
213 HW_pause(); |
|
214 } |
|
215 } |
|
216 |
|
217 -(void) numberOfScreensDecreased { |
|
218 if (self.initialScreenCount == 2) { |
|
219 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Oh noes! Display disconnected" |
|
220 message:NSLocalizedString(@"A monitor has been disconnected while playing and this has ended the match! You need to restart the game if you wish to use the second display again.",@"") |
|
221 delegate:nil |
|
222 cancelButtonTitle:@"Ok" |
|
223 otherButtonTitles:nil]; |
|
224 [alert show]; |
|
225 [alert release]; |
|
226 HW_terminate(NO); |
|
227 } |
|
228 } |
|
229 |
298 #pragma mark - |
230 #pragma mark - |
299 #pragma mark overlay user interaction |
231 #pragma mark overlay appearance |
300 // nice transition for dimming, should be called only by the timer himself |
232 // nice transition for dimming, should be called only by the timer himself |
301 -(void) dimOverlay { |
233 -(void) dimOverlay { |
302 if (isGameRunning()) { |
234 if (isGameRunning()) { |
303 [UIView beginAnimations:@"overlay dim" context:NULL]; |
235 [UIView beginAnimations:@"overlay dim" context:NULL]; |
304 [UIView setAnimationDuration:0.6]; |
236 [UIView setAnimationDuration:0.6]; |