Mercurial > sdl-ios-xcode
annotate src/video/ggi/SDL_ggivideo.c @ 1643:51038e80ae59
More general fix for bug #189
The clipping is done at a higher level, and the low level functions are
passed clipped rectangles. Drivers which don't support source clipping
have not been changed, so the image will be squished instead of clipped,
but at least they will no longer crash when the destination rect was out
of bounds.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 17 Apr 2006 06:47:23 +0000 |
parents | 8d9bb0cf2c2a |
children | 782fd950bd46 c121d94672cb a1b03ba2fcd0 |
rev | line source |
---|---|
0 | 1 /* |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
2 SDL - Simple DirectMedia Layer |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
3 Copyright (C) 1997-2006 Sam Lantinga |
0 | 4 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
5 This library is free software; you can redistribute it and/or |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
6 modify it under the terms of the GNU Lesser General Public |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
7 License as published by the Free Software Foundation; either |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
8 version 2.1 of the License, or (at your option) any later version. |
0 | 9 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
10 This library is distributed in the hope that it will be useful, |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
13 Lesser General Public License for more details. |
0 | 14 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
15 You should have received a copy of the GNU Lesser General Public |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
16 License along with this library; if not, write to the Free Software |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 18 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
19 Sam Lantinga |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
20 slouken@libsdl.org |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
21 */ |
1402
d910939febfa
Use consistent identifiers for the various platforms we support.
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
22 #include "SDL_config.h" |
0 | 23 |
24 /* GGI-based SDL video driver implementation. | |
25 */ | |
26 | |
27 #include <fcntl.h> | |
28 #include <unistd.h> | |
29 #include <sys/mman.h> | |
30 | |
31 #include <ggi/ggi.h> | |
32 #include <ggi/gii.h> | |
33 | |
34 #include "SDL_video.h" | |
35 #include "SDL_mouse.h" | |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
36 #include "../SDL_sysvideo.h" |
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
37 #include "../SDL_pixels_c.h" |
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
38 #include "../../events/SDL_events_c.h" |
0 | 39 #include "SDL_ggivideo.h" |
40 #include "SDL_ggimouse_c.h" | |
41 #include "SDL_ggievents_c.h" | |
42 | |
43 | |
44 struct private_hwdata | |
45 { | |
46 ggi_visual_t vis; | |
47 }; | |
48 | |
49 ggi_visual_t VIS; | |
50 | |
51 /* Initialization/Query functions */ | |
52 static int GGI_VideoInit(_THIS, SDL_PixelFormat *vformat); | |
53 static SDL_Rect **GGI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | |
54 static SDL_Surface *GGI_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | |
55 static int GGI_SetColors(_THIS, int firstcolor, int ncolors, | |
56 SDL_Color *colors); | |
57 static void GGI_VideoQuit(_THIS); | |
58 | |
59 /* Hardware surface functions */ | |
60 static int GGI_AllocHWSurface(_THIS, SDL_Surface *surface); | |
61 static int GGI_LockHWSurface(_THIS, SDL_Surface *surface); | |
62 static void GGI_UnlockHWSurface(_THIS, SDL_Surface *surface); | |
63 static void GGI_FreeHWSurface(_THIS, SDL_Surface *surface); | |
64 | |
65 /* GGI driver bootstrap functions */ | |
66 | |
67 static int GGI_Available(void) | |
68 { | |
69 ggi_visual_t *vis; | |
17
4f22a992f5e9
Fixed crash in GGI detection
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
70 |
4f22a992f5e9
Fixed crash in GGI detection
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
71 vis = NULL; |
4f22a992f5e9
Fixed crash in GGI detection
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
72 if (ggiInit() == 0) { |
4f22a992f5e9
Fixed crash in GGI detection
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
73 vis = ggiOpen(NULL); |
4f22a992f5e9
Fixed crash in GGI detection
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
74 if (vis != NULL) { |
4f22a992f5e9
Fixed crash in GGI detection
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
75 ggiClose(vis); |
4f22a992f5e9
Fixed crash in GGI detection
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
76 } |
0 | 77 } |
78 return (vis != NULL); | |
79 } | |
80 | |
81 static void GGI_DeleteDevice(SDL_VideoDevice *device) | |
82 { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
83 SDL_free(device->hidden); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
84 SDL_free(device); |
0 | 85 } |
86 | |
87 static SDL_VideoDevice *GGI_CreateDevice(int devindex) | |
88 { | |
89 SDL_VideoDevice *device; | |
90 | |
91 /* Initialize all variables that we clean on shutdown */ | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
92 device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); |
0 | 93 if ( device ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
94 SDL_memset(device, 0, (sizeof *device)); |
0 | 95 device->hidden = (struct SDL_PrivateVideoData *) |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
96 SDL_malloc((sizeof *device->hidden)); |
0 | 97 } |
98 if ( (device == NULL) || (device->hidden == NULL) ) { | |
99 SDL_OutOfMemory(); | |
100 if ( device ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
101 SDL_free(device); |
0 | 102 } |
103 return(0); | |
104 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
105 SDL_memset(device->hidden, 0, (sizeof *device->hidden)); |
0 | 106 |
107 /* Set the function pointers */ | |
108 device->VideoInit = GGI_VideoInit; | |
109 device->ListModes = GGI_ListModes; | |
110 device->SetVideoMode = GGI_SetVideoMode; | |
111 device->SetColors = GGI_SetColors; | |
112 device->UpdateRects = NULL; | |
113 device->VideoQuit = GGI_VideoQuit; | |
114 device->AllocHWSurface = GGI_AllocHWSurface; | |
115 device->CheckHWBlit = NULL; | |
116 device->FillHWRect = NULL; | |
117 device->SetHWColorKey = NULL; | |
118 device->SetHWAlpha = NULL; | |
119 device->LockHWSurface = GGI_LockHWSurface; | |
120 device->UnlockHWSurface = GGI_UnlockHWSurface; | |
121 device->FlipHWSurface = NULL; | |
122 device->FreeHWSurface = GGI_FreeHWSurface; | |
123 device->SetCaption = NULL; | |
124 device->SetIcon = NULL; | |
125 device->IconifyWindow = NULL; | |
126 device->GrabInput = NULL; | |
127 device->GetWMInfo = NULL; | |
128 device->InitOSKeymap = GGI_InitOSKeymap; | |
129 device->PumpEvents = GGI_PumpEvents; | |
130 | |
131 device->free = GGI_DeleteDevice; | |
132 | |
133 return device; | |
134 } | |
135 | |
136 VideoBootStrap GGI_bootstrap = { | |
137 "ggi", "General Graphics Interface (GGI)", | |
138 GGI_Available, GGI_CreateDevice | |
139 }; | |
140 | |
141 | |
142 static SDL_Rect video_mode; | |
143 static SDL_Rect *SDL_modelist[4] = { NULL, NULL, NULL, NULL }; | |
144 | |
145 int GGI_VideoInit(_THIS, SDL_PixelFormat *vformat) | |
146 { | |
147 ggi_mode mode = | |
148 { | |
149 1, | |
150 { GGI_AUTO, GGI_AUTO }, | |
151 { GGI_AUTO, GGI_AUTO }, | |
152 { 0, 0 }, | |
153 GT_AUTO, | |
154 { GGI_AUTO, GGI_AUTO } | |
155 }; | |
156 struct private_hwdata *priv; | |
157 ggi_color pal[256], map[256]; | |
158 const ggi_directbuffer *db; | |
159 int err, num_bufs; | |
160 ggi_pixel white, black; | |
161 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
162 priv = SDL_malloc(sizeof(struct private_hwdata)); |
0 | 163 if (priv == NULL) |
164 { | |
165 SDL_SetError("Unhandled GGI mode type!\n"); | |
166 GGI_VideoQuit(NULL); | |
167 } | |
168 | |
169 if (ggiInit() != 0) | |
170 { | |
171 SDL_SetError("Unable to initialize GGI!\n"); | |
172 GGI_VideoQuit(NULL); | |
173 } | |
174 | |
175 VIS = ggiOpen(NULL); | |
176 if (VIS == NULL) | |
177 { | |
178 SDL_SetError("Unable to open default GGI visual!\n"); | |
179 ggiExit(); | |
180 GGI_VideoQuit(NULL); | |
181 } | |
182 | |
183 ggiSetFlags(VIS, GGIFLAG_ASYNC); | |
184 | |
185 /* Validate mode, autodetecting any GGI_AUTO or GT_AUTO fields */ | |
186 ggiCheckMode(VIS, &mode); | |
187 | |
188 /* At this point we should have a valid mode - try to set it */ | |
189 err = ggiSetMode(VIS, &mode); | |
190 | |
191 /* If we couldn't set _any_ modes, something is very wrong */ | |
192 if (err) | |
193 { | |
194 SDL_SetError("Can't set a mode!\n"); | |
195 ggiClose(VIS); | |
196 ggiExit(); | |
197 GGI_VideoQuit(NULL); | |
198 } | |
199 | |
1545
8d9bb0cf2c2a
Added current_w and current_h to the SDL_VideoInfo structure, which is set to the desktop resolution during video intialization, and then set to the current resolution when a video mode is set.
Sam Lantinga <slouken@libsdl.org>
parents:
1402
diff
changeset
|
200 /* Determine the current screen size */ |
8d9bb0cf2c2a
Added current_w and current_h to the SDL_VideoInfo structure, which is set to the desktop resolution during video intialization, and then set to the current resolution when a video mode is set.
Sam Lantinga <slouken@libsdl.org>
parents:
1402
diff
changeset
|
201 this->info.current_w = mode.virt.x; |
8d9bb0cf2c2a
Added current_w and current_h to the SDL_VideoInfo structure, which is set to the desktop resolution during video intialization, and then set to the current resolution when a video mode is set.
Sam Lantinga <slouken@libsdl.org>
parents:
1402
diff
changeset
|
202 this->info.current_h = mode.virt.y; |
8d9bb0cf2c2a
Added current_w and current_h to the SDL_VideoInfo structure, which is set to the desktop resolution during video intialization, and then set to the current resolution when a video mode is set.
Sam Lantinga <slouken@libsdl.org>
parents:
1402
diff
changeset
|
203 |
0 | 204 /* Set a palette for palletized modes */ |
205 if (GT_SCHEME(mode.graphtype) == GT_PALETTE) | |
206 { | |
207 ggiSetColorfulPalette(VIS); | |
208 ggiGetPalette(VIS, 0, 1 << vformat->BitsPerPixel, pal); | |
209 } | |
210 | |
211 /* Now we try to get the DirectBuffer info, which determines whether | |
212 * SDL can access hardware surfaces directly. */ | |
213 | |
214 num_bufs = ggiDBGetNumBuffers(VIS); | |
215 | |
216 if (num_bufs > 0) | |
217 { | |
218 db = ggiDBGetBuffer(VIS, 0); /* Only handle one DB for now */ | |
219 | |
220 vformat->BitsPerPixel = db->buffer.plb.pixelformat->depth; | |
221 | |
222 vformat->Rmask = db->buffer.plb.pixelformat->red_mask; | |
223 vformat->Gmask = db->buffer.plb.pixelformat->green_mask; | |
224 vformat->Bmask = db->buffer.plb.pixelformat->blue_mask; | |
225 | |
226 /* Fill in our hardware acceleration capabilities */ | |
227 | |
228 this->info.wm_available = 0; | |
229 this->info.hw_available = 1; | |
230 this->info.video_mem = db->buffer.plb.stride * mode.virt.y; | |
231 } | |
232 | |
233 video_mode.x = 0; | |
234 video_mode.y = 0; | |
235 video_mode.w = mode.virt.x; | |
236 video_mode.h = mode.virt.y; | |
237 SDL_modelist[((vformat->BitsPerPixel + 7) / 8) - 1] = &video_mode; | |
238 | |
239 /* We're done! */ | |
240 return(0); | |
241 } | |
242 | |
243 static SDL_Rect **GGI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | |
244 { | |
245 return(&SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1]); | |
246 } | |
247 | |
248 /* Various screen update functions available */ | |
249 static void GGI_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); | |
250 | |
251 SDL_Surface *GGI_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) | |
252 { | |
253 ggi_mode mode = | |
254 { | |
255 1, | |
256 { GGI_AUTO, GGI_AUTO }, | |
257 { GGI_AUTO, GGI_AUTO }, | |
258 { 0, 0 }, | |
259 GT_AUTO, | |
260 { GGI_AUTO, GGI_AUTO } | |
261 }; | |
262 const ggi_directbuffer *db; | |
263 ggi_color pal[256]; | |
264 int err; | |
265 | |
266 fprintf(stderr, "GGI_SetVideoMode()\n"); | |
267 | |
268 mode.visible.x = mode.virt.x = width; | |
269 mode.visible.y = mode.virt.y = height; | |
270 | |
271 /* Translate requested SDL bit depth into a GGI mode */ | |
272 switch (bpp) | |
273 { | |
274 case 1: mode.graphtype = GT_1BIT; break; | |
275 case 2: mode.graphtype = GT_2BIT; break; | |
276 case 4: mode.graphtype = GT_4BIT; break; | |
277 case 8: mode.graphtype = GT_8BIT; break; | |
278 case 15: mode.graphtype = GT_15BIT; break; | |
279 case 16: mode.graphtype = GT_16BIT; break; | |
280 case 24: mode.graphtype = GT_24BIT; break; | |
281 case 32: mode.graphtype = GT_32BIT; break; | |
282 default: | |
283 SDL_SetError("Unknown SDL bit depth, using GT_AUTO....\n"); | |
284 mode.graphtype = GT_AUTO; | |
285 } | |
286 | |
287 /* Validate mode, autodetecting any GGI_AUTO or GT_AUTO fields */ | |
288 ggiCheckMode(VIS, &mode); | |
289 | |
290 /* At this point we should have a valid mode - try to set it */ | |
291 err = ggiSetMode(VIS, &mode); | |
292 | |
293 /* If we couldn't set _any_ modes, something is very wrong */ | |
294 if (err) | |
295 { | |
296 SDL_SetError("Can't set a mode!\n"); | |
297 ggiClose(VIS); | |
298 ggiExit(); | |
299 GGI_VideoQuit(NULL); | |
300 } | |
301 | |
302 /* Set a palette for palletized modes */ | |
303 if (GT_SCHEME(mode.graphtype) == GT_PALETTE) | |
304 { | |
305 ggiSetColorfulPalette(VIS); | |
306 ggiGetPalette(VIS, 0, 1 << bpp, pal); | |
307 } | |
308 | |
309 db = ggiDBGetBuffer(VIS, 0); | |
310 | |
311 /* Set up the new mode framebuffer */ | |
312 current->flags = (SDL_FULLSCREEN | SDL_HWSURFACE); | |
313 current->w = mode.virt.x; | |
314 current->h = mode.virt.y; | |
315 current->pitch = db->buffer.plb.stride; | |
316 current->pixels = db->read; | |
317 | |
318 /* Set the blit function */ | |
319 this->UpdateRects = GGI_DirectUpdate; | |
320 | |
321 /* We're done */ | |
322 return(current); | |
323 } | |
324 | |
325 static int GGI_AllocHWSurface(_THIS, SDL_Surface *surface) | |
326 { | |
327 return(-1); | |
328 } | |
329 static void GGI_FreeHWSurface(_THIS, SDL_Surface *surface) | |
330 { | |
331 return; | |
332 } | |
333 static int GGI_LockHWSurface(_THIS, SDL_Surface *surface) | |
334 { | |
335 return(0); | |
336 } | |
337 static void GGI_UnlockHWSurface(_THIS, SDL_Surface *surface) | |
338 { | |
339 return; | |
340 } | |
341 | |
342 static void GGI_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) | |
343 { | |
344 int i; | |
345 | |
346 /* ggiFlush(VIS); */ | |
347 | |
348 for (i = 0; i < numrects; i++) | |
349 { | |
350 ggiFlushRegion(VIS, rects[i].x, rects[i].y, rects[i].w, rects[i].h); | |
351 } | |
352 return; | |
353 } | |
354 | |
355 int GGI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | |
356 { | |
357 int i; | |
358 ggi_color pal[256]; | |
359 | |
360 /* Set up the colormap */ | |
361 for (i = 0; i < ncolors; i++) | |
362 { | |
363 pal[i].r = (colors[i].r << 8) | colors[i].r; | |
364 pal[i].g = (colors[i].g << 8) | colors[i].g; | |
365 pal[i].b = (colors[i].b << 8) | colors[i].b; | |
366 } | |
367 | |
368 ggiSetPalette(VIS, firstcolor, ncolors, pal); | |
369 | |
370 return 1; | |
371 } | |
372 | |
373 void GGI_VideoQuit(_THIS) | |
374 { | |
375 } | |
376 void GGI_FinalQuit(void) | |
377 { | |
378 } |