Mercurial > sdl-ios-xcode
annotate src/video/SDL_stretch.c @ 1302:94643e9bad18
Date: Sat, 14 Jan 2006 15:16:01 -0500
From: Andrew Fuller
Subject: [SDL] [PATCH] ML-8866 PS2->USB converter
This converter seems to go by several names -- Super Dual Box, Dual
USB Joypad, and who knows what else. Also branded differently with
different colour cases, etc. But it seems to all be the same
internals. It is a common converter used for StepMania, with several
posts Googleable trying to make it work in Linux. I got mine
yesterday and wanted to play stepmania, so I went ahead and made a
crude patch for libsdl to split this baby into two logical joysticks.
A couple notes about the patch:
This patch works well for two dance mats hooked up and playing
stepmania, however the mapping of the other buttons may be off. I
have no joystick which uses all the buttons the converter reports, so
I have no way of testing them.
The name I used 0925:8866 which is the USB ID, and what SDLjoytest-GL
reported is the name, even though lsusb shows Wisegroup, Ltd MP-8866
Dual USB Joypad, and the existing virtual joystick mapping uses the
Wisegroup... name. Not sure why the discrepency.
I'm not subscribed to this mailing list, so please CC me on any
comments to this.
-Andrew
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 31 Jan 2006 14:59:43 +0000 |
parents | 73676c1f56ee |
children | c9b51268668f |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
627
diff
changeset
|
3 Copyright (C) 1997-2004 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
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 | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* This a stretch blit implementation based on ideas given to me by | |
29 Tomasz Cejner - thanks! :) | |
30 | |
31 April 27, 2000 - Sam Lantinga | |
32 */ | |
33 | |
34 #include "SDL_error.h" | |
35 #include "SDL_video.h" | |
36 #include "SDL_blit.h" | |
37 | |
38 /* This isn't ready for general consumption yet - it should be folded | |
39 into the general blitting mechanism. | |
40 */ | |
41 | |
288
2f5a6062db86
Updated for Watcom C++ and LCC compilers
Sam Lantinga <slouken@libsdl.org>
parents:
274
diff
changeset
|
42 #if (defined(WIN32) && !defined(_M_ALPHA) && !defined(_WIN32_WCE) && \ |
2f5a6062db86
Updated for Watcom C++ and LCC compilers
Sam Lantinga <slouken@libsdl.org>
parents:
274
diff
changeset
|
43 !defined(__WATCOMC__) && !defined(__LCC__) && !defined(__FREEBCC__)) || \ |
2f5a6062db86
Updated for Watcom C++ and LCC compilers
Sam Lantinga <slouken@libsdl.org>
parents:
274
diff
changeset
|
44 (defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT)) |
0 | 45 #define USE_ASM_STRETCH |
46 #endif | |
47 | |
48 #ifdef USE_ASM_STRETCH | |
49 | |
50 #if defined(WIN32) || defined(i386) | |
51 #define PREFIX16 0x66 | |
52 #define STORE_BYTE 0xAA | |
53 #define STORE_WORD 0xAB | |
54 #define LOAD_BYTE 0xAC | |
55 #define LOAD_WORD 0xAD | |
56 #define RETURN 0xC3 | |
57 #else | |
58 #error Need assembly opcodes for this architecture | |
59 #endif | |
60 | |
61 static unsigned char copy_row[4096]; | |
62 | |
63 static int generate_rowbytes(int src_w, int dst_w, int bpp) | |
64 { | |
65 static struct { | |
66 int bpp; | |
67 int src_w; | |
68 int dst_w; | |
69 } last; | |
70 | |
71 int i; | |
72 int pos, inc; | |
73 unsigned char *eip; | |
74 unsigned char load, store; | |
75 | |
76 /* See if we need to regenerate the copy buffer */ | |
77 if ( (src_w == last.src_w) && | |
1164
10b3fb28c86b
Date: Mon, 31 Oct 2005 14:23:34 +0100
Ryan C. Gordon <icculus@icculus.org>
parents:
894
diff
changeset
|
78 (dst_w == last.dst_w) && (bpp == last.bpp) ) { |
0 | 79 return(0); |
80 } | |
81 last.bpp = bpp; | |
82 last.src_w = src_w; | |
83 last.dst_w = dst_w; | |
84 | |
85 switch (bpp) { | |
86 case 1: | |
87 load = LOAD_BYTE; | |
88 store = STORE_BYTE; | |
89 break; | |
90 case 2: | |
91 case 4: | |
92 load = LOAD_WORD; | |
93 store = STORE_WORD; | |
94 break; | |
95 default: | |
96 SDL_SetError("ASM stretch of %d bytes isn't supported\n", bpp); | |
97 return(-1); | |
98 } | |
99 pos = 0x10000; | |
100 inc = (src_w << 16) / dst_w; | |
101 eip = copy_row; | |
102 for ( i=0; i<dst_w; ++i ) { | |
103 while ( pos >= 0x10000L ) { | |
104 if ( bpp == 2 ) { | |
105 *eip++ = PREFIX16; | |
106 } | |
107 *eip++ = load; | |
108 pos -= 0x10000L; | |
109 } | |
110 if ( bpp == 2 ) { | |
111 *eip++ = PREFIX16; | |
112 } | |
113 *eip++ = store; | |
114 pos += inc; | |
115 } | |
116 *eip++ = RETURN; | |
117 | |
118 /* Verify that we didn't overflow (too late) */ | |
119 if ( eip > (copy_row+sizeof(copy_row)) ) { | |
120 SDL_SetError("Copy buffer overflow"); | |
121 return(-1); | |
122 } | |
123 return(0); | |
124 } | |
125 | |
126 #else | |
127 | |
128 #define DEFINE_COPY_ROW(name, type) \ | |
129 void name(type *src, int src_w, type *dst, int dst_w) \ | |
130 { \ | |
131 int i; \ | |
132 int pos, inc; \ | |
133 type pixel = 0; \ | |
134 \ | |
135 pos = 0x10000; \ | |
136 inc = (src_w << 16) / dst_w; \ | |
137 for ( i=dst_w; i>0; --i ) { \ | |
138 while ( pos >= 0x10000L ) { \ | |
139 pixel = *src++; \ | |
140 pos -= 0x10000L; \ | |
141 } \ | |
142 *dst++ = pixel; \ | |
143 pos += inc; \ | |
144 } \ | |
145 } | |
146 DEFINE_COPY_ROW(copy_row1, Uint8) | |
147 DEFINE_COPY_ROW(copy_row2, Uint16) | |
148 DEFINE_COPY_ROW(copy_row4, Uint32) | |
149 | |
150 #endif /* USE_ASM_STRETCH */ | |
151 | |
152 /* The ASM code doesn't handle 24-bpp stretch blits */ | |
153 void copy_row3(Uint8 *src, int src_w, Uint8 *dst, int dst_w) | |
154 { | |
155 int i; | |
156 int pos, inc; | |
157 Uint8 pixel[3]; | |
158 | |
159 pos = 0x10000; | |
160 inc = (src_w << 16) / dst_w; | |
161 for ( i=dst_w; i>0; --i ) { | |
162 while ( pos >= 0x10000L ) { | |
163 pixel[0] = *src++; | |
164 pixel[1] = *src++; | |
165 pixel[2] = *src++; | |
166 pos -= 0x10000L; | |
167 } | |
168 *dst++ = pixel[0]; | |
169 *dst++ = pixel[1]; | |
170 *dst++ = pixel[2]; | |
171 pos += inc; | |
172 } | |
173 } | |
174 | |
175 /* Perform a stretch blit between two surfaces of the same format. | |
176 NOTE: This function is not safe to call from multiple threads! | |
177 */ | |
178 int SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect, | |
179 SDL_Surface *dst, SDL_Rect *dstrect) | |
180 { | |
894
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
181 int src_locked; |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
182 int dst_locked; |
0 | 183 int pos, inc; |
184 int dst_width; | |
185 int dst_maxrow; | |
186 int src_row, dst_row; | |
187 Uint8 *srcp = NULL; | |
188 Uint8 *dstp; | |
189 SDL_Rect full_src; | |
190 SDL_Rect full_dst; | |
191 #if defined(USE_ASM_STRETCH) && defined(__GNUC__) | |
192 int u1, u2; | |
193 #endif | |
194 const int bpp = dst->format->BytesPerPixel; | |
195 | |
196 if ( src->format->BitsPerPixel != dst->format->BitsPerPixel ) { | |
197 SDL_SetError("Only works with same format surfaces"); | |
198 return(-1); | |
199 } | |
200 | |
201 /* Verify the blit rectangles */ | |
202 if ( srcrect ) { | |
203 if ( (srcrect->x < 0) || (srcrect->y < 0) || | |
204 ((srcrect->x+srcrect->w) > src->w) || | |
205 ((srcrect->y+srcrect->h) > src->h) ) { | |
206 SDL_SetError("Invalid source blit rectangle"); | |
207 return(-1); | |
208 } | |
209 } else { | |
210 full_src.x = 0; | |
211 full_src.y = 0; | |
212 full_src.w = src->w; | |
213 full_src.h = src->h; | |
214 srcrect = &full_src; | |
215 } | |
216 if ( dstrect ) { | |
217 if ( (dstrect->x < 0) || (dstrect->y < 0) || | |
218 ((dstrect->x+dstrect->w) > dst->w) || | |
219 ((dstrect->y+dstrect->h) > dst->h) ) { | |
220 SDL_SetError("Invalid destination blit rectangle"); | |
221 return(-1); | |
222 } | |
223 } else { | |
224 full_dst.x = 0; | |
225 full_dst.y = 0; | |
226 full_dst.w = dst->w; | |
227 full_dst.h = dst->h; | |
228 dstrect = &full_dst; | |
229 } | |
230 | |
894
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
231 /* Lock the destination if it's in hardware */ |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
232 dst_locked = 0; |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
233 if ( SDL_MUSTLOCK(dst) ) { |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
234 if ( SDL_LockSurface(dst) < 0 ) { |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
235 SDL_SetError("Unable to lock destination surface"); |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
236 return(-1); |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
237 } |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
238 dst_locked = 1; |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
239 } |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
240 /* Lock the source if it's in hardware */ |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
241 src_locked = 0; |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
242 if ( SDL_MUSTLOCK(src) ) { |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
243 if ( SDL_LockSurface(src) < 0 ) { |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
244 if ( dst_locked ) { |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
245 SDL_UnlockSurface(dst); |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
246 } |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
247 SDL_SetError("Unable to lock source surface"); |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
248 return(-1); |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
249 } |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
250 src_locked = 1; |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
251 } |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
252 |
0 | 253 /* Set up the data... */ |
254 pos = 0x10000; | |
255 inc = (srcrect->h << 16) / dstrect->h; | |
256 src_row = srcrect->y; | |
257 dst_row = dstrect->y; | |
258 dst_width = dstrect->w*bpp; | |
259 | |
260 #ifdef USE_ASM_STRETCH | |
261 /* Write the opcodes for this stretch */ | |
262 if ( (bpp != 3) && | |
263 (generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0) ) { | |
264 return(-1); | |
265 } | |
266 #endif | |
267 | |
268 /* Perform the stretch blit */ | |
269 for ( dst_maxrow = dst_row+dstrect->h; dst_row<dst_maxrow; ++dst_row ) { | |
270 dstp = (Uint8 *)dst->pixels + (dst_row*dst->pitch) | |
271 + (dstrect->x*bpp); | |
272 while ( pos >= 0x10000L ) { | |
273 srcp = (Uint8 *)src->pixels + (src_row*src->pitch) | |
274 + (srcrect->x*bpp); | |
275 ++src_row; | |
276 pos -= 0x10000L; | |
277 } | |
278 #ifdef USE_ASM_STRETCH | |
279 switch (bpp) { | |
280 case 3: | |
281 copy_row3(srcp, srcrect->w, dstp, dstrect->w); | |
282 break; | |
283 default: | |
284 #ifdef __GNUC__ | |
627
8b9ac38381d0
Fixed compile problem in SDL_stretch.c with gcc 3.3
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
285 __asm__ __volatile__ ( |
1228
f4a3a4129d04
From Mike Frysinger and/or Gentoo:
Ryan C. Gordon <icculus@icculus.org>
parents:
1164
diff
changeset
|
286 "call *%4" |
0 | 287 : "=&D" (u1), "=&S" (u2) |
1234
73676c1f56ee
For sanity's sake, removed the '&' when passing copy_row array to asm.
Ryan C. Gordon <icculus@icculus.org>
parents:
1233
diff
changeset
|
288 : "0" (dstp), "1" (srcp), "r" (copy_row) |
0 | 289 : "memory" ); |
290 #else | |
291 #ifdef WIN32 | |
1234
73676c1f56ee
For sanity's sake, removed the '&' when passing copy_row array to asm.
Ryan C. Gordon <icculus@icculus.org>
parents:
1233
diff
changeset
|
292 { void *code = copy_row; |
0 | 293 __asm { |
294 push edi | |
295 push esi | |
296 | |
297 mov edi, dstp | |
298 mov esi, srcp | |
299 call dword ptr code | |
300 | |
301 pop esi | |
302 pop edi | |
303 } | |
304 } | |
305 #else | |
306 #error Need inline assembly for this compiler | |
307 #endif | |
308 #endif /* __GNUC__ */ | |
309 break; | |
310 } | |
311 #else | |
312 switch (bpp) { | |
313 case 1: | |
314 copy_row1(srcp, srcrect->w, dstp, dstrect->w); | |
315 break; | |
316 case 2: | |
317 copy_row2((Uint16 *)srcp, srcrect->w, | |
318 (Uint16 *)dstp, dstrect->w); | |
319 break; | |
320 case 3: | |
321 copy_row3(srcp, srcrect->w, dstp, dstrect->w); | |
322 break; | |
323 case 4: | |
324 copy_row4((Uint32 *)srcp, srcrect->w, | |
325 (Uint32 *)dstp, dstrect->w); | |
326 break; | |
327 } | |
328 #endif | |
329 pos += inc; | |
330 } | |
894
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
331 |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
332 /* We need to unlock the surfaces if they're locked */ |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
333 if ( dst_locked ) { |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
334 SDL_UnlockSurface(dst); |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
335 } |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
336 if ( src_locked ) { |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
337 SDL_UnlockSurface(src); |
1d1a823904d8
Don't crash if the stretch routines are used on hardware surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
338 } |
0 | 339 return(0); |
340 } | |
341 |