rev |
line source |
nuclear@2
|
1 #include <stdlib.h>
|
nuclear@2
|
2 #import <OpenGLES/ES2/glext.h>
|
nuclear@0
|
3 #import "viewctl.h"
|
nuclear@2
|
4 #include "istereo.h"
|
nuclear@0
|
5
|
nuclear@0
|
6 @interface ViewController () {
|
nuclear@0
|
7 EAGLContext *ctx;
|
nuclear@16
|
8 float pixel_scale, max_pixel_scale, low_pixel_scale;
|
nuclear@1
|
9
|
nuclear@5
|
10 GLKView *glview;
|
nuclear@1
|
11 ADBannerView *ad;
|
nuclear@1
|
12 BOOL ad_visible;
|
nuclear@16
|
13 BOOL ad_ready;
|
nuclear@16
|
14
|
nuclear@16
|
15 int ios_ver_major, ios_ver_minor;
|
nuclear@16
|
16 BOOL landscape_swap;
|
nuclear@0
|
17 }
|
nuclear@0
|
18
|
nuclear@1
|
19
|
nuclear@1
|
20 - (void)create_ad;
|
nuclear@2
|
21 - (void)show_ad;
|
nuclear@2
|
22 - (void)hide_ad;
|
nuclear@1
|
23
|
nuclear@1
|
24 - (void)init_gl;
|
nuclear@1
|
25 - (void)destroy_gl;
|
nuclear@16
|
26
|
nuclear@16
|
27 - (void)enable_retina;
|
nuclear@16
|
28 - (void)disable_retina;
|
nuclear@16
|
29 - (BOOL)is_retina_enabled;
|
nuclear@16
|
30 - (BOOL)have_retina;
|
nuclear@0
|
31 @end
|
nuclear@0
|
32
|
nuclear@16
|
33 static ViewController *view_ctl;
|
nuclear@16
|
34 static BOOL ad_show_requested;
|
nuclear@16
|
35
|
nuclear@16
|
36 void ad_banner_show(void)
|
nuclear@16
|
37 {
|
nuclear@16
|
38 if(view_ctl) {
|
nuclear@16
|
39 [view_ctl show_ad];
|
nuclear@16
|
40 }
|
nuclear@16
|
41 ad_show_requested = YES;
|
nuclear@16
|
42 }
|
nuclear@16
|
43
|
nuclear@16
|
44 void ad_banner_hide(void)
|
nuclear@16
|
45 {
|
nuclear@16
|
46 if(view_ctl) {
|
nuclear@16
|
47 [view_ctl hide_ad];
|
nuclear@16
|
48 }
|
nuclear@16
|
49 ad_show_requested = NO;
|
nuclear@16
|
50 }
|
nuclear@16
|
51
|
nuclear@16
|
52 void use_retina_res(int enable)
|
nuclear@16
|
53 {
|
nuclear@16
|
54 if(enable) {
|
nuclear@16
|
55 [view_ctl enable_retina];
|
nuclear@16
|
56 } else {
|
nuclear@16
|
57 [view_ctl disable_retina];
|
nuclear@16
|
58 }
|
nuclear@16
|
59 }
|
nuclear@16
|
60
|
nuclear@16
|
61 int using_retina_res(void)
|
nuclear@16
|
62 {
|
nuclear@16
|
63 return [view_ctl is_retina_enabled] ? 1 : 0;
|
nuclear@16
|
64 }
|
nuclear@16
|
65
|
nuclear@16
|
66 int have_retina(void)
|
nuclear@16
|
67 {
|
nuclear@16
|
68 if(view_ctl) {
|
nuclear@16
|
69 return [view_ctl have_retina] ? 1 : 0;
|
nuclear@16
|
70 }
|
nuclear@16
|
71 return 0;
|
nuclear@16
|
72 }
|
nuclear@16
|
73
|
nuclear@16
|
74
|
nuclear@0
|
75 @implementation ViewController
|
nuclear@0
|
76
|
nuclear@0
|
77 - (void)viewDidLoad
|
nuclear@0
|
78 {
|
nuclear@0
|
79 [super viewDidLoad];
|
nuclear@0
|
80
|
nuclear@16
|
81 view_ctl = self;
|
nuclear@16
|
82
|
nuclear@16
|
83 NSString *str = [[UIDevice currentDevice] systemVersion];
|
nuclear@16
|
84 if(sscanf(str.UTF8String, "%d.%d", &ios_ver_major, &ios_ver_minor) != 2) {
|
nuclear@16
|
85 ios_ver_major = 8;
|
nuclear@16
|
86 ios_ver_minor = 0;
|
nuclear@16
|
87 }
|
nuclear@16
|
88 printf("iOS version: %d.%d\n", ios_ver_major, ios_ver_minor);
|
nuclear@16
|
89
|
nuclear@16
|
90 // in iOS versions before 8, the view size and event coordinates are swapped in landscape
|
nuclear@16
|
91 if((int)NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_8_0) {
|
nuclear@16
|
92 assert(ios_ver_major < 8);
|
nuclear@16
|
93 landscape_swap = YES;
|
nuclear@16
|
94 } else {
|
nuclear@16
|
95 landscape_swap = NO;
|
nuclear@16
|
96 }
|
nuclear@3
|
97
|
nuclear@0
|
98 self->ctx = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
|
nuclear@0
|
99 if(!self->ctx) {
|
nuclear@0
|
100 NSLog(@"Failed to create OpenGL ES 2.0 context");
|
nuclear@0
|
101 }
|
nuclear@0
|
102
|
nuclear@5
|
103 glview = (GLKView*)self.view;
|
nuclear@5
|
104 glview.context = self->ctx;
|
nuclear@5
|
105 glview.drawableDepthFormat = GLKViewDrawableDepthFormat24;
|
nuclear@0
|
106
|
nuclear@5
|
107 if([glview respondsToSelector: NSSelectorFromString(@"contentScaleFactor")]) {
|
nuclear@16
|
108 max_pixel_scale = [[UIScreen mainScreen] scale];
|
nuclear@16
|
109 printf("max pixel scale: %g\n", pixel_scale);
|
nuclear@3
|
110 } else {
|
nuclear@16
|
111 max_pixel_scale = 1.0f;
|
nuclear@3
|
112 }
|
nuclear@16
|
113 low_pixel_scale = 1.0f;
|
nuclear@16
|
114 [self disable_retina]; // default to non-retina mode
|
nuclear@3
|
115
|
nuclear@1
|
116 [self create_ad];
|
nuclear@1
|
117
|
nuclear@1
|
118 [self init_gl];
|
nuclear@0
|
119 }
|
nuclear@0
|
120
|
nuclear@0
|
121 - (void)dealloc
|
nuclear@0
|
122 {
|
nuclear@16
|
123 view_ctl = nil;
|
nuclear@16
|
124
|
nuclear@1
|
125 [self destroy_gl];
|
nuclear@0
|
126
|
nuclear@0
|
127 if([EAGLContext currentContext] == self->ctx) {
|
nuclear@0
|
128 [EAGLContext setCurrentContext: nil];
|
nuclear@0
|
129 }
|
nuclear@0
|
130 }
|
nuclear@0
|
131
|
nuclear@0
|
132 - (void)didReceiveMemoryWarning
|
nuclear@0
|
133 {
|
nuclear@0
|
134 [super didReceiveMemoryWarning];
|
nuclear@0
|
135
|
nuclear@0
|
136 if([self isViewLoaded] && ([[self view] window] == nil)) {
|
nuclear@0
|
137 self.view = nil;
|
nuclear@0
|
138
|
nuclear@1
|
139 [self destroy_gl];
|
nuclear@0
|
140
|
nuclear@0
|
141 if([EAGLContext currentContext] == self->ctx) {
|
nuclear@0
|
142 [EAGLContext setCurrentContext: nil];
|
nuclear@0
|
143 }
|
nuclear@0
|
144 self->ctx = nil;
|
nuclear@0
|
145 }
|
nuclear@0
|
146
|
nuclear@0
|
147 // Dispose of any resources that can be recreated.
|
nuclear@0
|
148 }
|
nuclear@0
|
149
|
nuclear@0
|
150 - (BOOL)prefersStatusBarHidden
|
nuclear@0
|
151 {
|
nuclear@0
|
152 return YES;
|
nuclear@0
|
153 }
|
nuclear@0
|
154
|
nuclear@4
|
155 - (BOOL)shouldAutorotate
|
nuclear@4
|
156 {
|
nuclear@4
|
157 return YES;
|
nuclear@4
|
158 }
|
nuclear@4
|
159
|
nuclear@4
|
160 - (UIInterfaceOrientationMask)supportedInterfaceOrientations
|
nuclear@4
|
161 {
|
nuclear@4
|
162 return UIInterfaceOrientationMaskLandscape;
|
nuclear@4
|
163 //return UIInterfaceOrientationMaskAll;
|
nuclear@4
|
164 }
|
nuclear@4
|
165
|
nuclear@1
|
166 - (void)create_ad
|
nuclear@1
|
167 {
|
nuclear@1
|
168 ad = [[ADBannerView alloc] initWithAdType: ADAdTypeBanner];
|
nuclear@16
|
169 CGRect rect = ad.frame;
|
nuclear@16
|
170 rect.size.width = glview.bounds.size.width;
|
nuclear@16
|
171 ad.frame = rect;
|
nuclear@1
|
172 [ad setAutoresizingMask: UIViewAutoresizingFlexibleWidth];
|
nuclear@16
|
173
|
nuclear@2
|
174 ad_visible = YES;
|
nuclear@16
|
175 ad_ready = NO;
|
nuclear@2
|
176 [self hide_ad];
|
nuclear@5
|
177 [glview addSubview: ad];
|
nuclear@1
|
178 ad.delegate = self;
|
nuclear@1
|
179 }
|
nuclear@1
|
180
|
nuclear@2
|
181 - (void)show_ad
|
nuclear@1
|
182 {
|
nuclear@16
|
183 if(!ad_visible && ad_ready) {
|
nuclear@1
|
184 CGRect rect = ad.frame;
|
nuclear@1
|
185 rect.origin.y = 0;
|
nuclear@1
|
186 ad.frame = rect;
|
nuclear@1
|
187 ad_visible = YES;
|
nuclear@1
|
188 }
|
nuclear@1
|
189 }
|
nuclear@1
|
190
|
nuclear@2
|
191 - (void)hide_ad
|
nuclear@2
|
192 {
|
nuclear@2
|
193 if(ad_visible) {
|
nuclear@2
|
194 ad.frame = CGRectOffset(ad.frame, 0, -ad.frame.size.height);
|
nuclear@2
|
195 ad_visible = NO;
|
nuclear@2
|
196 }
|
nuclear@2
|
197 }
|
nuclear@2
|
198
|
nuclear@2
|
199 - (void)init_gl
|
nuclear@2
|
200 {
|
nuclear@2
|
201 [EAGLContext setCurrentContext: self->ctx];
|
nuclear@2
|
202
|
nuclear@2
|
203 if(init() == -1) {
|
nuclear@2
|
204 NSLog(@"app initialization failed");
|
nuclear@2
|
205 exit(0);
|
nuclear@2
|
206 }
|
nuclear@2
|
207 }
|
nuclear@2
|
208
|
nuclear@2
|
209 - (void)destroy_gl
|
nuclear@2
|
210 {
|
nuclear@2
|
211 cleanup();
|
nuclear@2
|
212 [EAGLContext setCurrentContext: self->ctx];
|
nuclear@2
|
213 }
|
nuclear@2
|
214
|
nuclear@16
|
215 - (void)enable_retina
|
nuclear@16
|
216 {
|
nuclear@16
|
217 pixel_scale = max_pixel_scale;
|
nuclear@16
|
218 printf("enable_retina setting pixel scale: %g\n", pixel_scale);
|
nuclear@16
|
219 glview.contentScaleFactor = pixel_scale;
|
nuclear@16
|
220 [glview setNeedsLayout];
|
nuclear@16
|
221 }
|
nuclear@16
|
222
|
nuclear@16
|
223 - (void)disable_retina
|
nuclear@16
|
224 {
|
nuclear@16
|
225 pixel_scale = low_pixel_scale;
|
nuclear@16
|
226 printf("disable_retina setting pixel scale: %g\n", pixel_scale);
|
nuclear@16
|
227 glview.contentScaleFactor = pixel_scale;
|
nuclear@16
|
228 [glview setNeedsLayout];
|
nuclear@16
|
229 }
|
nuclear@16
|
230
|
nuclear@16
|
231 - (BOOL)is_retina_enabled
|
nuclear@16
|
232 {
|
nuclear@16
|
233 return pixel_scale > low_pixel_scale;
|
nuclear@16
|
234 }
|
nuclear@16
|
235
|
nuclear@16
|
236 - (BOOL)have_retina
|
nuclear@16
|
237 {
|
nuclear@16
|
238 return max_pixel_scale > 1.0;
|
nuclear@16
|
239 }
|
nuclear@16
|
240
|
nuclear@2
|
241
|
nuclear@2
|
242 - (void)glkView: (GLKView*)view drawInRect: (CGRect)rect
|
nuclear@2
|
243 {
|
nuclear@2
|
244 redraw();
|
nuclear@2
|
245 }
|
nuclear@2
|
246
|
nuclear@2
|
247 - (void)viewDidLayoutSubviews
|
nuclear@2
|
248 {
|
nuclear@2
|
249 CGRect rect = self.view.frame;
|
nuclear@3
|
250 int xsz = rect.size.width * pixel_scale;
|
nuclear@3
|
251 int ysz = rect.size.height * pixel_scale;
|
nuclear@16
|
252
|
nuclear@16
|
253 BOOL is_landscape = UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
|
nuclear@16
|
254 if(is_landscape && landscape_swap) {
|
nuclear@16
|
255 int tmp = xsz;
|
nuclear@16
|
256 xsz = ysz;
|
nuclear@16
|
257 ysz = tmp;
|
nuclear@16
|
258 }
|
nuclear@16
|
259
|
nuclear@3
|
260 reshape(xsz, ysz);
|
nuclear@3
|
261 printf("viewport %dx%d (scale: %g)\n", xsz, ysz, pixel_scale);
|
nuclear@2
|
262 }
|
nuclear@2
|
263
|
nuclear@6
|
264 - (void)touchesBegan: (NSSet<UITouch*>*)touches withEvent: (UIEvent*)event
|
nuclear@6
|
265 {
|
nuclear@6
|
266 UITouch *touch = [touches anyObject];
|
nuclear@16
|
267 CGPoint pt = [touch locationInView: glview];
|
nuclear@16
|
268 int x = (int)(pt.x * pixel_scale);
|
nuclear@16
|
269 int y = (int)(pt.y * pixel_scale);
|
nuclear@16
|
270
|
nuclear@16
|
271 mouse_button(0, 1, x, y);
|
nuclear@6
|
272 }
|
nuclear@6
|
273
|
nuclear@6
|
274 - (void)touchesMoved: (NSSet<UITouch*>*)touches withEvent: (UIEvent*)event
|
nuclear@6
|
275 {
|
nuclear@6
|
276 UITouch *touch = [touches anyObject];
|
nuclear@16
|
277 CGPoint pt = [touch locationInView: glview];
|
nuclear@16
|
278 int x = (int)(pt.x * pixel_scale);
|
nuclear@16
|
279 int y = (int)(pt.y * pixel_scale);
|
nuclear@16
|
280
|
nuclear@16
|
281 mouse_motion(x, y);
|
nuclear@6
|
282 }
|
nuclear@6
|
283
|
nuclear@6
|
284 - (void)touchesEnded: (NSSet<UITouch*>*)touches withEvent: (UIEvent*)event
|
nuclear@6
|
285 {
|
nuclear@6
|
286 UITouch *touch = [touches anyObject];
|
nuclear@16
|
287 CGPoint pt = [touch locationInView: glview];
|
nuclear@16
|
288 int x = (int)(pt.x * pixel_scale);
|
nuclear@16
|
289 int y = (int)(pt.y * pixel_scale);
|
nuclear@16
|
290
|
nuclear@16
|
291 mouse_button(0, 0, x, y);
|
nuclear@16
|
292 printf("touch release %d %d\n", x, y);
|
nuclear@6
|
293 }
|
nuclear@6
|
294
|
nuclear@6
|
295 - (void)touchesCancelled: (NSSet<UITouch*>*)touches withEvent: (UIEvent*)event
|
nuclear@6
|
296 {
|
nuclear@6
|
297 UITouch *touch = [touches anyObject];
|
nuclear@16
|
298 CGPoint pt = [touch locationInView: glview];
|
nuclear@16
|
299 int x = (int)(pt.x * pixel_scale);
|
nuclear@16
|
300 int y = (int)(pt.y * pixel_scale);
|
nuclear@16
|
301
|
nuclear@16
|
302 mouse_button(0, 0, x, y);
|
nuclear@6
|
303 }
|
nuclear@6
|
304
|
nuclear@2
|
305 // ADBannerDelegate functions
|
nuclear@2
|
306
|
nuclear@2
|
307 - (void)bannerViewDidLoadAd: (ADBannerView*)banner
|
nuclear@2
|
308 {
|
nuclear@16
|
309 ad_ready = YES;
|
nuclear@16
|
310 if(ad_show_requested) {
|
nuclear@16
|
311 [self show_ad];
|
nuclear@16
|
312 }
|
nuclear@2
|
313 }
|
nuclear@2
|
314
|
nuclear@1
|
315 - (void)bannerView: (ADBannerView*)banner didFailToReceiveAdWithError: (NSError*)error
|
nuclear@1
|
316 {
|
nuclear@16
|
317 ad_ready = NO;
|
nuclear@2
|
318 [self hide_ad];
|
nuclear@1
|
319
|
nuclear@1
|
320 NSLog(@"Failed to retrieve ad");
|
nuclear@1
|
321 }
|
nuclear@1
|
322
|
nuclear@1
|
323
|
nuclear@0
|
324 @end /* implementation ViewController */
|