src/video/SDL_stretch.c
branchSDL-1.3
changeset 1662 782fd950bd46
parent 1442 e3242177fe4a
child 1668 4da1ee79c9af
     1.1 --- a/src/video/SDL_stretch.c	Sun May 21 17:27:13 2006 +0000
     1.2 +++ b/src/video/SDL_stretch.c	Sun May 28 13:04:16 2006 +0000
     1.3 @@ -55,67 +55,68 @@
     1.4  
     1.5  static unsigned char copy_row[4096];
     1.6  
     1.7 -static int generate_rowbytes(int src_w, int dst_w, int bpp)
     1.8 +static int
     1.9 +generate_rowbytes (int src_w, int dst_w, int bpp)
    1.10  {
    1.11 -	static struct {
    1.12 -		int bpp;
    1.13 -		int src_w;
    1.14 -		int dst_w;
    1.15 -	} last;
    1.16 +    static struct
    1.17 +    {
    1.18 +        int bpp;
    1.19 +        int src_w;
    1.20 +        int dst_w;
    1.21 +    } last;
    1.22  
    1.23 -	int i;
    1.24 -	int pos, inc;
    1.25 -	unsigned char *eip;
    1.26 -	unsigned char load, store;
    1.27 +    int i;
    1.28 +    int pos, inc;
    1.29 +    unsigned char *eip;
    1.30 +    unsigned char load, store;
    1.31  
    1.32 -	/* See if we need to regenerate the copy buffer */
    1.33 -	if ( (src_w == last.src_w) &&
    1.34 -	     (dst_w == last.dst_w) && (bpp == last.bpp) ) {
    1.35 -		return(0);
    1.36 -	}
    1.37 -	last.bpp = bpp;
    1.38 -	last.src_w = src_w;
    1.39 -	last.dst_w = dst_w;
    1.40 +    /* See if we need to regenerate the copy buffer */
    1.41 +    if ((src_w == last.src_w) && (dst_w == last.dst_w) && (bpp == last.bpp)) {
    1.42 +        return (0);
    1.43 +    }
    1.44 +    last.bpp = bpp;
    1.45 +    last.src_w = src_w;
    1.46 +    last.dst_w = dst_w;
    1.47  
    1.48 -	switch (bpp) {
    1.49 -	    case 1:
    1.50 -		load = LOAD_BYTE;
    1.51 -		store = STORE_BYTE;
    1.52 -		break;
    1.53 -	    case 2:
    1.54 -	    case 4:
    1.55 -		load = LOAD_WORD;
    1.56 -		store = STORE_WORD;
    1.57 -		break;
    1.58 -	    default:
    1.59 -		SDL_SetError("ASM stretch of %d bytes isn't supported\n", bpp);
    1.60 -		return(-1);
    1.61 -	}
    1.62 -	pos = 0x10000;
    1.63 -	inc = (src_w << 16) / dst_w;
    1.64 -	eip = copy_row;
    1.65 -	for ( i=0; i<dst_w; ++i ) {
    1.66 -		while ( pos >= 0x10000L ) {
    1.67 -			if ( bpp == 2 ) {
    1.68 -				*eip++ = PREFIX16;
    1.69 -			}
    1.70 -			*eip++ = load;
    1.71 -			pos -= 0x10000L;
    1.72 -		}
    1.73 -		if ( bpp == 2 ) {
    1.74 -			*eip++ = PREFIX16;
    1.75 -		}
    1.76 -		*eip++ = store;
    1.77 -		pos += inc;
    1.78 -	}
    1.79 -	*eip++ = RETURN;
    1.80 +    switch (bpp) {
    1.81 +    case 1:
    1.82 +        load = LOAD_BYTE;
    1.83 +        store = STORE_BYTE;
    1.84 +        break;
    1.85 +    case 2:
    1.86 +    case 4:
    1.87 +        load = LOAD_WORD;
    1.88 +        store = STORE_WORD;
    1.89 +        break;
    1.90 +    default:
    1.91 +        SDL_SetError ("ASM stretch of %d bytes isn't supported\n", bpp);
    1.92 +        return (-1);
    1.93 +    }
    1.94 +    pos = 0x10000;
    1.95 +    inc = (src_w << 16) / dst_w;
    1.96 +    eip = copy_row;
    1.97 +    for (i = 0; i < dst_w; ++i) {
    1.98 +        while (pos >= 0x10000L) {
    1.99 +            if (bpp == 2) {
   1.100 +                *eip++ = PREFIX16;
   1.101 +            }
   1.102 +            *eip++ = load;
   1.103 +            pos -= 0x10000L;
   1.104 +        }
   1.105 +        if (bpp == 2) {
   1.106 +            *eip++ = PREFIX16;
   1.107 +        }
   1.108 +        *eip++ = store;
   1.109 +        pos += inc;
   1.110 +    }
   1.111 +    *eip++ = RETURN;
   1.112  
   1.113 -	/* Verify that we didn't overflow (too late) */
   1.114 -	if ( eip > (copy_row+sizeof(copy_row)) ) {
   1.115 -		SDL_SetError("Copy buffer overflow");
   1.116 -		return(-1);
   1.117 -	}
   1.118 -	return(0);
   1.119 +    /* Verify that we didn't overflow (too late) */
   1.120 +    if (eip > (copy_row + sizeof (copy_row))) {
   1.121 +        SDL_SetError ("Copy buffer overflow");
   1.122 +        return (-1);
   1.123 +    }
   1.124 +    return (0);
   1.125  }
   1.126  
   1.127  #else
   1.128 @@ -138,197 +139,187 @@
   1.129  		pos += inc;				\
   1.130  	}						\
   1.131  }
   1.132 -DEFINE_COPY_ROW(copy_row1, Uint8)
   1.133 -DEFINE_COPY_ROW(copy_row2, Uint16)
   1.134 -DEFINE_COPY_ROW(copy_row4, Uint32)
   1.135 +DEFINE_COPY_ROW (copy_row1, Uint8)
   1.136 +    DEFINE_COPY_ROW (copy_row2, Uint16) DEFINE_COPY_ROW (copy_row4, Uint32)
   1.137 +#endif /* USE_ASM_STRETCH */
   1.138 +/* The ASM code doesn't handle 24-bpp stretch blits */
   1.139 +     void
   1.140 +     copy_row3 (Uint8 * src, int src_w, Uint8 * dst, int dst_w)
   1.141 +{
   1.142 +    int i;
   1.143 +    int pos, inc;
   1.144 +    Uint8 pixel[3];
   1.145  
   1.146 -#endif /* USE_ASM_STRETCH */
   1.147 -
   1.148 -/* The ASM code doesn't handle 24-bpp stretch blits */
   1.149 -void copy_row3(Uint8 *src, int src_w, Uint8 *dst, int dst_w)
   1.150 -{
   1.151 -	int i;
   1.152 -	int pos, inc;
   1.153 -	Uint8 pixel[3];
   1.154 -
   1.155 -	pos = 0x10000;
   1.156 -	inc = (src_w << 16) / dst_w;
   1.157 -	for ( i=dst_w; i>0; --i ) {
   1.158 -		while ( pos >= 0x10000L ) {
   1.159 -			pixel[0] = *src++;
   1.160 -			pixel[1] = *src++;
   1.161 -			pixel[2] = *src++;
   1.162 -			pos -= 0x10000L;
   1.163 -		}
   1.164 -		*dst++ = pixel[0];
   1.165 -		*dst++ = pixel[1];
   1.166 -		*dst++ = pixel[2];
   1.167 -		pos += inc;
   1.168 -	}
   1.169 +    pos = 0x10000;
   1.170 +    inc = (src_w << 16) / dst_w;
   1.171 +    for (i = dst_w; i > 0; --i) {
   1.172 +        while (pos >= 0x10000L) {
   1.173 +            pixel[0] = *src++;
   1.174 +            pixel[1] = *src++;
   1.175 +            pixel[2] = *src++;
   1.176 +            pos -= 0x10000L;
   1.177 +        }
   1.178 +        *dst++ = pixel[0];
   1.179 +        *dst++ = pixel[1];
   1.180 +        *dst++ = pixel[2];
   1.181 +        pos += inc;
   1.182 +    }
   1.183  }
   1.184  
   1.185  /* Perform a stretch blit between two surfaces of the same format.
   1.186     NOTE:  This function is not safe to call from multiple threads!
   1.187  */
   1.188 -int SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect,
   1.189 -                    SDL_Surface *dst, SDL_Rect *dstrect)
   1.190 +int
   1.191 +SDL_SoftStretch (SDL_Surface * src, SDL_Rect * srcrect,
   1.192 +                 SDL_Surface * dst, SDL_Rect * dstrect)
   1.193  {
   1.194 -	int src_locked;
   1.195 -	int dst_locked;
   1.196 -	int pos, inc;
   1.197 -	int dst_width;
   1.198 -	int dst_maxrow;
   1.199 -	int src_row, dst_row;
   1.200 -	Uint8 *srcp = NULL;
   1.201 -	Uint8 *dstp;
   1.202 -	SDL_Rect full_src;
   1.203 -	SDL_Rect full_dst;
   1.204 +    int src_locked;
   1.205 +    int dst_locked;
   1.206 +    int pos, inc;
   1.207 +    int dst_width;
   1.208 +    int dst_maxrow;
   1.209 +    int src_row, dst_row;
   1.210 +    Uint8 *srcp = NULL;
   1.211 +    Uint8 *dstp;
   1.212 +    SDL_Rect full_src;
   1.213 +    SDL_Rect full_dst;
   1.214  #if defined(USE_ASM_STRETCH) && defined(__GNUC__)
   1.215 -	int u1, u2;
   1.216 +    int u1, u2;
   1.217  #endif
   1.218 -	const int bpp = dst->format->BytesPerPixel;
   1.219 +    const int bpp = dst->format->BytesPerPixel;
   1.220  
   1.221 -	if ( src->format->BitsPerPixel != dst->format->BitsPerPixel ) {
   1.222 -		SDL_SetError("Only works with same format surfaces");
   1.223 -		return(-1);
   1.224 -	}
   1.225 +    if (src->format->BitsPerPixel != dst->format->BitsPerPixel) {
   1.226 +        SDL_SetError ("Only works with same format surfaces");
   1.227 +        return (-1);
   1.228 +    }
   1.229  
   1.230 -	/* Verify the blit rectangles */
   1.231 -	if ( srcrect ) {
   1.232 -		if ( (srcrect->x < 0) || (srcrect->y < 0) ||
   1.233 -		     ((srcrect->x+srcrect->w) > src->w) ||
   1.234 -		     ((srcrect->y+srcrect->h) > src->h) ) {
   1.235 -			SDL_SetError("Invalid source blit rectangle");
   1.236 -			return(-1);
   1.237 -		}
   1.238 -	} else {
   1.239 -		full_src.x = 0;
   1.240 -		full_src.y = 0;
   1.241 -		full_src.w = src->w;
   1.242 -		full_src.h = src->h;
   1.243 -		srcrect = &full_src;
   1.244 -	}
   1.245 -	if ( dstrect ) {
   1.246 -		if ( (dstrect->x < 0) || (dstrect->y < 0) ||
   1.247 -		     ((dstrect->x+dstrect->w) > dst->w) ||
   1.248 -		     ((dstrect->y+dstrect->h) > dst->h) ) {
   1.249 -			SDL_SetError("Invalid destination blit rectangle");
   1.250 -			return(-1);
   1.251 -		}
   1.252 -	} else {
   1.253 -		full_dst.x = 0;
   1.254 -		full_dst.y = 0;
   1.255 -		full_dst.w = dst->w;
   1.256 -		full_dst.h = dst->h;
   1.257 -		dstrect = &full_dst;
   1.258 -	}
   1.259 +    /* Verify the blit rectangles */
   1.260 +    if (srcrect) {
   1.261 +        if ((srcrect->x < 0) || (srcrect->y < 0) ||
   1.262 +            ((srcrect->x + srcrect->w) > src->w) ||
   1.263 +            ((srcrect->y + srcrect->h) > src->h)) {
   1.264 +            SDL_SetError ("Invalid source blit rectangle");
   1.265 +            return (-1);
   1.266 +        }
   1.267 +    } else {
   1.268 +        full_src.x = 0;
   1.269 +        full_src.y = 0;
   1.270 +        full_src.w = src->w;
   1.271 +        full_src.h = src->h;
   1.272 +        srcrect = &full_src;
   1.273 +    }
   1.274 +    if (dstrect) {
   1.275 +        if ((dstrect->x < 0) || (dstrect->y < 0) ||
   1.276 +            ((dstrect->x + dstrect->w) > dst->w) ||
   1.277 +            ((dstrect->y + dstrect->h) > dst->h)) {
   1.278 +            SDL_SetError ("Invalid destination blit rectangle");
   1.279 +            return (-1);
   1.280 +        }
   1.281 +    } else {
   1.282 +        full_dst.x = 0;
   1.283 +        full_dst.y = 0;
   1.284 +        full_dst.w = dst->w;
   1.285 +        full_dst.h = dst->h;
   1.286 +        dstrect = &full_dst;
   1.287 +    }
   1.288  
   1.289 -	/* Lock the destination if it's in hardware */
   1.290 -	dst_locked = 0;
   1.291 -	if ( SDL_MUSTLOCK(dst) ) {
   1.292 -		if ( SDL_LockSurface(dst) < 0 ) {
   1.293 -			SDL_SetError("Unable to lock destination surface");
   1.294 -			return(-1);
   1.295 -		}
   1.296 -		dst_locked = 1;
   1.297 -	}
   1.298 -	/* Lock the source if it's in hardware */
   1.299 -	src_locked = 0;
   1.300 -	if ( SDL_MUSTLOCK(src) ) {
   1.301 -		if ( SDL_LockSurface(src) < 0 ) {
   1.302 -			if ( dst_locked ) {
   1.303 -				SDL_UnlockSurface(dst);
   1.304 -			}
   1.305 -			SDL_SetError("Unable to lock source surface");
   1.306 -			return(-1);
   1.307 -		}
   1.308 -		src_locked = 1;
   1.309 -	}
   1.310 +    /* Lock the destination if it's in hardware */
   1.311 +    dst_locked = 0;
   1.312 +    if (SDL_MUSTLOCK (dst)) {
   1.313 +        if (SDL_LockSurface (dst) < 0) {
   1.314 +            SDL_SetError ("Unable to lock destination surface");
   1.315 +            return (-1);
   1.316 +        }
   1.317 +        dst_locked = 1;
   1.318 +    }
   1.319 +    /* Lock the source if it's in hardware */
   1.320 +    src_locked = 0;
   1.321 +    if (SDL_MUSTLOCK (src)) {
   1.322 +        if (SDL_LockSurface (src) < 0) {
   1.323 +            if (dst_locked) {
   1.324 +                SDL_UnlockSurface (dst);
   1.325 +            }
   1.326 +            SDL_SetError ("Unable to lock source surface");
   1.327 +            return (-1);
   1.328 +        }
   1.329 +        src_locked = 1;
   1.330 +    }
   1.331  
   1.332 -	/* Set up the data... */
   1.333 -	pos = 0x10000;
   1.334 -	inc = (srcrect->h << 16) / dstrect->h;
   1.335 -	src_row = srcrect->y;
   1.336 -	dst_row = dstrect->y;
   1.337 -	dst_width = dstrect->w*bpp;
   1.338 +    /* Set up the data... */
   1.339 +    pos = 0x10000;
   1.340 +    inc = (srcrect->h << 16) / dstrect->h;
   1.341 +    src_row = srcrect->y;
   1.342 +    dst_row = dstrect->y;
   1.343 +    dst_width = dstrect->w * bpp;
   1.344  
   1.345  #ifdef USE_ASM_STRETCH
   1.346 -	/* Write the opcodes for this stretch */
   1.347 -	if ( (bpp != 3) &&
   1.348 -	     (generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0) ) {
   1.349 -		return(-1);
   1.350 -	}
   1.351 +    /* Write the opcodes for this stretch */
   1.352 +    if ((bpp != 3) && (generate_rowbytes (srcrect->w, dstrect->w, bpp) < 0)) {
   1.353 +        return (-1);
   1.354 +    }
   1.355  #endif
   1.356  
   1.357 -	/* Perform the stretch blit */
   1.358 -	for ( dst_maxrow = dst_row+dstrect->h; dst_row<dst_maxrow; ++dst_row ) {
   1.359 -		dstp = (Uint8 *)dst->pixels + (dst_row*dst->pitch)
   1.360 -		                            + (dstrect->x*bpp);
   1.361 -		while ( pos >= 0x10000L ) {
   1.362 -			srcp = (Uint8 *)src->pixels + (src_row*src->pitch)
   1.363 -			                            + (srcrect->x*bpp);
   1.364 -			++src_row;
   1.365 -			pos -= 0x10000L;
   1.366 -		}
   1.367 +    /* Perform the stretch blit */
   1.368 +    for (dst_maxrow = dst_row + dstrect->h; dst_row < dst_maxrow; ++dst_row) {
   1.369 +        dstp = (Uint8 *) dst->pixels + (dst_row * dst->pitch)
   1.370 +            + (dstrect->x * bpp);
   1.371 +        while (pos >= 0x10000L) {
   1.372 +            srcp = (Uint8 *) src->pixels + (src_row * src->pitch)
   1.373 +                + (srcrect->x * bpp);
   1.374 +            ++src_row;
   1.375 +            pos -= 0x10000L;
   1.376 +        }
   1.377  #ifdef USE_ASM_STRETCH
   1.378 -		switch (bpp) {
   1.379 -		    case 3:
   1.380 -			copy_row3(srcp, srcrect->w, dstp, dstrect->w);
   1.381 -			break;
   1.382 -		    default:
   1.383 +        switch (bpp) {
   1.384 +        case 3:
   1.385 +            copy_row3 (srcp, srcrect->w, dstp, dstrect->w);
   1.386 +            break;
   1.387 +        default:
   1.388  #ifdef __GNUC__
   1.389 -			__asm__ __volatile__ (
   1.390 -			"call *%4"
   1.391 -			: "=&D" (u1), "=&S" (u2)
   1.392 -			: "0" (dstp), "1" (srcp), "r" (copy_row)
   1.393 -			: "memory" );
   1.394 +          __asm__ __volatile__ ("call *%4": "=&D" (u1), "=&S" (u2): "0" (dstp), "1" (srcp), "r" (copy_row):"memory");
   1.395  #elif defined(_MSC_VER) || defined(__WATCOMC__)
   1.396 -		{ void *code = copy_row;
   1.397 -			__asm {
   1.398 -				push edi
   1.399 -				push esi
   1.400 -	
   1.401 -				mov edi, dstp
   1.402 -				mov esi, srcp
   1.403 -				call dword ptr code
   1.404 -
   1.405 -				pop esi
   1.406 -				pop edi
   1.407 -			}
   1.408 -		}
   1.409 +            {
   1.410 +                void *code = copy_row;
   1.411 +                __asm {
   1.412 +                push edi
   1.413 +                        push esi
   1.414 +                        mov edi, dstp
   1.415 +                        mov esi, srcp call dword ptr code pop esi pop edi}
   1.416 +            }
   1.417  #else
   1.418  #error Need inline assembly for this compiler
   1.419  #endif
   1.420 -			break;
   1.421 -		}
   1.422 +            break;
   1.423 +        }
   1.424  #else
   1.425 -		switch (bpp) {
   1.426 -		    case 1:
   1.427 -			copy_row1(srcp, srcrect->w, dstp, dstrect->w);
   1.428 -			break;
   1.429 -		    case 2:
   1.430 -			copy_row2((Uint16 *)srcp, srcrect->w,
   1.431 -			          (Uint16 *)dstp, dstrect->w);
   1.432 -			break;
   1.433 -		    case 3:
   1.434 -			copy_row3(srcp, srcrect->w, dstp, dstrect->w);
   1.435 -			break;
   1.436 -		    case 4:
   1.437 -			copy_row4((Uint32 *)srcp, srcrect->w,
   1.438 -			          (Uint32 *)dstp, dstrect->w);
   1.439 -			break;
   1.440 -		}
   1.441 +        switch (bpp) {
   1.442 +        case 1:
   1.443 +            copy_row1 (srcp, srcrect->w, dstp, dstrect->w);
   1.444 +            break;
   1.445 +        case 2:
   1.446 +            copy_row2 ((Uint16 *) srcp, srcrect->w,
   1.447 +                       (Uint16 *) dstp, dstrect->w);
   1.448 +            break;
   1.449 +        case 3:
   1.450 +            copy_row3 (srcp, srcrect->w, dstp, dstrect->w);
   1.451 +            break;
   1.452 +        case 4:
   1.453 +            copy_row4 ((Uint32 *) srcp, srcrect->w,
   1.454 +                       (Uint32 *) dstp, dstrect->w);
   1.455 +            break;
   1.456 +        }
   1.457  #endif
   1.458 -		pos += inc;
   1.459 -	}
   1.460 +        pos += inc;
   1.461 +    }
   1.462  
   1.463 -	/* We need to unlock the surfaces if they're locked */
   1.464 -	if ( dst_locked ) {
   1.465 -		SDL_UnlockSurface(dst);
   1.466 -	}
   1.467 -	if ( src_locked ) {
   1.468 -		SDL_UnlockSurface(src);
   1.469 -	}
   1.470 -	return(0);
   1.471 +    /* We need to unlock the surfaces if they're locked */
   1.472 +    if (dst_locked) {
   1.473 +        SDL_UnlockSurface (dst);
   1.474 +    }
   1.475 +    if (src_locked) {
   1.476 +        SDL_UnlockSurface (src);
   1.477 +    }
   1.478 +    return (0);
   1.479  }
   1.480  
   1.481 +/* vi: set ts=4 sw=4 expandtab: */