Mercurial > sdl-ios-xcode
comparison src/video/uikit/SDL_uikitvideo.m @ 4443:c598e440c87c
Implemented display mode functionality for UIKit.
The iPad (and iPhoneOS 3.2) introduce both a larger screen and the ability to
enumerate and configure external displays. This hooks up SDL's multi-display
API to this new functionality, and removes the hardcoded iPhone resolution.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Thu, 29 Apr 2010 22:53:18 -0400 |
parents | 41253c0fa9b3 |
children | 06becafcac89 |
comparison
equal
deleted
inserted
replaced
4441:e3033ab628a1 | 4443:c598e440c87c |
---|---|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
18 | 18 |
19 Sam Lantinga | 19 Sam Lantinga |
20 slouken@libsdl.org | 20 slouken@libsdl.org |
21 */ | 21 */ |
22 | |
23 #import <UIKit/UIKit.h> | |
24 | |
22 #include "SDL_config.h" | 25 #include "SDL_config.h" |
23 | 26 |
24 #include "SDL_video.h" | 27 #include "SDL_video.h" |
25 #include "SDL_mouse.h" | 28 #include "SDL_mouse.h" |
26 #include "../SDL_sysvideo.h" | 29 #include "../SDL_sysvideo.h" |
33 #include "SDL_uikitopengles.h" | 36 #include "SDL_uikitopengles.h" |
34 | 37 |
35 #include "SDL_renderer_sw.h" | 38 #include "SDL_renderer_sw.h" |
36 #include "SDL_renderer_gles.h" | 39 #include "SDL_renderer_gles.h" |
37 | 40 |
41 #include "SDL_assert.h" | |
42 | |
38 #define UIKITVID_DRIVER_NAME "uikit" | 43 #define UIKITVID_DRIVER_NAME "uikit" |
39 | 44 |
40 /* Initialization/Query functions */ | 45 /* Initialization/Query functions */ |
41 static int UIKit_VideoInit(_THIS); | 46 static int UIKit_VideoInit(_THIS); |
47 static void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display); | |
42 static int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, | 48 static int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, |
43 SDL_DisplayMode * mode); | 49 SDL_DisplayMode * mode); |
44 static void UIKit_VideoQuit(_THIS); | 50 static void UIKit_VideoQuit(_THIS); |
51 | |
52 static BOOL supports_multiple_displays = NO; | |
45 | 53 |
46 /* DUMMY driver bootstrap functions */ | 54 /* DUMMY driver bootstrap functions */ |
47 | 55 |
48 static int | 56 static int |
49 UIKit_Available(void) | 57 UIKit_Available(void) |
72 } | 80 } |
73 | 81 |
74 /* Set the function pointers */ | 82 /* Set the function pointers */ |
75 device->VideoInit = UIKit_VideoInit; | 83 device->VideoInit = UIKit_VideoInit; |
76 device->VideoQuit = UIKit_VideoQuit; | 84 device->VideoQuit = UIKit_VideoQuit; |
85 device->GetDisplayModes = UIKit_GetDisplayModes; | |
77 device->SetDisplayMode = UIKit_SetDisplayMode; | 86 device->SetDisplayMode = UIKit_SetDisplayMode; |
78 device->PumpEvents = UIKit_PumpEvents; | 87 device->PumpEvents = UIKit_PumpEvents; |
79 device->CreateWindow = UIKit_CreateWindow; | 88 device->CreateWindow = UIKit_CreateWindow; |
80 device->DestroyWindow = UIKit_DestroyWindow; | 89 device->DestroyWindow = UIKit_DestroyWindow; |
81 | 90 |
98 UIKITVID_DRIVER_NAME, "SDL UIKit video driver", | 107 UIKITVID_DRIVER_NAME, "SDL UIKit video driver", |
99 UIKit_Available, UIKit_CreateDevice | 108 UIKit_Available, UIKit_CreateDevice |
100 }; | 109 }; |
101 | 110 |
102 | 111 |
112 /* | |
113 !!! FIXME: | |
114 | |
115 The main screen should list a AxB mode for portrait orientation, and then | |
116 also list BxA for landscape mode. When setting a given resolution, we should | |
117 rotate the view's transform appropriately (extra credit if you check the | |
118 accelerometer and rotate the display so it's never upside down). | |
119 | |
120 http://iphonedevelopment.blogspot.com/2008/10/starting-in-landscape-mode-without.html | |
121 | |
122 */ | |
123 | |
124 static void | |
125 UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display) | |
126 { | |
127 const UIScreen *screen = (UIScreen *) display->driverdata; | |
128 SDL_DisplayMode mode; | |
129 SDL_zero(mode); | |
130 | |
131 // availableModes showed up in 3.2 (the iPad and later). We should only | |
132 // land here for at least that version of the OS. | |
133 if (!supports_multiple_displays) { | |
134 const CGRect rect = [screen bounds]; | |
135 mode.format = SDL_PIXELFORMAT_ABGR8888; | |
136 mode.w = (int) rect.size.width; | |
137 mode.h = (int) rect.size.height; | |
138 mode.refresh_rate = 0; | |
139 mode.driverdata = NULL; | |
140 SDL_AddDisplayMode(display, &mode); | |
141 return; | |
142 } | |
143 | |
144 const NSArray *modes = [screen availableModes]; | |
145 const NSUInteger mode_count = [modes count]; | |
146 NSUInteger i; | |
147 for (i = 0; i < mode_count; i++) { | |
148 UIScreenMode *uimode = (UIScreenMode *) [modes objectAtIndex:i]; | |
149 const CGSize size = [uimode size]; | |
150 mode.format = SDL_PIXELFORMAT_ABGR8888; | |
151 mode.w = (int) size.width; | |
152 mode.h = (int) size.height; | |
153 mode.refresh_rate = 0; | |
154 mode.driverdata = uimode; | |
155 [uimode retain]; | |
156 SDL_AddDisplayMode(display, &mode); | |
157 } | |
158 } | |
159 | |
160 | |
161 static void | |
162 UIKit_AddDisplay(UIScreen *screen, int w, int h) | |
163 { | |
164 SDL_VideoDisplay display; | |
165 SDL_DisplayMode mode; | |
166 | |
167 SDL_zero(mode); | |
168 mode.format = SDL_PIXELFORMAT_ABGR8888; | |
169 mode.w = w; | |
170 mode.h = h; | |
171 mode.refresh_rate = 0; | |
172 | |
173 SDL_zero(display); | |
174 display.desktop_mode = mode; | |
175 display.current_mode = mode; | |
176 display.driverdata = screen; | |
177 [screen retain]; | |
178 SDL_AddVideoDisplay(&display); | |
179 } | |
180 | |
181 | |
103 int | 182 int |
104 UIKit_VideoInit(_THIS) | 183 UIKit_VideoInit(_THIS) |
105 { | 184 { |
106 SDL_DisplayMode mode; | 185 _this->gl_config.driver_loaded = 1; |
107 | 186 |
108 _this->gl_config.driver_loaded = 1; | 187 const float version = [[[UIDevice currentDevice] systemVersion] floatValue]; |
109 | 188 supports_multiple_displays = (version >= 3.2f); |
110 SDL_VideoDisplay display; | 189 |
111 SDL_zero(display); | 190 // If this is iPhoneOS < 3.2, all devices are one screen, 320x480 pixels. |
112 | 191 // The iPad added both a larger main screen and the ability to use |
113 /* Use a 32-bpp desktop mode */ | 192 // external displays. |
114 SDL_zero(mode); | 193 if (!supports_multiple_displays) { |
115 mode.format = SDL_PIXELFORMAT_ABGR8888; | 194 // Just give 'em the whole main screen. |
116 mode.w = 320; | 195 UIScreen *screen = [UIScreen mainScreen]; |
117 mode.h = 480; | 196 const CGRect rect = [screen bounds]; |
118 mode.refresh_rate = 0; | 197 UIKit_AddDisplay(screen, (int)rect.size.width, (int)rect.size.height); |
119 mode.driverdata = NULL; | 198 } else { |
120 | 199 const NSArray *screens = [UIScreen screens]; |
121 display.num_display_modes = 1; | 200 const NSUInteger screen_count = [screens count]; |
122 display.max_display_modes = 1; | 201 NSUInteger i; |
123 display.display_modes = (SDL_DisplayMode *)SDL_malloc(display.max_display_modes * sizeof(SDL_DisplayMode)); | 202 for (i = 0; i < screen_count; i++) { |
124 | 203 // the main screen is the first element in the array. |
125 display.display_modes[0] = mode; | 204 UIScreen *screen = (UIScreen *) [screens objectAtIndex:i]; |
126 display.desktop_mode = mode; | 205 const CGSize size = [[screen currentMode] size]; |
127 display.current_mode = mode; | 206 UIKit_AddDisplay(screen, (int) size.width, (int) size.height); |
128 | 207 } |
129 SDL_AddVideoDisplay(&display); | 208 } |
130 | 209 |
131 /* We're done! */ | 210 /* We're done! */ |
132 return 0; | 211 return 0; |
133 } | 212 } |
134 | 213 |
135 static int | 214 static int |
136 UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) | 215 UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) |
137 { | 216 { |
217 UIScreen *screen = (UIScreen *) display->driverdata; | |
218 if (!supports_multiple_displays) { | |
219 // Not on at least iPhoneOS 3.2 (versions prior to iPad). | |
220 SDL_assert(mode->driverdata == NULL); | |
221 } else { | |
222 UIScreenMode *uimode = (UIScreenMode *) mode->driverdata; | |
223 [screen setCurrentMode:uimode]; | |
224 } | |
225 | |
138 return 0; | 226 return 0; |
139 } | 227 } |
140 | 228 |
141 void | 229 void |
142 UIKit_VideoQuit(_THIS) | 230 UIKit_VideoQuit(_THIS) |
143 { | 231 { |
232 // Release Objective-C objects, so higher level doesn't free() them. | |
233 int i, j; | |
234 for (i = 0; i < _this->num_displays; i++) { | |
235 SDL_VideoDisplay *display = &_this->displays[i]; | |
236 UIScreen *screen = (UIScreen *) display->driverdata; | |
237 [((UIScreen *) display->driverdata) release]; | |
238 display->driverdata = NULL; | |
239 for (j = 0; j < display->num_display_modes; j++) { | |
240 SDL_DisplayMode *mode = &display->display_modes[j]; | |
241 UIScreenMode *uimode = (UIScreenMode *) mode->driverdata; | |
242 if (uimode) { | |
243 [uimode release]; | |
244 mode->driverdata = NULL; | |
245 } | |
246 } | |
247 } | |
144 } | 248 } |
145 | 249 |
146 /* vi: set ts=4 sw=4 expandtab: */ | 250 /* vi: set ts=4 sw=4 expandtab: */ |