Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F126822
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
35 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/util/sdl/stretch/SDL_stretch.h b/util/sdl/stretch/SDL_stretch.h
new file mode 100644
index 00000000..24f0b981
--- /dev/null
+++ b/util/sdl/stretch/SDL_stretch.h
@@ -0,0 +1,85 @@
+/*
+ SDL_stretch - Stretch Functions For The Simple DirectMedia Layer
+ Copyright (C) 2003 Guido Draheim
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Guido Draheim, guidod@gmx.de
+*/
+
+#ifndef _SDL_stretch_h
+#define _SDL_stretch_h
+
+#include <SDL_video.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef DECLSPEC
+#define DECLSPEC
+#endif
+
+/** Perform a stretch blit between two surfaces of the same format.
+ * NOTE: This function is not safe to call from multiple threads!
+ *
+ * This function will stretch a srcrect smoothly to the full area of
+ * the dst surface. If no srcrect is given then the full area of the
+ * src surface is stretched smoothly to the full dst surface. The
+ * dstrect is ignored always.
+ *
+ * This function will also watch for a clip rectangle on the src
+ * surface. This may speed up handling in your programs by creating
+ * a larger src surface with an associated viewframe, and the srcrect
+ * argument needs not be recomputed.
+ */
+extern DECLSPEC int
+SDL_StretchSurfaceRect(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect);
+/** Perform a stretch blit between two surfaces of the same format.
+ * NOTE: This function is not safe to call from multiple threads!
+ *
+ * This function will stretch a srcrect smoothly to the full area of
+ * the dst surface. If no srcrect is given then the full area of the
+ * src surface is stretched smoothly to the full dst surface. The
+ * dstrect is ignored always.
+ *
+ * Remember that this is the inverse meaning, the main SDL lib will
+ * ignore the srcrect and only watch for the dstrect if any.
+ */
+extern DECLSPEC int
+SDL_StretchSurfaceBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect);
+/**
+ * This function will stretch to 150%. This is not only a fast function
+ * but it is also safe to call from multiple threads. If the srcrect
+ * is given then only that rect is copied. Otherwise the full src
+ * surface is copied to the full dst surface. The dstrect is ignored.
+ */
+extern DECLSPEC int
+SDL_StretchSurface_23(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect);
+
+/**
+ * return some informative information.
+ */
+extern DECLSPEC char*
+SDL_StretchInfo(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/util/sdl/stretch/SDL_stretchasm.h b/util/sdl/stretch/SDL_stretchasm.h
new file mode 100644
index 00000000..d2441456
--- /dev/null
+++ b/util/sdl/stretch/SDL_stretchasm.h
@@ -0,0 +1,102 @@
+/*
+ SDL_stretch - Stretch Functions For The Simple DirectMedia Layer
+ Copyright (C) 2003 Guido Draheim
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Guido Draheim, guidod@gmx.de
+*/
+
+#ifndef _SDL_STRETCHASM_IMPLEMENTATION_
+#define _SDL_STRETCHASM_IMPLEMENTATION_
+
+/* development header - do not use */
+
+#if (defined(WIN32) && !defined(_M_ALPHA) && !defined(_WIN32_WCE))
+#define SDL_STRETCH_I386
+#define SDL_STRETCH_MASM
+#define SDL_STRETCH_USE_ASM
+#endif
+
+#if defined(__i386__) && defined(__GNUC__)
+#define SDL_STRETCH_I386
+#define SDL_STRETCH_GAS
+#define SDL_STRETCH_USE_ASM
+#endif
+
+#if defined(__x86_64__) && defined(__GNUC__)
+#define SDL_STRETCH_X86_64
+#define SDL_STRETCH_GAS
+#define SDL_STRETCH_USE_ASM
+#endif
+
+#if defined SDL_STRETCH_I386 && defined SDL_STRETCH_MASM
+#define SDL_STRETCH_CALL(code, srcp, dstp) \
+__asm {\
+ push edi ;\
+ push esi ;\
+ mov edi, dstp ;\
+ mov esi, srcp ;\
+ call dword ptr code ;\
+ pop esi ;\
+ pop edi ;\
+}
+#endif
+
+#if defined SDL_STRETCH_X86_64 && defined SDL_STRETCH_MASM
+#define SDL_STRETCH_CALL(code, srcp, dstp) \
+__asm {\
+ push rdi ;\
+ push rsi ;\
+ mov rdi, dstp ;\
+ mov rsi, srcp ;\
+ call qword ptr code ;\
+ pop rsi ;\
+ pop rdi ;\
+}
+#endif
+
+#if defined SDL_STRETCH_I386 && defined SDL_STRETCH_GAS
+#define SDL_STRETCH_CALL(code, srcp, dstp) \
+__asm__ __volatile__ ("call *%%eax" \
+ :: "S" (dstp), "D" (srcp), "a" (code));
+#endif
+
+#if defined SDL_STRETCH_X86_64 && defined SDL_STRETCH_GAS
+#define SDL_STRETCH_CALL(code, srcp, dstp) \
+__asm__ __volatile__ ("call *%%rax" \
+ :: "S" (dstp), "D" (srcp), "a" (code));
+#endif
+
+#if defined USE_ASM_STRETCH && ! defined SDL_STRETCH_USE_ASM
+#define SDL_STRETCH_USE_ASM 1
+#endif
+
+#if defined SDL_STRETCH_DISABLE_ASM
+#undef SDL_STRETCH_USE_ASM
+#undef SDL_STRETCH_CALL
+#endif
+
+#if defined SDL_STRETCH_USE_INTERPRETED_CODE
+#undef SDL_STRETCH_CALL
+#endif
+
+#if defined SDL_STRETCH_I386 || defined WIN32 || !defined SDL_STRETCH_CALL
+#define SDL_STRETCH_DATA_EXECUTABLE
+#else
+#define SDL_STRETCH_DATA_NOEXEC
+#endif
+
+#endif
diff --git a/util/sdl/stretch/SDL_stretchcode.h b/util/sdl/stretch/SDL_stretchcode.h
new file mode 100644
index 00000000..f8d06c3d
--- /dev/null
+++ b/util/sdl/stretch/SDL_stretchcode.h
@@ -0,0 +1,103 @@
+/*
+ SDL_stretch - Stretch Functions For The Simple DirectMedia Layer
+ Copyright (C) 2003 Guido Draheim
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Guido Draheim, guidod@gmx.de
+*/
+
+#ifndef _SDL_STRETCHCODE_IMPLEMENTATION_
+#define _SDL_STRETCHCODE_IMPLEMENTATION_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* development header - do not use */
+
+#define SDL_STRETCHCODE_BUFFERSIZE 8192
+
+/**
+ * TheRowStretchCode is a shared buffer between Stretch-routines that
+ * use no extra buffer-argument. You should call SDL_SetRowStretchCode
+ * to fill this internal buffer and set a "call"-operation for your target
+ * cpu to execute this static buffer. That is done for effiency
+ * as the RowStretch is often called in a tight loop for each Row
+ * in a rectengular stretch and it is best to not use a variable
+ * argument with an indirect call or a function call that would
+ * build up a callframe and release that callframe later.
+ *
+ * If you do not need that effiency, use PutRowStretchCode and RunRowStretchCode
+ * which are also good in a multithreading environment. To allocate a new buffer
+ * for usage with Put/Run you can use the NewRowStretchCode routine which is
+ * also used on NX machines (e.g. AMD64) where the data segment is set to be
+ * not-executable (in that case it will allocate from heap and use mprotect).
+ * if the argument is 0 then a buffer of the default size is allocated. If the
+ * buffer allocation (or mprotect) fails it will return NULL and SDL_SetError.
+ */
+extern unsigned char* SDL_GetRowStretchCode(void);
+
+/** => SDL_GetRowStretchCode */
+extern unsigned char* SDL_NewRowStretchCode(unsigned size);
+
+/**
+ * The SetRowStretchCode is a wrapper around PutRowStretchCode that
+ * uses the Adress and Size of the shared SDL_TheRowStretchCode buffer.
+ * The PutRowStretchCode will fill the given buffer with an assembler
+ * stream that should be called with SDL_RunRowStretchCode. The
+ * assembler stream is usually faster as all the scale decisions are
+ * done in advance of the execution. This helps when a RunCode is
+ * done multiple times with the same src_w/dst_w/bpp pair. All the
+ * pixel-get and pixel-set calls are unrolled in that buffer. Therefore,
+ * the buffer should be big enough - as a rule of thumb use a buffer
+ * of size (src_w+dst_w)*5
+ *
+ * If PutCode or SetCode fails, a NULL is returned and SDL_SetError.
+ * Otherwise, the start adress of the machine code buffer is returned,
+ * which is also the input argument of PutCode and RunCode.
+ */
+unsigned char* SDL_SetRowStretchCode(int src_w, int dst_w, int bpp);
+/** => SDL_SetRowStretchCode */
+unsigned char* SDL_PutRowStretchCode(unsigned char* buffer, int buflen,
+ int src_w, int dst_w, int bpp);
+/** => SDL_SetRowStretchCode */
+void SDL_RunRowStretchCode(unsigned char* buffer,
+ unsigned char* src,
+ unsigned char* dst);
+
+/** => SDL_SetRowStretchCode
+ * If SDL_SetRowStretchCode fails, this function must be used instead.
+ * This function and its cousins are singular routines that work in
+ * a tight loop to scale a single row. The number specifies the
+ * byte-width of each pixel (it is not a bit-width!).
+ */
+void SDL_StretchRow1(Uint8 *src, int src_w, Uint8 *dst, int dst_w);
+/** => SDL_SetRowStretchCode */
+void SDL_StretchRow2(Uint16 *src, int src_w, Uint16 *dst, int dst_w);
+/** => SDL_SetRowStretchCode */
+void SDL_StretchRow3(Uint8 *src, int src_w, Uint8 *dst, int dst_w);
+/** => SDL_SetRowStretchCode */
+void SDL_StretchRow4(Uint32 *src, int src_w, Uint32 *dst, int dst_w);
+
+/**
+ * return some informative information.
+ */
+extern char* SDL_StretchRowInfo(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/util/sdl/stretch/SDL_stretchtest.hh b/util/sdl/stretch/SDL_stretchtest.hh
new file mode 100644
index 00000000..07800a0b
--- /dev/null
+++ b/util/sdl/stretch/SDL_stretchtest.hh
@@ -0,0 +1,42 @@
+/*
+ SDL_stretch - Stretch Functions For The Simple DirectMedia Layer
+ Copyright (C) 2003 Guido Draheim
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Guido Draheim, guidod@gmx.de
+*/
+
+#ifndef _SDL_stretch_test_h
+#define _SDL_stretch_test_h
+
+#include "SDL_video.h"
+#ifndef _SDL_video_h
+#include <SDL/SDL_video.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int SDL_StretchSurfaceRectTo(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect);
+extern int SDL_StretchSurfaceBlitTo(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/util/sdl/stretch/config.h b/util/sdl/stretch/config.h
new file mode 100644
index 00000000..3f811f54
--- /dev/null
+++ b/util/sdl/stretch/config.h
@@ -0,0 +1,60 @@
+/* src/config.h. Generated from config.h.in by configure. */
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "SDL_stretch"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME ""
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING ""
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION ""
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "0.3.1"
diff --git a/util/sdl/stretch/sdlscreen.c b/util/sdl/stretch/sdlscreen.c
new file mode 100644
index 00000000..a1df98fe
--- /dev/null
+++ b/util/sdl/stretch/sdlscreen.c
@@ -0,0 +1,376 @@
+/*
+ SDL_stretch - Stretch Functions For The Simple DirectMedia Layer
+ Copyright (C) 2003 Guido Draheim
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Guido Draheim, guidod@gmx.de
+*/
+
+/* these will fill the target surface completely */
+
+/****************************************************
+ *
+ * WARNING: these routines are not used anymore.
+ * (they will not be part of the normal library)
+ *
+ ****************************************************
+ */
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id: sdstretch.c $";
+#endif
+
+#include "SDL/SDL_error.h"
+#include "SDL/SDL_video.h"
+#include "SDL_stretch.h"
+#include "SDL_stretchcode.h"
+#include "SDL_stretchasm.h"
+#include "SDL_stretchtest.hh"
+
+#define PRERUN 0
+
+
+/* Perform a stretch blit between two surfaces of the same format.
+ NOTE: This function is not safe to call from multiple threads!
+*/
+int SDL_StretchSurfaceBlitTo(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ int i = 0;
+ int src_row, dst_row;
+ SDL_Rect full_src;
+ /* SDL_Rect full_dst; */
+# if defined SDL_STRETCH_USE_ASM
+ unsigned char* code = 0;
+# endif
+ const int bpp = dst->format->BytesPerPixel;
+ auto int dest_w = srcrect->w * dst->w / src->w;
+ auto int dest_x = srcrect->x * dst->w / src->w;
+
+ if ( src->format->BitsPerPixel != dst->format->BitsPerPixel ) {
+ SDL_SetError("Only works with same format surfaces");
+ return(-1);
+ }
+
+ /* Verify the blit rectangles */
+ if ( srcrect ) {
+ if ( (srcrect->x < 0) || (srcrect->y < 0) ||
+ ((srcrect->x+srcrect->w) > src->w) ||
+ ((srcrect->y+srcrect->h) > src->h) ) {
+ SDL_SetError("Invalid source blit rectangle");
+ return(-1);
+ }
+ } else {
+ full_src.x = 0;
+ full_src.y = 0;
+ full_src.w = src->w;
+ full_src.h = src->h;
+ srcrect = &full_src;
+ }
+
+# ifdef SDL_STRETCH_USE_ASM
+ /* Write the opcodes for this stretch */
+ /* if ( (bpp != 3) */
+ code = SDL_SetRowStretchCode(srcrect->w, dest_w, bpp);
+# endif
+
+
+ if (PRERUN) /* let the compiler do the dead-code removal */
+ { /* Pre-Run the stretch blit (the invisible lines) */
+ src_row = 0;
+ dst_row = 0;
+ while (1)
+ {
+ if (src_row >= srcrect->y) break;
+ dst_row++; i += src->h;
+ if (i < dst->h) continue;
+ do { i -= dst->h; src_row++; } while (i >= dst->h);
+ }
+ }else
+ { /* or compute the resulting dst_row and i-fraction directly: */
+ src_row = srcrect->y;
+ dst_row = ((src_row * dst->h)+(src->h-1)) / src->h;
+ i = (dst_row * src->h - src_row * dst->h ) % dst->h;
+ if (i < 0) i += dst->h;
+ }
+
+ if (dstrect) { /*returnvalue*/
+ dstrect->y = dst_row;
+ dstrect->x = dest_x;
+ dstrect->w = dest_w;
+ }
+
+
+ while (src_row < srcrect->y + srcrect->h)
+ {
+ Uint8 *srcp, *dstp;
+ srcp = (Uint8 *)src->pixels + (src_row*src->pitch)
+ + (srcrect->x*bpp);
+ draw:
+ dstp = (Uint8 *)dst->pixels + (dst_row*dst->pitch)
+ + (dest_x*bpp);
+# ifdef SDL_STRETCH_USE_ASM
+ if (code)
+ {
+# if defined SDL_STRETCH_CALL
+ SDL_STRETCH_CALL(code, srcp, dstp);
+# else
+ SDL_RunRowStretchCode(code, srcp, dstp);
+# endif
+ }else
+# endif /*USE_ASM*/
+ {
+ switch (bpp) {
+ case 1:
+ SDL_StretchRow1(srcp, srcrect->w, dstp, dest_w);
+ break;
+ case 2:
+ SDL_StretchRow2((Uint16 *)srcp, srcrect->w,
+ (Uint16 *)dstp, dest_w);
+ break;
+ case 3:
+ SDL_StretchRow3(srcp, srcrect->w, dstp, dest_w);
+ break;
+ case 4:
+ SDL_StretchRow4((Uint32 *)srcp, srcrect->w,
+ (Uint32 *)dstp, dest_w);
+ break;
+ }
+ }
+
+ dst_row++; i += src->h;
+ if (dst_row == dst->h) break; /*oops*/
+ if (i < dst->h) goto draw; /* draw the line again */
+ do { i -= dst->h; src_row++; } while (i >= dst->h);
+ }
+
+ if (dstrect) dstrect->h = dst_row - dstrect->y; /*returnvalue*/
+
+ return(0);
+}
+
+/* ------------------------------------------------------------------------ */
+
+#define OPTIMIZED 1
+
+#if defined SDL_STRETCH_USE_ASM && defined OPTIMIZED
+static int SDL_StretchFastBlitTo(
+ unsigned char* code,
+ int dst_row, int src_row,
+ SDL_Surface* dst, SDL_Surface* src,
+ SDL_Rect* rect, SDL_Rect* clip, int dest_x, int i)
+{
+ const int bpp = src->format->BytesPerPixel;
+ Uint8 *srcp = (Uint8 *)src->pixels + (src_row*src->pitch) + (rect->x*bpp);
+ Uint8 *srcE = (Uint8 *)src->pixels + ((rect->y + rect->h)
+ *src->pitch) + (rect->x*bpp);
+ Uint8 *dstp = (Uint8 *)dst->pixels + (dst_row*dst->pitch) + (dest_x*bpp);
+// Uint8* dstE = (Uint8 *)dst->pixels + (dst->h*dst->pitch) + (dest_x*bpp);
+
+ while (srcp < srcE)
+ {
+ draws:
+# if defined SDL_STRETCH_CALL
+ SDL_STRETCH_CALL(code, srcp, dstp)
+# else
+ SDL_RunRowStretchCode(code, srcp, dstp);
+# endif
+ dstp += dst->pitch; i += clip->h;
+ // if (dstp == dstE) break; /*oops*/
+ if (i < dst->h) goto draws; /* draw the line again */
+ do { i -= dst->h; srcp += src->pitch; } while (i >= dst->h);
+ }
+ return dst_row;
+}
+#endif
+
+#define DEBUGSIZES 0
+#define DEBUGSIZES_ (src->h != dst->h)
+
+/* Perform a stretch blit between two surfaces of the same format.
+ NOTE: This function is not safe to call from multiple threads!
+*/
+int SDL_StretchSurfaceRectTo(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ int i = 0;
+ int src_row, dst_row;
+ int dest_x, dest_w;
+ SDL_Rect rect;
+ SDL_Rect clip;
+# if defined SDL_STRETCH_USE_ASM
+ unsigned char* code = 0;
+# endif
+ const int bpp = src->format->BytesPerPixel;
+
+ if ( src->format->BitsPerPixel != dst->format->BitsPerPixel ) {
+ SDL_SetError("Only works with same format surfaces");
+ return(-1);
+ }
+
+ /* Verify the blit rectangles */
+ if ( srcrect ) {
+ rect = *srcrect;
+#if 0
+ clip.x = clip.y = 0; clip.h = src->h; clip.w = src->w;
+#else
+ clip = src->clip_rect;
+
+ if (rect.x > clip.x + clip.w ||
+ rect.x + rect.w < clip.x ||
+ rect.y > clip.y + clip.h ||
+ rect.y + rect.h < clip.y) return 1;
+ if (rect.x < clip.x) { rect.w -= clip.x-rect.x; rect.x = clip.x; }
+ if (rect.w > clip.x + clip.w - rect.x)
+ rect.w = clip.x + clip.w - rect.x;
+ if (rect.y < clip.y) { rect.h -= clip.y-rect.y; rect.y = clip.y; }
+ if (rect.h > clip.y + clip.h - rect.y)
+ rect.h = clip.y + clip.h - rect.y;
+#endif
+ if (! rect.h || !rect.w) return 1;
+ } else {
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = src->w;
+ rect.h = src->h;
+ clip = rect;
+ }
+
+ if (DEBUGSIZES)
+ fprintf (stderr, "[%i/%i][%i+%i/%i+%i][%i+%i/%i+%i]\n",
+ src->w,src->h,
+ clip.x,clip.w,clip.y,clip.h,
+ rect.x,rect.w,rect.y,rect.h);
+
+ dest_w = rect.w * dst->w / clip.w;
+ dest_x = (rect.x-clip.x) * dst->w / clip.w;
+
+# ifdef SDL_STRETCH_USE_ASM
+ /* Write the opcodes for this stretch */
+ /* if ( (bpp != 3) */
+ code = SDL_SetRowStretchCode(rect.w, dest_w, bpp);
+# endif
+
+ if (PRERUN) /* let the compiler do the dead-code removal */
+ { /* Pre-Run the stretch blit (the invisible lines) */
+ src_row = clip.y;
+ dst_row = 0;
+ while (1)
+ {
+ if (src_row >= rect.y) break;
+ dst_row++; i += clip.h;
+ if (i < dst->h) continue;
+ do { i -= dst->h; src_row++; } while (i >= dst->h);
+ }
+ }else
+ { /* or compute the resulting dst_row and i-fraction directly: */
+ src_row = rect.y - clip.y;
+ dst_row = ((src_row * dst->h)+(clip.h-1)) / clip.h;
+ i = (dst_row * clip.h - src_row * dst->h ) % dst->h;
+ if (i < 0) i += dst->h;
+ }
+
+ if (dstrect) {
+ dstrect->y = dst_row;
+ dstrect->x = dest_x;
+ dstrect->w = dest_w;
+ }
+
+ if (DEBUGSIZES)
+ fprintf (stderr, "[%i/%i][%i+%i/%i+%i][%i+%i/%i+%i]"
+ " -> [%i/%i][%i+%i/%i+?]\n",
+ src->w,src->h,
+ clip.x,clip.w,clip.y,clip.h,
+ rect.x,rect.w,rect.y,rect.h,
+ dst->w,dst->h,
+ dest_x,dest_w,dst_row);
+
+# ifdef SDL_STRETCH_USE_ASM
+ if (code)
+ {
+# ifdef OPTIMIZED
+ dst_row = SDL_StretchFastBlitTo(code, dst_row, src_row, dst, src, &rect, &clip, dest_x,i);
+# else
+ while (src_row < rect.y + rect.h)
+ {
+ Uint8 *srcp, *dstp;
+ srcp = (Uint8 *)src->pixels + (src_row*src->pitch)
+ + (rect.x*bpp);
+ draws:
+ dstp = (Uint8 *)dst->pixels + (dst_row*dst->pitch)
+ + (dest_x*bpp);
+# ifdef SDL_STRETCH_CALL
+ SDL_STRETCH_CALL(code, srcp, dstp);
+# else
+ SDL_RunRowStretchCode(code, srcp, dstp);
+# endif
+ dst_row++; i += clip.h;
+ if (dst_row == dst->h) break; /*oops*/
+ if (i < dst->h) goto draws; /* draw the line again */
+ do { i -= dst->h; src_row++; } while (i >= dst->h);
+ }
+# endif
+ }else
+# endif /*USE_ASM*/
+ {
+ while (src_row < rect.y + rect.h)
+ {
+ Uint8 *srcp, *dstp;
+ srcp = (Uint8 *)src->pixels + (src_row*src->pitch)
+ + (rect.x*bpp);
+ draw:
+ dstp = (Uint8 *)dst->pixels + (dst_row*dst->pitch)
+ + (dest_x*bpp);
+
+ if (DEBUGSIZES) fprintf(stderr, ".");
+ switch (bpp) {
+ case 1:
+ SDL_StretchRow1(srcp, rect.w, dstp, dest_w);
+ break;
+ case 2:
+ SDL_StretchRow2((Uint16 *)srcp, rect.w,
+ (Uint16 *)dstp, dest_w);
+ break;
+ case 3:
+ SDL_StretchRow3(srcp, rect.w, dstp, dest_w);
+ break;
+ case 4:
+ SDL_StretchRow4((Uint32 *)srcp, rect.w,
+ (Uint32 *)dstp, dest_w);
+ break;
+ }
+
+ dst_row++; i += clip.h;
+ if (dst_row == dst->h) break; /*oops*/
+ if (i < dst->h) goto draw; /* draw the line again */
+ do { i -= dst->h; src_row++; } while (i >= dst->h);
+ }
+ }
+
+ if (dstrect) dstrect->h = dst_row - dstrect->y; /*returnvalue*/
+
+ if (DEBUGSIZES)
+ fprintf (stderr, "[%i/%i][%i+%i/%i+%i][%i+%i/%i+%i]"
+ " -> [%i/%i][%i+%i/?..%i]\n",
+ src->w,src->h,
+ clip.x,clip.w,clip.y,clip.h,
+ rect.x,rect.w,rect.y,rect.h,
+ dst->w,dst->h,
+ dest_x,dest_w,dst_row);
+
+ return(0);
+}
diff --git a/util/sdl/stretch/sdlstretch.c b/util/sdl/stretch/sdlstretch.c
new file mode 100644
index 00000000..5701691a
--- /dev/null
+++ b/util/sdl/stretch/sdlstretch.c
@@ -0,0 +1,382 @@
+/*
+ SDL_stretch - Stretch Functions For The Simple DirectMedia Layer
+ Copyright (C) 2003 Guido Draheim
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Guido Draheim, guidod@gmx.de
+*/
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id: sdstretch.c $";
+#endif
+
+#include "SDL/SDL_error.h"
+#include "SDL/SDL_video.h"
+#include "SDL_stretch.h"
+#include "SDL_stretchcode.h"
+#include "SDL_stretchasm.h"
+
+#define PRERUN 0
+
+
+/* Perform a stretch blit between two surfaces of the same format.
+ NOTE: This function is not safe to call from multiple threads!
+*/
+int SDL_StretchSurfaceBlit(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ int i = 0;
+ int src_row, dst_row;
+ SDL_Rect rect;
+# if defined SDL_STRETCH_USE_ASM
+ unsigned char* code = 0;
+# endif
+ const int bpp = dst->format->BytesPerPixel;
+ auto int dest_w;
+ auto int dest_x;
+
+ if ( src->format->BitsPerPixel != dst->format->BitsPerPixel ) {
+ SDL_SetError("Only works with same format surfaces");
+ return(-1);
+ }
+
+ /* Verify the blit rectangles */
+ if ( srcrect ) {
+ if ( (srcrect->x < 0) || (srcrect->y < 0) ||
+ ((srcrect->x+srcrect->w) > src->w) ||
+ ((srcrect->y+srcrect->h) > src->h) ) {
+ SDL_SetError("Invalid source blit rectangle");
+ return(-1);
+ }
+ } else {
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = src->w;
+ rect.h = src->h;
+ srcrect = ▭
+ }
+
+ dest_w = srcrect->w * dst->w / src->w;
+ dest_x = srcrect->x * dst->w / src->w;
+
+# ifdef SDL_STRETCH_USE_ASM
+ /* Write the opcodes for this stretch */
+ /* if ( (bpp != 3) */
+ code = SDL_SetRowStretchCode(srcrect->w, dest_w, bpp);
+# endif
+
+
+ if (PRERUN) /* let the compiler do the dead-code removal */
+ { /* Pre-Run the stretch blit (the invisible lines) */
+ src_row = 0;
+ dst_row = 0;
+ while (1)
+ {
+ if (src_row >= srcrect->y) break;
+ dst_row++; i += src->h;
+ if (i < dst->h) continue;
+ do { i -= dst->h; src_row++; } while (i >= dst->h);
+ }
+ }else
+ { /* or compute the resulting dst_row and i-fraction directly: */
+ src_row = srcrect->y;
+ dst_row = ((src_row * dst->h)+(src->h-1)) / src->h;
+ i = (dst_row * src->h - src_row * dst->h ) % dst->h;
+ if (i < 0) i += dst->h;
+ }
+
+ if (dstrect) { /*returnvalue*/
+ dstrect->y = dst_row;
+ dstrect->x = dest_x;
+ dstrect->w = dest_w;
+ }
+
+
+ while (src_row < srcrect->y + srcrect->h)
+ {
+ Uint8 *srcp, *dstp;
+ srcp = (Uint8 *)src->pixels
+ + (src_row*src->pitch)
+ + (srcrect->x*bpp);
+ draw:
+ dstp = (Uint8 *)dst->pixels
+ + (dst_row*dst->pitch)
+ + (dest_x*bpp);
+# ifdef SDL_STRETCH_USE_ASM
+ if (code)
+ {
+# ifdef SDL_STRETCH_CALL
+ SDL_STRETCH_CALL(code, srcp, dstp);
+# else
+ SDL_RunRowStretchCode(code, srcp, dstp);
+# endif
+ }else
+# endif /*USE_ASM*/
+ {
+ switch (bpp) {
+ case 1:
+ SDL_StretchRow1(srcp, srcrect->w, dstp, dest_w);
+ break;
+ case 2:
+ SDL_StretchRow2((Uint16 *)srcp, srcrect->w,
+ (Uint16 *)dstp, dest_w);
+ break;
+ case 3:
+ SDL_StretchRow3(srcp, srcrect->w, dstp, dest_w);
+ break;
+ case 4:
+ SDL_StretchRow4((Uint32 *)srcp, srcrect->w,
+ (Uint32 *)dstp, dest_w);
+ break;
+ }
+ }
+
+ dst_row++; i += src->h;
+ if (dst_row == dst->h) break; /*oops*/
+ if (i < dst->h) goto draw; /* draw the line again */
+ do { i -= dst->h; src_row++; } while (i >= dst->h);
+ }
+
+ if (dstrect) dstrect->h = dst_row - dstrect->y; /*returnvalue*/
+
+ return(0);
+}
+
+/* ------------------------------------------------------------------------ */
+
+#define OPTIMIZED 1
+
+#if defined SDL_STRETCH_USE_ASM && defined OPTIMIZED
+static int SDL_StretchFastBlit(unsigned char* code,
+ int dst_row, int src_row,
+ SDL_Surface* dst, SDL_Surface* src,
+ SDL_Rect* rect, SDL_Rect* clip, int dest_x, int i)
+{
+ const int bpp = src->format->BytesPerPixel;
+ Uint8 *srcp = (Uint8 *)src->pixels
+ + (src_row*src->pitch)
+ + (rect->x*bpp);
+ Uint8 *srcE = (Uint8 *)src->pixels
+ + ((rect->y + rect->h) * src->pitch)
+ + (rect->x*bpp);
+ Uint8 *dstp = (Uint8 *)dst->pixels
+ + (dst_row*dst->pitch)
+ + (dest_x*bpp);
+// Uint8* dstE = (Uint8 *)dst->pixels + (dst->h*dst->pitch) + (dest_x*bpp);
+
+ while (srcp < srcE)
+ {
+ draws:
+# ifdef SDL_STRETCH_CALL
+ SDL_STRETCH_CALL(code, srcp, dstp);
+# else
+ SDL_RunRowStretchCode(code, srcp, dstp);
+# endif
+ dstp += dst->pitch; i += clip->h;
+ // if (dstp == dstE) break; /*oops*/
+ if (i < dst->h) goto draws; /* draw the line again */
+ do { i -= dst->h; srcp += src->pitch; } while (i >= dst->h);
+ }
+ return dst_row;
+}
+#endif
+
+#define DEBUGSIZES 0
+#define DEBUGSIZES_ (src->h != dst->h)
+
+/* Perform a stretch blit between two surfaces of the same format.
+ NOTE: This function is not safe to call from multiple threads!
+*/
+int SDL_StretchSurfaceRect(SDL_Surface *src, SDL_Rect *srcrect,
+ SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ int i = 0;
+ int src_row, dst_row;
+ int dest_x, dest_w;
+ SDL_Rect rect;
+ SDL_Rect clip;
+# if defined SDL_STRETCH_USE_ASM
+ unsigned char* code = 0;
+# endif
+ const int bpp = src->format->BytesPerPixel;
+
+ if ( src->format->BitsPerPixel != dst->format->BitsPerPixel ) {
+ SDL_SetError("Only works with same format surfaces");
+ return(-1);
+ }
+
+ /* Verify the blit rectangles */
+ if ( srcrect ) {
+ rect = *srcrect;
+#if 0
+ clip.x = clip.y = 0; clip.h = src->h; clip.w = src->w;
+#else
+ clip = src->clip_rect;
+
+ if (rect.x > clip.x + clip.w ||
+ rect.x + rect.w < clip.x ||
+ rect.y > clip.y + clip.h ||
+ rect.y + rect.h < clip.y) return 1;
+ if (rect.x < clip.x) { rect.w -= clip.x-rect.x; rect.x = clip.x; }
+ if (rect.w > clip.x + clip.w - rect.x)
+ rect.w = clip.x + clip.w - rect.x;
+ if (rect.y < clip.y) { rect.h -= clip.y-rect.y; rect.y = clip.y; }
+ if (rect.h > clip.y + clip.h - rect.y)
+ rect.h = clip.y + clip.h - rect.y;
+#endif
+ if (! rect.h || !rect.w) return 1;
+ } else {
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = src->w;
+ rect.h = src->h;
+ clip = rect;
+ }
+
+ if (DEBUGSIZES)
+ fprintf (stderr, "[%i/%i][%i+%i/%i+%i][%i+%i/%i+%i]\n",
+ src->w,src->h,
+ clip.x,clip.w,clip.y,clip.h,
+ rect.x,rect.w,rect.y,rect.h);
+
+ dest_w = rect.w * dst->w / clip.w;
+ dest_x = (rect.x-clip.x) * dst->w / clip.w;
+
+# ifdef SDL_STRETCH_USE_ASM
+ /* Write the opcodes for this stretch */
+ /* if ( (bpp != 3) */
+ code = SDL_SetRowStretchCode(rect.w, dest_w, bpp);
+# endif
+
+ if (PRERUN) /* let the compiler do the dead-code removal */
+ { /* Pre-Run the stretch blit (the invisible lines) */
+ src_row = clip.y;
+ dst_row = 0;
+ while (1)
+ {
+ if (src_row >= rect.y) break;
+ dst_row++; i += clip.h;
+ if (i < dst->h) continue;
+ do { i -= dst->h; src_row++; } while (i >= dst->h);
+ }
+ }else
+ { /* or compute the resulting dst_row and i-fraction directly: */
+ src_row = rect.y - clip.y;
+ dst_row = ((src_row * dst->h)+(clip.h-1)) / clip.h;
+ i = (dst_row * clip.h - src_row * dst->h ) % dst->h;
+ if (i < 0) i += dst->h;
+ }
+
+ if (dstrect) {
+ dstrect->y = dst_row;
+ dstrect->x = dest_x;
+ dstrect->w = dest_w;
+ }
+
+ if (DEBUGSIZES)
+ fprintf (stderr, "[%i/%i][%i+%i/%i+%i][%i+%i/%i+%i]"
+ " -> [%i/%i][%i+%i/%i+?]\n",
+ src->w,src->h,
+ clip.x,clip.w,clip.y,clip.h,
+ rect.x,rect.w,rect.y,rect.h,
+ dst->w,dst->h,
+ dest_x,dest_w,dst_row);
+
+#ifdef SDL_STRETCH_USE_ASM
+ if (code)
+ {
+# ifdef OPTIMIZED
+ dst_row = SDL_StretchFastBlit(code, dst_row, src_row, dst, src, &rect, &clip, dest_x,i);
+# else
+ while (src_row < rect.y + rect.h)
+ {
+ Uint8 *srcp, *dstp;
+ srcp = (Uint8 *)src->pixels
+ + (src_row*src->pitch)
+ + (rect.x*bpp);
+ draws:
+ dstp = (Uint8 *)dst->pixels
+ + (dst_row*dst->pitch)
+ + (dest_x*bpp);
+
+# ifdef SDL_STRETCH_CALL
+ SDL_STRETCH_CALL(code, srcp, dstp);
+# else
+ SDL_RunRowStretchCode(code, srcp, dstp);
+# endif
+ dst_row++; i += clip.h;
+ if (dst_row == dst->h) break; /*oops*/
+ if (i < dst->h) goto draws; /* draw the line again */
+ do { i -= dst->h; src_row++; } while (i >= dst->h);
+ }
+# endif
+ }else
+# endif /*USE_ASM*/
+ {
+ while (src_row < rect.y + rect.h)
+ {
+ Uint8 *srcp, *dstp;
+ srcp = (Uint8 *)src->pixels
+ + (src_row*src->pitch)
+ + (rect.x*bpp);
+ draw:
+ dstp = (Uint8 *)dst->pixels
+ + (dst_row*dst->pitch)
+ + (dest_x*bpp);
+
+ if (DEBUGSIZES) fprintf(stderr, ".");
+ switch (bpp) {
+ case 1:
+ SDL_StretchRow1(srcp, rect.w, dstp, dest_w);
+ break;
+ case 2:
+ SDL_StretchRow2((Uint16 *)srcp, rect.w,
+ (Uint16 *)dstp, dest_w);
+ break;
+ case 3:
+ SDL_StretchRow3(srcp, rect.w, dstp, dest_w);
+ break;
+ case 4:
+ SDL_StretchRow4((Uint32 *)srcp, rect.w,
+ (Uint32 *)dstp, dest_w);
+ break;
+ }
+
+ dst_row++; i += clip.h;
+ if (dst_row == dst->h) break; /*oops*/
+ if (i < dst->h) goto draw; /* draw the line again */
+ do { i -= dst->h; src_row++; } while (i >= dst->h);
+ }
+ }
+
+ if (dstrect) dstrect->h = dst_row - dstrect->y; /*returnvalue*/
+
+ if (DEBUGSIZES)
+ fprintf (stderr, "[%i/%i][%i+%i/%i+%i][%i+%i/%i+%i]"
+ " -> [%i/%i][%i+%i/?..%i]\n",
+ src->w,src->h,
+ clip.x,clip.w,clip.y,clip.h,
+ rect.x,rect.w,rect.y,rect.h,
+ dst->w,dst->h,
+ dest_x,dest_w,dst_row);
+
+ return(0);
+}
+
+char* SDL_StretchInfo(void) {
+ return SDL_StretchRowInfo();
+}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Jun 11, 1:09 PM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
69178
Default Alt Text
(35 KB)
Attached To
Mode
R75 R-Tech1
Attached
Detach File
Event Timeline