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: */