Mercurial > sdl-ios-xcode
annotate src/video/wscons/SDL_wsconsvideo.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 | 56f952883795 |
children | 782fd950bd46 c121d94672cb a1b03ba2fcd0 |
rev | line source |
---|---|
1187 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1187
diff
changeset
|
3 Copyright (C) 1997-2006 Sam Lantinga |
1187 | 4 |
5 This library is free software; you can redistribute it and/or | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1187
diff
changeset
|
6 modify it under the terms of the GNU Lesser General Public |
1187 | 7 License as published by the Free Software Foundation; either |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1187
diff
changeset
|
8 version 2.1 of the License, or (at your option) any later version. |
1187 | 9 |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1187
diff
changeset
|
13 Lesser General Public License for more details. |
1187 | 14 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1187
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:
1187
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:
1187
diff
changeset
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
1187 | 18 |
19 Sam Lantinga | |
20 slouken@libsdl.org | |
21 */ | |
1402
d910939febfa
Use consistent identifiers for the various platforms we support.
Sam Lantinga <slouken@libsdl.org>
parents:
1383
diff
changeset
|
22 #include "SDL_config.h" |
1187 | 23 |
24 #include <sys/time.h> | |
25 #include <sys/mman.h> | |
26 #include <sys/ioctl.h> | |
27 #include <dev/wscons/wsdisplay_usl_io.h> | |
28 #include <fcntl.h> | |
29 #include <unistd.h> | |
30 #include <errno.h> | |
31 | |
32 #include "SDL_video.h" | |
33 #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
|
34 #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
|
35 #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
|
36 #include "../../events/SDL_events_c.h" |
1187 | 37 |
38 #include "SDL_wsconsvideo.h" | |
39 #include "SDL_wsconsevents_c.h" | |
40 #include "SDL_wsconsmouse_c.h" | |
41 | |
42 #define WSCONSVID_DRIVER_NAME "wscons" | |
43 enum { | |
44 WSCONS_ROTATE_NONE = 0, | |
45 WSCONS_ROTATE_CCW = 90, | |
46 WSCONS_ROTATE_UD = 180, | |
47 WSCONS_ROTATE_CW = 270 | |
48 }; | |
49 | |
50 #define min(a,b) ((a)<(b)?(a):(b)) | |
51 | |
52 /* Initialization/Query functions */ | |
53 static int WSCONS_VideoInit(_THIS, SDL_PixelFormat *vformat); | |
54 static SDL_Rect **WSCONS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | |
55 static SDL_Surface *WSCONS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | |
56 static int WSCONS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); | |
57 static void WSCONS_VideoQuit(_THIS); | |
58 | |
59 /* Hardware surface functions */ | |
60 static int WSCONS_AllocHWSurface(_THIS, SDL_Surface *surface); | |
61 static int WSCONS_LockHWSurface(_THIS, SDL_Surface *surface); | |
62 static void WSCONS_UnlockHWSurface(_THIS, SDL_Surface *surface); | |
63 static void WSCONS_FreeHWSurface(_THIS, SDL_Surface *surface); | |
64 | |
65 /* etc. */ | |
66 static WSCONS_bitBlit WSCONS_blit16; | |
67 static WSCONS_bitBlit WSCONS_blit16blocked; | |
68 static void WSCONS_UpdateRects(_THIS, int numrects, SDL_Rect *rects); | |
69 | |
70 void WSCONS_ReportError(char *fmt, ...) | |
71 { | |
72 char message[200]; | |
1596
56f952883795
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
1545
diff
changeset
|
73 va_list vaArgs; |
1187 | 74 |
75 message[199] = '\0'; | |
76 | |
77 va_start(vaArgs, fmt); | |
78 vsnprintf(message, 199, fmt, vaArgs); | |
79 va_end(vaArgs); | |
80 | |
81 SDL_SetError(message); | |
82 fprintf(stderr, "WSCONS error: %s\n", message); | |
83 } | |
84 | |
85 /* WSCONS driver bootstrap functions */ | |
86 | |
87 static int WSCONS_Available(void) | |
88 { | |
89 return 1; | |
90 } | |
91 | |
92 static void WSCONS_DeleteDevice(SDL_VideoDevice *device) | |
93 { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
94 SDL_free(device->hidden); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
95 SDL_free(device); |
1187 | 96 } |
97 | |
98 static SDL_VideoDevice *WSCONS_CreateDevice(int devindex) | |
99 { | |
100 SDL_VideoDevice *device; | |
101 | |
102 /* 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
|
103 device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); |
1187 | 104 if (device == NULL) { |
105 SDL_OutOfMemory(); | |
106 return 0; | |
107 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
108 SDL_memset(device, 0, (sizeof *device)); |
1187 | 109 device->hidden = |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
110 (struct SDL_PrivateVideoData *)SDL_malloc((sizeof *device->hidden)); |
1187 | 111 if (device->hidden == NULL) { |
112 SDL_OutOfMemory(); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
113 SDL_free(device); |
1187 | 114 return(0); |
115 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
116 SDL_memset(device->hidden, 0, (sizeof *device->hidden)); |
1187 | 117 device->hidden->fd = -1; |
118 | |
119 /* Set the function pointers */ | |
120 device->VideoInit = WSCONS_VideoInit; | |
121 device->ListModes = WSCONS_ListModes; | |
122 device->SetVideoMode = WSCONS_SetVideoMode; | |
123 device->SetColors = WSCONS_SetColors; | |
124 device->UpdateRects = WSCONS_UpdateRects; | |
125 device->VideoQuit = WSCONS_VideoQuit; | |
126 device->AllocHWSurface = WSCONS_AllocHWSurface; | |
127 device->LockHWSurface = WSCONS_LockHWSurface; | |
128 device->UnlockHWSurface = WSCONS_UnlockHWSurface; | |
129 device->FreeHWSurface = WSCONS_FreeHWSurface; | |
130 device->InitOSKeymap = WSCONS_InitOSKeymap; | |
131 device->PumpEvents = WSCONS_PumpEvents; | |
132 device->free = WSCONS_DeleteDevice; | |
133 | |
134 return device; | |
135 } | |
136 | |
137 VideoBootStrap WSCONS_bootstrap = { | |
138 WSCONSVID_DRIVER_NAME, | |
139 "SDL wscons video driver", | |
140 WSCONS_Available, | |
141 WSCONS_CreateDevice | |
142 }; | |
143 | |
144 #define WSCONSDEV_FORMAT "/dev/ttyC%01x" | |
145 | |
146 int WSCONS_VideoInit(_THIS, SDL_PixelFormat *vformat) | |
147 { | |
148 char devnamebuf[30]; | |
149 char *devname; | |
150 char *rotation; | |
151 int wstype; | |
152 int wsmode = WSDISPLAYIO_MODE_DUMBFB; | |
153 size_t len, mapsize; | |
154 int pagemask; | |
155 int width, height; | |
156 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
157 devname = SDL_getenv("SDL_WSCONSDEV"); |
1187 | 158 if (devname == NULL) { |
159 int activeVT; | |
160 if (ioctl(STDIN_FILENO, VT_GETACTIVE, &activeVT) == -1) { | |
161 WSCONS_ReportError("Unable to determine active terminal: %s", | |
162 strerror(errno)); | |
163 return -1; | |
164 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
165 SDL_snprintf(devnamebuf, sizeof(devnamebuf), WSCONSDEV_FORMAT, activeVT - 1); |
1187 | 166 devname = devnamebuf; |
167 } | |
168 | |
169 private->fd = open(devname, O_RDWR | O_NONBLOCK, 0); | |
170 if (private->fd == -1) { | |
171 WSCONS_ReportError("open %s: %s", devname, strerror(errno)); | |
172 return -1; | |
173 } | |
174 if (ioctl(private->fd, WSDISPLAYIO_GINFO, &private->info) == -1) { | |
175 WSCONS_ReportError("ioctl WSDISPLAY_GINFO: %s", strerror(errno)); | |
176 return -1; | |
177 } | |
178 if (ioctl(private->fd, WSDISPLAYIO_GTYPE, &wstype) == -1) { | |
179 WSCONS_ReportError("ioctl WSDISPLAY_GTYPE: %s", strerror(errno)); | |
180 return -1; | |
181 } | |
182 if (ioctl(private->fd, WSDISPLAYIO_LINEBYTES, &private->physlinebytes) == -1) { | |
183 WSCONS_ReportError("ioctl WSDISPLAYIO_LINEBYTES: %s", strerror(errno)); | |
184 return -1; | |
185 } | |
186 if (private->info.depth > 8) { | |
187 if (wstype == WSDISPLAY_TYPE_SUN24 || | |
188 wstype == WSDISPLAY_TYPE_SUNCG12 || | |
189 wstype == WSDISPLAY_TYPE_SUNCG14 || | |
190 wstype == WSDISPLAY_TYPE_SUNTCX || | |
191 wstype == WSDISPLAY_TYPE_SUNFFB) { | |
192 private->redMask = 0x0000ff; | |
193 private->greenMask = 0x00ff00; | |
194 private->blueMask = 0xff0000; | |
1383 | 195 #ifdef WSDISPLAY_TYPE_PXALCD |
1187 | 196 } else if (wstype == WSDISPLAY_TYPE_PXALCD) { |
197 private->redMask = 0x1f << 11; | |
198 private->greenMask = 0x3f << 5; | |
199 private->blueMask = 0x1f; | |
1383 | 200 #endif |
1187 | 201 } else { |
202 WSCONS_ReportError("Unknown video hardware"); | |
203 return -1; | |
204 } | |
205 } else { | |
206 WSCONS_ReportError("Displays with 8 bpp or less are not supported"); | |
207 return -1; | |
208 } | |
209 | |
210 private->rotate = WSCONS_ROTATE_NONE; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
211 rotation = SDL_getenv("SDL_VIDEO_WSCONS_ROTATION"); |
1187 | 212 if (rotation != NULL) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
213 if (SDL_strlen(rotation) == 0) { |
1187 | 214 private->shadowFB = 0; |
215 private->rotate = WSCONS_ROTATE_NONE; | |
216 printf("Not rotating, no shadow\n"); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
217 } else if (!SDL_strcmp(rotation, "NONE")) { |
1187 | 218 private->shadowFB = 1; |
219 private->rotate = WSCONS_ROTATE_NONE; | |
220 printf("Not rotating, but still using shadow\n"); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
221 } else if (!SDL_strcmp(rotation, "CW")) { |
1187 | 222 private->shadowFB = 1; |
223 private->rotate = WSCONS_ROTATE_CW; | |
224 printf("Rotating screen clockwise\n"); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
225 } else if (!SDL_strcmp(rotation, "CCW")) { |
1187 | 226 private->shadowFB = 1; |
227 private->rotate = WSCONS_ROTATE_CCW; | |
228 printf("Rotating screen counter clockwise\n"); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
229 } else if (!SDL_strcmp(rotation, "UD")) { |
1187 | 230 private->shadowFB = 1; |
231 private->rotate = WSCONS_ROTATE_UD; | |
232 printf("Rotating screen upside down\n"); | |
233 } else { | |
234 WSCONS_ReportError("\"%s\" is not a valid value for " | |
235 "SDL_VIDEO_WSCONS_ROTATION", rotation); | |
236 return -1; | |
237 } | |
238 } | |
239 | |
240 switch (private->info.depth) { | |
241 case 1: | |
242 case 4: | |
243 case 8: | |
244 len = private->physlinebytes * private->info.height; | |
245 break; | |
246 case 16: | |
247 if (private->physlinebytes == private->info.width) { | |
248 len = private->info.width * private->info.height * sizeof(short); | |
249 } else { | |
250 len = private->physlinebytes * private->info.height; | |
251 } | |
252 if (private->rotate == WSCONS_ROTATE_NONE || | |
253 private->rotate == WSCONS_ROTATE_UD) { | |
254 private->blitFunc = WSCONS_blit16; | |
255 } else { | |
256 private->blitFunc = WSCONS_blit16blocked; | |
257 } | |
258 break; | |
259 case 32: | |
260 if (private->physlinebytes == private->info.width) { | |
261 len = private->info.width * private->info.height * sizeof(int); | |
262 } else { | |
263 len = private->physlinebytes * private->info.height; | |
264 } | |
265 break; | |
266 default: | |
267 WSCONS_ReportError("unsupported depth %d", private->info.depth); | |
268 return -1; | |
269 } | |
270 | |
271 if (private->shadowFB && private->blitFunc == NULL) { | |
272 WSCONS_ReportError("Using software buffer, but no blitter function is " | |
273 "available for this %d bpp.", private->info.depth); | |
274 return -1; | |
275 } | |
276 | |
277 if (ioctl(private->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) { | |
278 WSCONS_ReportError("ioctl SMODE"); | |
279 return -1; | |
280 } | |
281 | |
282 pagemask = getpagesize() - 1; | |
283 mapsize = ((int)len + pagemask) & ~pagemask; | |
284 private->physmem = (Uint8 *)mmap(NULL, mapsize, | |
285 PROT_READ | PROT_WRITE, MAP_SHARED, | |
286 private->fd, (off_t)0); | |
287 if (private->physmem == (Uint8 *)MAP_FAILED) { | |
288 private->physmem = NULL; | |
289 WSCONS_ReportError("mmap: %s", strerror(errno)); | |
290 return -1; | |
291 } | |
292 private->fbmem_len = len; | |
293 | |
294 if (private->rotate == WSCONS_ROTATE_CW || | |
295 private->rotate == WSCONS_ROTATE_CCW) { | |
296 width = private->info.height; | |
297 height = private->info.width; | |
298 } else { | |
299 width = private->info.width; | |
300 height = private->info.height; | |
301 } | |
302 | |
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
|
303 this->info.current_w = width; |
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
|
304 this->info.current_h = height; |
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
|
305 |
1187 | 306 if (private->shadowFB) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
307 private->shadowmem = (Uint8 *)SDL_malloc(len); |
1187 | 308 if (private->shadowmem == NULL) { |
309 WSCONS_ReportError("No memory for shadow"); | |
310 return -1; | |
311 } | |
312 private->fbstart = private->shadowmem; | |
313 private->fblinebytes = width * ((private->info.depth + 7) / 8); | |
314 } else { | |
315 private->fbstart = private->physmem; | |
316 private->fblinebytes = private->physlinebytes; | |
317 } | |
318 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
319 private->SDL_modelist[0] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect)); |
1187 | 320 private->SDL_modelist[0]->w = width; |
321 private->SDL_modelist[0]->h = height; | |
322 | |
323 vformat->BitsPerPixel = private->info.depth; | |
324 vformat->BytesPerPixel = private->info.depth / 8; | |
325 | |
326 if (WSCONS_InitKeyboard(this) == -1) { | |
327 return -1; | |
328 } | |
329 | |
330 return 0; | |
331 } | |
332 | |
333 SDL_Rect **WSCONS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | |
334 { | |
335 if (format->BitsPerPixel == private->info.depth) { | |
336 return private->SDL_modelist; | |
337 } else { | |
338 return NULL; | |
339 } | |
340 } | |
341 | |
342 SDL_Surface *WSCONS_SetVideoMode(_THIS, SDL_Surface *current, | |
343 int width, int height, int bpp, Uint32 flags) | |
344 { | |
345 if (width != private->SDL_modelist[0]->w || | |
346 height != private->SDL_modelist[0]->h) { | |
347 WSCONS_ReportError("Requested video mode %dx%d not supported.", | |
348 width, height); | |
349 return NULL; | |
350 } | |
351 if (bpp != private->info.depth) { | |
352 WSCONS_ReportError("Requested video depth %d bpp not supported.", bpp); | |
353 return NULL; | |
354 } | |
355 | |
356 if (!SDL_ReallocFormat(current, | |
357 bpp, | |
358 private->redMask, | |
359 private->greenMask, | |
360 private->blueMask, | |
361 0)) { | |
362 WSCONS_ReportError("Couldn't allocate new pixel format"); | |
363 return NULL; | |
364 } | |
365 | |
366 current->flags &= SDL_FULLSCREEN; | |
367 if (private->shadowFB) { | |
368 current->flags |= SDL_SWSURFACE; | |
369 } else { | |
370 current->flags |= SDL_HWSURFACE; | |
371 } | |
372 current->w = width; | |
373 current->h = height; | |
374 current->pitch = private->fblinebytes; | |
375 current->pixels = private->fbstart; | |
376 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
377 SDL_memset(private->fbstart, 0, private->fbmem_len); |
1187 | 378 |
379 return current; | |
380 } | |
381 | |
382 static int WSCONS_AllocHWSurface(_THIS, SDL_Surface *surface) | |
383 { | |
384 return -1; | |
385 } | |
386 static void WSCONS_FreeHWSurface(_THIS, SDL_Surface *surface) | |
387 { | |
388 } | |
389 | |
390 static int WSCONS_LockHWSurface(_THIS, SDL_Surface *surface) | |
391 { | |
392 return 0; | |
393 } | |
394 | |
395 static void WSCONS_UnlockHWSurface(_THIS, SDL_Surface *surface) | |
396 { | |
397 } | |
398 | |
399 static void WSCONS_blit16(Uint8 *byte_src_pos, | |
400 int srcRightDelta, | |
401 int srcDownDelta, | |
402 Uint8 *byte_dst_pos, | |
403 int dst_linebytes, | |
404 int width, | |
405 int height) | |
406 { | |
407 int w; | |
408 Uint16 *src_pos = (Uint16 *)byte_src_pos; | |
409 Uint16 *dst_pos = (Uint16 *)byte_dst_pos; | |
410 | |
411 while (height) { | |
412 Uint16 *src = src_pos; | |
413 Uint16 *dst = dst_pos; | |
414 for (w = width; w != 0; w--) { | |
415 *dst = *src; | |
416 src += srcRightDelta; | |
417 dst++; | |
418 } | |
419 dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes); | |
420 src_pos += srcDownDelta; | |
421 height--; | |
422 } | |
423 } | |
424 | |
425 #define BLOCKSIZE_W 32 | |
426 #define BLOCKSIZE_H 32 | |
427 | |
428 static void WSCONS_blit16blocked(Uint8 *byte_src_pos, | |
429 int srcRightDelta, | |
430 int srcDownDelta, | |
431 Uint8 *byte_dst_pos, | |
432 int dst_linebytes, | |
433 int width, | |
434 int height) | |
435 { | |
436 int w; | |
437 Uint16 *src_pos = (Uint16 *)byte_src_pos; | |
438 Uint16 *dst_pos = (Uint16 *)byte_dst_pos; | |
439 | |
440 while (height > 0) { | |
441 Uint16 *src = src_pos; | |
442 Uint16 *dst = dst_pos; | |
443 for (w = width; w > 0; w -= BLOCKSIZE_W) { | |
444 WSCONS_blit16((Uint8 *)src, | |
445 srcRightDelta, | |
446 srcDownDelta, | |
447 (Uint8 *)dst, | |
448 dst_linebytes, | |
449 min(w, BLOCKSIZE_W), | |
450 min(height, BLOCKSIZE_H)); | |
451 src += srcRightDelta * BLOCKSIZE_W; | |
452 dst += BLOCKSIZE_W; | |
453 } | |
454 dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes * BLOCKSIZE_H); | |
455 src_pos += srcDownDelta * BLOCKSIZE_H; | |
456 height -= BLOCKSIZE_H; | |
457 } | |
458 } | |
459 | |
460 static void WSCONS_UpdateRects(_THIS, int numrects, SDL_Rect *rects) | |
461 { | |
462 int width = private->SDL_modelist[0]->w; | |
463 int height = private->SDL_modelist[0]->h; | |
464 int bytesPerPixel = (private->info.depth + 7) / 8; | |
465 int i; | |
466 | |
467 if (!private->shadowFB) { | |
468 return; | |
469 } | |
470 | |
471 if (private->info.depth != 16) { | |
472 WSCONS_ReportError("Shadow copy only implemented for 16 bpp"); | |
473 return; | |
474 } | |
475 | |
476 for (i = 0; i < numrects; i++) { | |
477 int x1, y1, x2, y2; | |
478 int scr_x1, scr_y1, scr_x2, scr_y2; | |
479 int sha_x1, sha_y1; | |
480 int shadowRightDelta; /* Address change when moving right in dest */ | |
481 int shadowDownDelta; /* Address change when moving down in dest */ | |
482 Uint8 *src_start; | |
483 Uint8 *dst_start; | |
484 | |
485 x1 = rects[i].x; | |
486 y1 = rects[i].y; | |
487 x2 = x1 + rects[i].w; | |
488 y2 = y1 + rects[i].h; | |
489 | |
490 if (x1 < 0) { | |
491 x1 = 0; | |
492 } else if (x1 > width) { | |
493 x1 = width; | |
494 } | |
495 if (x2 < 0) { | |
496 x2 = 0; | |
497 } else if (x2 > width) { | |
498 x2 = width; | |
499 } | |
500 if (y1 < 0) { | |
501 y1 = 0; | |
502 } else if (y1 > height) { | |
503 y1 = height; | |
504 } | |
505 if (y2 < 0) { | |
506 y2 = 0; | |
507 } else if (y2 > height) { | |
508 y2 = height; | |
509 } | |
510 if (x2 <= x1 || y2 <= y1) { | |
511 continue; | |
512 } | |
513 | |
514 switch (private->rotate) { | |
515 case WSCONS_ROTATE_NONE: | |
516 sha_x1 = scr_x1 = x1; | |
517 sha_y1 = scr_y1 = y1; | |
518 scr_x2 = x2; | |
519 scr_y2 = y2; | |
520 shadowRightDelta = 1; | |
521 shadowDownDelta = width; | |
522 break; | |
523 case WSCONS_ROTATE_CCW: | |
524 scr_x1 = y1; | |
525 scr_y1 = width - x2; | |
526 scr_x2 = y2; | |
527 scr_y2 = width - x1; | |
528 sha_x1 = x2 - 1; | |
529 sha_y1 = y1; | |
530 shadowRightDelta = width; | |
531 shadowDownDelta = -1; | |
532 break; | |
533 case WSCONS_ROTATE_UD: | |
534 scr_x1 = width - x2; | |
535 scr_y1 = height - y2; | |
536 scr_x2 = width - x1; | |
537 scr_y2 = height - y1; | |
538 sha_x1 = x2 - 1; | |
539 sha_y1 = y2 - 1; | |
540 shadowRightDelta = -1; | |
541 shadowDownDelta = -width; | |
542 break; | |
543 case WSCONS_ROTATE_CW: | |
544 scr_x1 = height - y2; | |
545 scr_y1 = x1; | |
546 scr_x2 = height - y1; | |
547 scr_y2 = x2; | |
548 sha_x1 = x1; | |
549 sha_y1 = y2 - 1; | |
550 shadowRightDelta = -width; | |
551 shadowDownDelta = 1; | |
552 break; | |
553 default: | |
554 WSCONS_ReportError("Unknown rotation"); | |
555 return; | |
556 } | |
557 | |
558 src_start = private->shadowmem + (sha_y1 * width + sha_x1) * bytesPerPixel; | |
559 dst_start = private->physmem + scr_y1 * private->physlinebytes + | |
560 scr_x1 * bytesPerPixel; | |
561 | |
562 private->blitFunc(src_start, | |
563 shadowRightDelta, | |
564 shadowDownDelta, | |
565 dst_start, | |
566 private->physlinebytes, | |
567 scr_x2 - scr_x1, | |
568 scr_y2 - scr_y1); | |
569 } | |
570 } | |
571 | |
572 int WSCONS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | |
573 { | |
574 return 0; | |
575 } | |
576 | |
577 /* | |
578 * Note: If we are terminated, this could be called in the middle of | |
579 * another SDL video routine -- notably UpdateRects. | |
580 */ | |
581 void WSCONS_VideoQuit(_THIS) | |
582 { | |
583 int mode = WSDISPLAYIO_MODE_EMUL; | |
584 | |
585 if (private->shadowmem != NULL) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
586 SDL_free(private->shadowmem); |
1187 | 587 private->shadowmem = NULL; |
588 } | |
589 private->fbstart = NULL; | |
590 if (this->screen != NULL) { | |
591 this->screen->pixels = NULL; | |
592 } | |
593 | |
594 if (private->SDL_modelist[0] != NULL) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
595 SDL_free(private->SDL_modelist[0]); |
1187 | 596 private->SDL_modelist[0] = NULL; |
597 } | |
598 | |
599 if (ioctl(private->fd, WSDISPLAYIO_SMODE, &mode) == -1) { | |
600 WSCONS_ReportError("ioctl SMODE"); | |
601 } | |
602 | |
603 WSCONS_ReleaseKeyboard(this); | |
604 | |
605 if (private->fd != -1) { | |
606 close(private->fd); | |
607 private->fd = -1; | |
608 } | |
609 } |