diff --git a/debian/changelog b/debian/changelog
index 528c210..3f59aea 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -3,6 +3,8 @@ instead (1.3.2) unstable; urgency=low
* bug fix (dates in save slots);
* bug fix (dbg fixes);
* small bug fixes;
+ * s60 build;
+ * SDL 1.3 ready;
-- Peter Kosyh
Mon, 14 Feb 2011 16:24:00 +0300
diff --git a/src/sdl-instead/SDL_gfxBlitFunc.c b/src/sdl-instead/SDL_gfxBlitFunc.c
index be3c445..e976da3 100644
--- a/src/sdl-instead/SDL_gfxBlitFunc.c
+++ b/src/sdl-instead/SDL_gfxBlitFunc.c
@@ -1,454 +1,505 @@
/*
- SDL_gfxBlitFunc: custom blitters (part of SDL_gfx library)
+SDL_gfxBlitFunc: custom blitters (part of SDL_gfx library)
+
+LGPL (c) A. Schiffler
- LGPL (c) A. Schiffler
-
*/
-
#include "SDL_gfxBlitFunc.h"
-/* -------- Alpha adjustment table, modified transfer function -------- */
+/*!
+\brief Alpha adjustment table for custom blitter.
-unsigned int GFX_ALPHA_ADJUST[256] = {
- 0, /* 0 */
- 15, /* 1 */
- 22, /* 2 */
- 27, /* 3 */
- 31, /* 4 */
- 35, /* 5 */
- 39, /* 6 */
- 42, /* 7 */
- 45, /* 8 */
- 47, /* 9 */
- 50, /* 10 */
- 52, /* 11 */
- 55, /* 12 */
- 57, /* 13 */
- 59, /* 14 */
- 61, /* 15 */
- 63, /* 16 */
- 65, /* 17 */
- 67, /* 18 */
- 69, /* 19 */
- 71, /* 20 */
- 73, /* 21 */
- 74, /* 22 */
- 76, /* 23 */
- 78, /* 24 */
- 79, /* 25 */
- 81, /* 26 */
- 82, /* 27 */
- 84, /* 28 */
- 85, /* 29 */
- 87, /* 30 */
- 88, /* 31 */
- 90, /* 32 */
- 91, /* 33 */
- 93, /* 34 */
- 94, /* 35 */
- 95, /* 36 */
- 97, /* 37 */
- 98, /* 38 */
- 99, /* 39 */
- 100, /* 40 */
- 102, /* 41 */
- 103, /* 42 */
- 104, /* 43 */
- 105, /* 44 */
- 107, /* 45 */
- 108, /* 46 */
- 109, /* 47 */
- 110, /* 48 */
- 111, /* 49 */
- 112, /* 50 */
- 114, /* 51 */
- 115, /* 52 */
- 116, /* 53 */
- 117, /* 54 */
- 118, /* 55 */
- 119, /* 56 */
- 120, /* 57 */
- 121, /* 58 */
- 122, /* 59 */
- 123, /* 60 */
- 124, /* 61 */
- 125, /* 62 */
- 126, /* 63 */
- 127, /* 64 */
- 128, /* 65 */
- 129, /* 66 */
- 130, /* 67 */
- 131, /* 68 */
- 132, /* 69 */
- 133, /* 70 */
- 134, /* 71 */
- 135, /* 72 */
- 136, /* 73 */
- 137, /* 74 */
- 138, /* 75 */
- 139, /* 76 */
- 140, /* 77 */
- 141, /* 78 */
- 141, /* 79 */
- 142, /* 80 */
- 143, /* 81 */
- 144, /* 82 */
- 145, /* 83 */
- 146, /* 84 */
- 147, /* 85 */
- 148, /* 86 */
- 148, /* 87 */
- 149, /* 88 */
- 150, /* 89 */
- 151, /* 90 */
- 152, /* 91 */
- 153, /* 92 */
- 153, /* 93 */
- 154, /* 94 */
- 155, /* 95 */
- 156, /* 96 */
- 157, /* 97 */
- 158, /* 98 */
- 158, /* 99 */
- 159, /* 100 */
- 160, /* 101 */
- 161, /* 102 */
- 162, /* 103 */
- 162, /* 104 */
- 163, /* 105 */
- 164, /* 106 */
- 165, /* 107 */
- 165, /* 108 */
- 166, /* 109 */
- 167, /* 110 */
- 168, /* 111 */
- 168, /* 112 */
- 169, /* 113 */
- 170, /* 114 */
- 171, /* 115 */
- 171, /* 116 */
- 172, /* 117 */
- 173, /* 118 */
- 174, /* 119 */
- 174, /* 120 */
- 175, /* 121 */
- 176, /* 122 */
- 177, /* 123 */
- 177, /* 124 */
- 178, /* 125 */
- 179, /* 126 */
- 179, /* 127 */
- 180, /* 128 */
- 181, /* 129 */
- 182, /* 130 */
- 182, /* 131 */
- 183, /* 132 */
- 184, /* 133 */
- 184, /* 134 */
- 185, /* 135 */
- 186, /* 136 */
- 186, /* 137 */
- 187, /* 138 */
- 188, /* 139 */
- 188, /* 140 */
- 189, /* 141 */
- 190, /* 142 */
- 190, /* 143 */
- 191, /* 144 */
- 192, /* 145 */
- 192, /* 146 */
- 193, /* 147 */
- 194, /* 148 */
- 194, /* 149 */
- 195, /* 150 */
- 196, /* 151 */
- 196, /* 152 */
- 197, /* 153 */
- 198, /* 154 */
- 198, /* 155 */
- 199, /* 156 */
- 200, /* 157 */
- 200, /* 158 */
- 201, /* 159 */
- 201, /* 160 */
- 202, /* 161 */
- 203, /* 162 */
- 203, /* 163 */
- 204, /* 164 */
- 205, /* 165 */
- 205, /* 166 */
- 206, /* 167 */
- 206, /* 168 */
- 207, /* 169 */
- 208, /* 170 */
- 208, /* 171 */
- 209, /* 172 */
- 210, /* 173 */
- 210, /* 174 */
- 211, /* 175 */
- 211, /* 176 */
- 212, /* 177 */
- 213, /* 178 */
- 213, /* 179 */
- 214, /* 180 */
- 214, /* 181 */
- 215, /* 182 */
- 216, /* 183 */
- 216, /* 184 */
- 217, /* 185 */
- 217, /* 186 */
- 218, /* 187 */
- 218, /* 188 */
- 219, /* 189 */
- 220, /* 190 */
- 220, /* 191 */
- 221, /* 192 */
- 221, /* 193 */
- 222, /* 194 */
- 222, /* 195 */
- 223, /* 196 */
- 224, /* 197 */
- 224, /* 198 */
- 225, /* 199 */
- 225, /* 200 */
- 226, /* 201 */
- 226, /* 202 */
- 227, /* 203 */
- 228, /* 204 */
- 228, /* 205 */
- 229, /* 206 */
- 229, /* 207 */
- 230, /* 208 */
- 230, /* 209 */
- 231, /* 210 */
- 231, /* 211 */
- 232, /* 212 */
- 233, /* 213 */
- 233, /* 214 */
- 234, /* 215 */
- 234, /* 216 */
- 235, /* 217 */
- 235, /* 218 */
- 236, /* 219 */
- 236, /* 220 */
- 237, /* 221 */
- 237, /* 222 */
- 238, /* 223 */
- 238, /* 224 */
- 239, /* 225 */
- 240, /* 226 */
- 240, /* 227 */
- 241, /* 228 */
- 241, /* 229 */
- 242, /* 230 */
- 242, /* 231 */
- 243, /* 232 */
- 243, /* 233 */
- 244, /* 234 */
- 244, /* 235 */
- 245, /* 236 */
- 245, /* 237 */
- 246, /* 238 */
- 246, /* 239 */
- 247, /* 240 */
- 247, /* 241 */
- 248, /* 242 */
- 248, /* 243 */
- 249, /* 244 */
- 249, /* 245 */
- 250, /* 246 */
- 250, /* 247 */
- 251, /* 248 */
- 251, /* 249 */
- 252, /* 250 */
- 252, /* 251 */
- 253, /* 252 */
- 253, /* 253 */
- 254, /* 254 */
- 255 /* 255 */
- };
+The table provides values for a modified, non-linear
+transfer function which maintain brightness.
+*/
+static unsigned int GFX_ALPHA_ADJUST_ARRAY[256] = {
+ 0, /* 0 */
+ 15, /* 1 */
+ 22, /* 2 */
+ 27, /* 3 */
+ 31, /* 4 */
+ 35, /* 5 */
+ 39, /* 6 */
+ 42, /* 7 */
+ 45, /* 8 */
+ 47, /* 9 */
+ 50, /* 10 */
+ 52, /* 11 */
+ 55, /* 12 */
+ 57, /* 13 */
+ 59, /* 14 */
+ 61, /* 15 */
+ 63, /* 16 */
+ 65, /* 17 */
+ 67, /* 18 */
+ 69, /* 19 */
+ 71, /* 20 */
+ 73, /* 21 */
+ 74, /* 22 */
+ 76, /* 23 */
+ 78, /* 24 */
+ 79, /* 25 */
+ 81, /* 26 */
+ 82, /* 27 */
+ 84, /* 28 */
+ 85, /* 29 */
+ 87, /* 30 */
+ 88, /* 31 */
+ 90, /* 32 */
+ 91, /* 33 */
+ 93, /* 34 */
+ 94, /* 35 */
+ 95, /* 36 */
+ 97, /* 37 */
+ 98, /* 38 */
+ 99, /* 39 */
+ 100, /* 40 */
+ 102, /* 41 */
+ 103, /* 42 */
+ 104, /* 43 */
+ 105, /* 44 */
+ 107, /* 45 */
+ 108, /* 46 */
+ 109, /* 47 */
+ 110, /* 48 */
+ 111, /* 49 */
+ 112, /* 50 */
+ 114, /* 51 */
+ 115, /* 52 */
+ 116, /* 53 */
+ 117, /* 54 */
+ 118, /* 55 */
+ 119, /* 56 */
+ 120, /* 57 */
+ 121, /* 58 */
+ 122, /* 59 */
+ 123, /* 60 */
+ 124, /* 61 */
+ 125, /* 62 */
+ 126, /* 63 */
+ 127, /* 64 */
+ 128, /* 65 */
+ 129, /* 66 */
+ 130, /* 67 */
+ 131, /* 68 */
+ 132, /* 69 */
+ 133, /* 70 */
+ 134, /* 71 */
+ 135, /* 72 */
+ 136, /* 73 */
+ 137, /* 74 */
+ 138, /* 75 */
+ 139, /* 76 */
+ 140, /* 77 */
+ 141, /* 78 */
+ 141, /* 79 */
+ 142, /* 80 */
+ 143, /* 81 */
+ 144, /* 82 */
+ 145, /* 83 */
+ 146, /* 84 */
+ 147, /* 85 */
+ 148, /* 86 */
+ 148, /* 87 */
+ 149, /* 88 */
+ 150, /* 89 */
+ 151, /* 90 */
+ 152, /* 91 */
+ 153, /* 92 */
+ 153, /* 93 */
+ 154, /* 94 */
+ 155, /* 95 */
+ 156, /* 96 */
+ 157, /* 97 */
+ 158, /* 98 */
+ 158, /* 99 */
+ 159, /* 100 */
+ 160, /* 101 */
+ 161, /* 102 */
+ 162, /* 103 */
+ 162, /* 104 */
+ 163, /* 105 */
+ 164, /* 106 */
+ 165, /* 107 */
+ 165, /* 108 */
+ 166, /* 109 */
+ 167, /* 110 */
+ 168, /* 111 */
+ 168, /* 112 */
+ 169, /* 113 */
+ 170, /* 114 */
+ 171, /* 115 */
+ 171, /* 116 */
+ 172, /* 117 */
+ 173, /* 118 */
+ 174, /* 119 */
+ 174, /* 120 */
+ 175, /* 121 */
+ 176, /* 122 */
+ 177, /* 123 */
+ 177, /* 124 */
+ 178, /* 125 */
+ 179, /* 126 */
+ 179, /* 127 */
+ 180, /* 128 */
+ 181, /* 129 */
+ 182, /* 130 */
+ 182, /* 131 */
+ 183, /* 132 */
+ 184, /* 133 */
+ 184, /* 134 */
+ 185, /* 135 */
+ 186, /* 136 */
+ 186, /* 137 */
+ 187, /* 138 */
+ 188, /* 139 */
+ 188, /* 140 */
+ 189, /* 141 */
+ 190, /* 142 */
+ 190, /* 143 */
+ 191, /* 144 */
+ 192, /* 145 */
+ 192, /* 146 */
+ 193, /* 147 */
+ 194, /* 148 */
+ 194, /* 149 */
+ 195, /* 150 */
+ 196, /* 151 */
+ 196, /* 152 */
+ 197, /* 153 */
+ 198, /* 154 */
+ 198, /* 155 */
+ 199, /* 156 */
+ 200, /* 157 */
+ 200, /* 158 */
+ 201, /* 159 */
+ 201, /* 160 */
+ 202, /* 161 */
+ 203, /* 162 */
+ 203, /* 163 */
+ 204, /* 164 */
+ 205, /* 165 */
+ 205, /* 166 */
+ 206, /* 167 */
+ 206, /* 168 */
+ 207, /* 169 */
+ 208, /* 170 */
+ 208, /* 171 */
+ 209, /* 172 */
+ 210, /* 173 */
+ 210, /* 174 */
+ 211, /* 175 */
+ 211, /* 176 */
+ 212, /* 177 */
+ 213, /* 178 */
+ 213, /* 179 */
+ 214, /* 180 */
+ 214, /* 181 */
+ 215, /* 182 */
+ 216, /* 183 */
+ 216, /* 184 */
+ 217, /* 185 */
+ 217, /* 186 */
+ 218, /* 187 */
+ 218, /* 188 */
+ 219, /* 189 */
+ 220, /* 190 */
+ 220, /* 191 */
+ 221, /* 192 */
+ 221, /* 193 */
+ 222, /* 194 */
+ 222, /* 195 */
+ 223, /* 196 */
+ 224, /* 197 */
+ 224, /* 198 */
+ 225, /* 199 */
+ 225, /* 200 */
+ 226, /* 201 */
+ 226, /* 202 */
+ 227, /* 203 */
+ 228, /* 204 */
+ 228, /* 205 */
+ 229, /* 206 */
+ 229, /* 207 */
+ 230, /* 208 */
+ 230, /* 209 */
+ 231, /* 210 */
+ 231, /* 211 */
+ 232, /* 212 */
+ 233, /* 213 */
+ 233, /* 214 */
+ 234, /* 215 */
+ 234, /* 216 */
+ 235, /* 217 */
+ 235, /* 218 */
+ 236, /* 219 */
+ 236, /* 220 */
+ 237, /* 221 */
+ 237, /* 222 */
+ 238, /* 223 */
+ 238, /* 224 */
+ 239, /* 225 */
+ 240, /* 226 */
+ 240, /* 227 */
+ 241, /* 228 */
+ 241, /* 229 */
+ 242, /* 230 */
+ 242, /* 231 */
+ 243, /* 232 */
+ 243, /* 233 */
+ 244, /* 234 */
+ 244, /* 235 */
+ 245, /* 236 */
+ 245, /* 237 */
+ 246, /* 238 */
+ 246, /* 239 */
+ 247, /* 240 */
+ 247, /* 241 */
+ 248, /* 242 */
+ 248, /* 243 */
+ 249, /* 244 */
+ 249, /* 245 */
+ 250, /* 246 */
+ 250, /* 247 */
+ 251, /* 248 */
+ 251, /* 249 */
+ 252, /* 250 */
+ 252, /* 251 */
+ 253, /* 252 */
+ 253, /* 253 */
+ 254, /* 254 */
+ 255 /* 255 */
+};
-/* --- */
+/*!
+\brief Internal blitter using adjusted destination alpha during RGBA->RGBA blits.
-/* Special blitter for correct destination Alpha during RGBA->RGBA blits */
+Performs the blit based on the 'info' structure and applies the transfer function
+to the destination 'a' values.
-void SDL_gfxBlitBlitterRGBA(SDL_gfxBlitInfo * info)
+\param info The blit info to use.
+*/
+void _SDL_gfxBlitBlitterRGBA(SDL_gfxBlitInfo * info)
{
- int width = info->d_width;
- int height = info->d_height;
- Uint8 *src = info->s_pixels;
- int srcskip = info->s_skip;
- Uint8 *dst = info->d_pixels;
- int dstskip = info->d_skip;
- SDL_PixelFormat *srcfmt = info->src;
- SDL_PixelFormat *dstfmt = info->dst;
- int srcbpp = srcfmt->BytesPerPixel;
- int dstbpp = dstfmt->BytesPerPixel;
+ int width = info->d_width;
+ int height = info->d_height;
+ Uint8 *src = info->s_pixels;
+ int srcskip = info->s_skip;
+ Uint8 *dst = info->d_pixels;
+ int dstskip = info->d_skip;
+ SDL_PixelFormat *srcfmt = info->src;
+ SDL_PixelFormat *dstfmt = info->dst;
+ int srcbpp = srcfmt->BytesPerPixel;
+ int dstbpp = dstfmt->BytesPerPixel;
- while (height--) {
- GFX_DUFFS_LOOP4( {
- Uint32 pixel;
- unsigned sR;
- unsigned sG;
- unsigned sB;
- unsigned sA;
- unsigned dR;
- unsigned dG;
- unsigned dB;
- unsigned dA;
- unsigned sAA;
- GFX_DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB, sA);
- GFX_DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
- sAA=GFX_ALPHA_ADJUST[sA & 255];
- GFX_ALPHA_BLEND(sR, sG, sB, sAA, dR, dG, dB);
- dA |= sAA;
- GFX_ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
- src += srcbpp; dst += dstbpp;
- }, width);
- src += srcskip;
- dst += dstskip;
- }
+ while (height--) {
+ GFX_DUFFS_LOOP4( {
+ Uint32 pixel;
+ unsigned sR;
+ unsigned sG;
+ unsigned sB;
+ unsigned sA;
+ unsigned dR;
+ unsigned dG;
+ unsigned dB;
+ unsigned dA;
+ unsigned sAA;
+ GFX_DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB, sA);
+ GFX_DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
+ sAA=GFX_ALPHA_ADJUST_ARRAY[sA & 255];
+ GFX_ALPHA_BLEND(sR, sG, sB, sAA, dR, dG, dB);
+ dA |= sAA;
+ GFX_ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
+ src += srcbpp; dst += dstbpp;
+ }, width);
+ src += srcskip;
+ dst += dstskip;
+ }
}
-int SDL_gfxBlitRGBACall(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect)
+/*!
+\brief Internal blitter setup wrapper for RGBA->RGBA blits.
+
+Sets up the blitter info based on the 'src' and 'dst' surfaces and rectangles.
+
+\param src The source surface.
+\param srcrect The source rectangle.
+\param dst The destination surface.
+\param dstrect The destination rectangle.
+
+\returns Returns 1 if blit was performed, 0 otherwise.
+*/
+int _SDL_gfxBlitRGBACall(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect)
{
- /*
- * Set up source and destination buffer pointers, then blit
- */
- if (srcrect->w && srcrect->h) {
- SDL_gfxBlitInfo info;
+ /*
+ * Set up source and destination buffer pointers, then blit
+ */
+ if (srcrect->w && srcrect->h) {
+ SDL_gfxBlitInfo info;
- /*
- * Set up the blit information
- */
- info.s_pixels = (Uint8 *) src->pixels + src->offset + (Uint16) srcrect->y * src->pitch + (Uint16) srcrect->x * src->format->BytesPerPixel;
- info.s_width = srcrect->w;
- info.s_height = srcrect->h;
- info.s_skip = src->pitch - info.s_width * src->format->BytesPerPixel;
- info.d_pixels = (Uint8 *) dst->pixels + dst->offset + (Uint16) dstrect->y * dst->pitch + (Uint16) dstrect->x * dst->format->BytesPerPixel;
- info.d_width = dstrect->w;
- info.d_height = dstrect->h;
- info.d_skip = dst->pitch - info.d_width * dst->format->BytesPerPixel;
- info.aux_data = NULL;
- info.src = src->format;
- info.table = NULL;
- info.dst = dst->format;
+ /*
+ * Set up the blit information
+ */
+#if (SDL_MINOR_VERSION == 3)
+ info.s_pixels = (Uint8 *) src->pixels + (Uint16) srcrect->y * src->pitch + (Uint16) srcrect->x * src->format->BytesPerPixel;
+#else
+ info.s_pixels = (Uint8 *) src->pixels + src->offset + (Uint16) srcrect->y * src->pitch + (Uint16) srcrect->x * src->format->BytesPerPixel;
+#endif
+ info.s_width = srcrect->w;
+ info.s_height = srcrect->h;
+ info.s_skip = src->pitch - info.s_width * src->format->BytesPerPixel;
+#if (SDL_MINOR_VERSION == 3)
+ info.d_pixels = (Uint8 *) dst->pixels + (Uint16) dstrect->y * dst->pitch + (Uint16) dstrect->x * dst->format->BytesPerPixel;
+#else
+ info.d_pixels = (Uint8 *) dst->pixels + dst->offset + (Uint16) dstrect->y * dst->pitch + (Uint16) dstrect->x * dst->format->BytesPerPixel;
+#endif
+ info.d_width = dstrect->w;
+ info.d_height = dstrect->h;
+ info.d_skip = dst->pitch - info.d_width * dst->format->BytesPerPixel;
+ info.aux_data = NULL;
+ info.src = src->format;
+ info.table = NULL;
+ info.dst = dst->format;
- /*
- * Run the actual software blitter
- */
- SDL_gfxBlitBlitterRGBA(&info);
- }
+ /*
+ * Run the actual software blitter
+ */
+ _SDL_gfxBlitBlitterRGBA(&info);
+ return 1;
+ }
- return (0);
+ return (0);
}
+/*!
+\brief Blitter for RGBA->RGBA blits with alpha adjustment.
+Verifies the input 'src' and 'dst' surfaces and rectangles and performs blit.
+The destination clip rectangle is honored.
+
+\param src The source surface.
+\param srcrect The source rectangle.
+\param dst The destination surface.
+\param dstrect The destination rectangle.
+
+\returns Returns 1 if blit was performed, 0 otherwise, or -1 if an error occured.
+*/
int SDL_gfxBlitRGBA(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect)
{
- SDL_Rect sr, dr;
- int srcx, srcy, w, h;
+ SDL_Rect sr, dr;
+ int srcx, srcy, w, h;
- /*
- * Make sure the surfaces aren't locked
- */
- if (!src || !dst) {
- SDL_SetError("SDL_UpperBlit: passed a NULL surface");
- return (-1);
- }
- if (src->locked || dst->locked) {
- SDL_SetError("Surfaces must not be locked during blit");
- return (-1);
- }
+ /*
+ * Make sure the surfaces aren't locked
+ */
+ if (!src || !dst) {
+ SDL_SetError("SDL_UpperBlit: passed a NULL surface");
+ return (-1);
+ }
+ if (src->locked || dst->locked) {
+ SDL_SetError("Surfaces must not be locked during blit");
+ return (-1);
+ }
- /*
- * If the destination rectangle is NULL, use the entire dest surface
- */
- if (dstrect == NULL) {
- dr.x = dr.y = 0;
- dr.w = dst->w;
- dr.h = dst->h;
- } else {
- dr = *dstrect;
- }
+ /*
+ * If the destination rectangle is NULL, use the entire dest surface
+ */
+ if (dstrect == NULL) {
+ dr.x = dr.y = 0;
+ dr.w = dst->w;
+ dr.h = dst->h;
+ } else {
+ dr = *dstrect;
+ }
- /*
- * Clip the source rectangle to the source surface
- */
- if (srcrect) {
- int maxw, maxh;
+ /*
+ * Clip the source rectangle to the source surface
+ */
+ if (srcrect) {
+ int maxw, maxh;
- srcx = srcrect->x;
- w = srcrect->w;
- if (srcx < 0) {
- w += srcx;
- dr.x -= srcx;
- srcx = 0;
- }
- maxw = src->w - srcx;
- if (maxw < w)
- w = maxw;
+ srcx = srcrect->x;
+ w = srcrect->w;
+ if (srcx < 0) {
+ w += srcx;
+ dr.x -= srcx;
+ srcx = 0;
+ }
+ maxw = src->w - srcx;
+ if (maxw < w)
+ w = maxw;
- srcy = srcrect->y;
- h = srcrect->h;
- if (srcy < 0) {
- h += srcy;
- dr.y -= srcy;
- srcy = 0;
- }
- maxh = src->h - srcy;
- if (maxh < h)
- h = maxh;
+ srcy = srcrect->y;
+ h = srcrect->h;
+ if (srcy < 0) {
+ h += srcy;
+ dr.y -= srcy;
+ srcy = 0;
+ }
+ maxh = src->h - srcy;
+ if (maxh < h)
+ h = maxh;
- } else {
- srcx = srcy = 0;
- w = src->w;
- h = src->h;
- }
+ } else {
+ srcx = srcy = 0;
+ w = src->w;
+ h = src->h;
+ }
- /*
- * Clip the destination rectangle against the clip rectangle
- */
- {
- SDL_Rect *clip = &dst->clip_rect;
- int dx, dy;
+ /*
+ * Clip the destination rectangle against the clip rectangle
+ */
+ {
+ SDL_Rect *clip = &dst->clip_rect;
+ int dx, dy;
- dx = clip->x - dr.x;
- if (dx > 0) {
- w -= dx;
- dr.x += dx;
- srcx += dx;
- }
- dx = dr.x + w - clip->x - clip->w;
- if (dx > 0)
- w -= dx;
+ dx = clip->x - dr.x;
+ if (dx > 0) {
+ w -= dx;
+ dr.x += dx;
+ srcx += dx;
+ }
+ dx = dr.x + w - clip->x - clip->w;
+ if (dx > 0)
+ w -= dx;
- dy = clip->y - dr.y;
- if (dy > 0) {
- h -= dy;
- dr.y += dy;
- srcy += dy;
- }
- dy = dr.y + h - clip->y - clip->h;
- if (dy > 0)
- h -= dy;
- }
+ dy = clip->y - dr.y;
+ if (dy > 0) {
+ h -= dy;
+ dr.y += dy;
+ srcy += dy;
+ }
+ dy = dr.y + h - clip->y - clip->h;
+ if (dy > 0)
+ h -= dy;
+ }
- if (w > 0 && h > 0) {
- sr.x = srcx;
- sr.y = srcy;
- sr.w = dr.w = w;
- sr.h = dr.h = h;
- return (SDL_gfxBlitRGBACall(src, &sr, dst, &dr));
- }
- return 0;
+ if (w > 0 && h > 0) {
+ sr.x = srcx;
+ sr.y = srcy;
+ sr.w = dr.w = w;
+ sr.h = dr.h = h;
+ return (_SDL_gfxBlitRGBACall(src, &sr, dst, &dr));
+ }
+
+ return 0;
}
-/* Helper function that sets the alpha channel in a 32bit surface */
+/*!
+\brief Sets the alpha channel in a 32 bit surface.
+Helper function that sets the alpha channel in a 32 bit surface
+to a constant value.
+Only 32 bit surfaces can be used with this function.
+
+\param src Pointer to the target surface to change.
+\param a The alpha value to set.
+
+\return Returns 1 if alpha was changed, 0 otherwise.
+*/
int SDL_gfxSetAlpha(SDL_Surface *src, Uint8 a)
{
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
@@ -457,25 +508,69 @@ int SDL_gfxSetAlpha(SDL_Surface *src, Uint8 a)
Uint16 alpha_offset = 3;
#endif
Uint16 i, j;
-
+
/* Check if we have a 32bit surface */
if ( (src) && (src->format) && (src->format->BytesPerPixel==4) ) {
- /* Lock and process */
- if ( SDL_LockSurface(src) == 0 ) {
- Uint8 *pixels = (Uint8 *)src->pixels;
- Uint16 row_skip = (src->pitch - (4*src->w));
- pixels += alpha_offset;
- for ( i=0; ih; i++ ) {
- for ( j=0; jw; j++ ) {
- *pixels = a;
- pixels += 4;
- }
- pixels += row_skip;
- }
- SDL_UnlockSurface(src);
- }
- return 1;
- } else {
- return 0;
- }
+ /* Lock and process */
+ if ( SDL_LockSurface(src) == 0 ) {
+ Uint8 *pixels = (Uint8 *)src->pixels;
+ Uint16 row_skip = (src->pitch - (4*src->w));
+ pixels += alpha_offset;
+ for ( i=0; ih; i++ ) {
+ for ( j=0; jw; j++ ) {
+ *pixels = a;
+ pixels += 4;
+ }
+ pixels += row_skip;
+ }
+ SDL_UnlockSurface(src);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/*!
+\brief Multiply the alpha channel in a 32bit surface.
+
+Helper function that multiplies the alpha channel in a 32 bit surface
+with a constant value. The final alpha is always scaled to the range
+0-255 (i.e. the factor is a/256).
+Only 32 bit surfaces can be used with this function.
+
+\param src Pointer to the target surface to change.
+\param a The alpha value to multiply with.
+
+\return Returns 1 if alpha was changed, 0 otherwise.
+*/
+int SDL_gfxMultiplyAlpha(SDL_Surface *src, Uint8 a)
+{
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ Uint16 alpha_offset = 0;
+#else
+ Uint16 alpha_offset = 3;
+#endif
+ Uint16 i, j;
+
+ /* Check if we have a 32bit surface */
+ if ( (src) && (src->format) && (src->format->BytesPerPixel==4) && (a!=255) ) {
+ /* Lock and process */
+ if ( SDL_LockSurface(src) == 0 ) {
+ Uint8 *pixels = (Uint8 *)src->pixels;
+ Uint16 row_skip = (src->pitch - (4*src->w));
+ pixels += alpha_offset;
+ for ( i=0; ih; i++ ) {
+ for ( j=0; jw; j++ ) {
+ *pixels = (Uint8)(((int)(*pixels)*a)>>8);
+ pixels += 4;
+ }
+ pixels += row_skip;
+ }
+ SDL_UnlockSurface(src);
+ }
+ return 1;
+ }
+
+ return 0;
}
diff --git a/src/sdl-instead/SDL_gfxBlitFunc.h b/src/sdl-instead/SDL_gfxBlitFunc.h
index 527b051..2690de1 100644
--- a/src/sdl-instead/SDL_gfxBlitFunc.h
+++ b/src/sdl-instead/SDL_gfxBlitFunc.h
@@ -1,9 +1,9 @@
/*
- SDL_gfxBlitFunc: custom blitters (part of SDL_gfx library)
+SDL_gfxBlitFunc: custom blitters (part of SDL_gfx library)
+
+LGPL (c) A. Schiffler
- LGPL (c) A. Schiffler
-
*/
#ifndef _SDL_gfxBlitFunc_h
@@ -20,87 +20,123 @@ extern "C" {
#include
#include
-int SDL_gfxBlitRGBA(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect);
+ /* ---- Function Prototypes */
-int SDL_gfxSetAlpha(SDL_Surface * src, Uint8 a);
+#if defined(WIN32) || defined(WIN64)
+# if defined(DLL_EXPORT) && !defined(LIBSDL_GFX_DLL_IMPORT)
+# define SDL_GFXBLITFUNC_SCOPE __declspec(dllexport)
+# else
+# ifdef LIBSDL_GFX_DLL_IMPORT
+# define SDL_GFXBLITFUNC_SCOPE __declspec(dllimport)
+# endif
+# endif
+#endif
+#ifndef SDL_GFXBLITFUNC_SCOPE
+# define SDL_GFXBLITFUNC_SCOPE extern
+#endif
-/* -------- Macros */
+ SDL_GFXBLITFUNC_SCOPE int SDL_gfxBlitRGBA(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect);
-/* Define SDL macros locally as a substitute for a #include "SDL_blit.h", */
+ SDL_GFXBLITFUNC_SCOPE int SDL_gfxSetAlpha(SDL_Surface * src, Uint8 a);
-/* which doesn't work since the include file doesn't get installed. */
+ SDL_GFXBLITFUNC_SCOPE int SDL_gfxMultiplyAlpha(SDL_Surface * src, Uint8 a);
-/* The structure passed to the low level blit functions */
- typedef struct {
- Uint8 *s_pixels;
- int s_width;
- int s_height;
- int s_skip;
- Uint8 *d_pixels;
- int d_width;
- int d_height;
- int d_skip;
- void *aux_data;
- SDL_PixelFormat *src;
- Uint8 *table;
- SDL_PixelFormat *dst;
- } SDL_gfxBlitInfo;
+ /* -------- Macros */
+ /* Define SDL macros locally as a substitute for an #include "SDL_blit.h", */
+ /* which doesn't work since the include file doesn't get installed. */
+
+/*!
+\brief The structure passed to the low level blit functions.
+*/
+ typedef struct {
+ Uint8 *s_pixels;
+ int s_width;
+ int s_height;
+ int s_skip;
+ Uint8 *d_pixels;
+ int d_width;
+ int d_height;
+ int d_skip;
+ void *aux_data;
+ SDL_PixelFormat *src;
+ Uint8 *table;
+ SDL_PixelFormat *dst;
+ } SDL_gfxBlitInfo;
+
+/*!
+\brief Unwrap RGBA values from a pixel using mask, shift and loss for surface.
+*/
#define GFX_RGBA_FROM_PIXEL(pixel, fmt, r, g, b, a) \
-{ \
+ { \
r = ((pixel&fmt->Rmask)>>fmt->Rshift)<Rloss; \
g = ((pixel&fmt->Gmask)>>fmt->Gshift)<Gloss; \
b = ((pixel&fmt->Bmask)>>fmt->Bshift)<Bloss; \
a = ((pixel&fmt->Amask)>>fmt->Ashift)<Aloss; \
-}
+ }
+/*!
+\brief Disassemble buffer pointer into a pixel and separate RGBA values.
+*/
#define GFX_DISEMBLE_RGBA(buf, bpp, fmt, pixel, r, g, b, a) \
-do { \
+ do { \
pixel = *((Uint32 *)(buf)); \
GFX_RGBA_FROM_PIXEL(pixel, fmt, r, g, b, a); \
pixel &= ~fmt->Amask; \
-} while(0)
+ } while(0)
+/*!
+\brief Wrap a pixel from RGBA values using mask, shift and loss for surface.
+*/
#define GFX_PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a) \
-{ \
+ { \
pixel = ((r>>fmt->Rloss)<Rshift)| \
- ((g>>fmt->Gloss)<Gshift)| \
- ((b>>fmt->Bloss)<Bshift)| \
- ((a<Aloss)<Ashift); \
-}
+ ((g>>fmt->Gloss)<Gshift)| \
+ ((b>>fmt->Bloss)<Bshift)| \
+ ((a<Aloss)<Ashift); \
+ }
+/*!
+\brief Assemble pixel into buffer pointer from separate RGBA values.
+*/
#define GFX_ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a) \
-{ \
- Uint32 pixel; \
- \
- GFX_PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a); \
- *((Uint32 *)(buf)) = pixel; \
-}
+ { \
+ Uint32 pixel; \
+ \
+ GFX_PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a); \
+ *((Uint32 *)(buf)) = pixel; \
+ }
-/* Blend the RGB values of two pixels based on a source alpha value */
+/*!
+\brief Blend the RGB values of two pixels based on a source alpha value.
+*/
#define GFX_ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB) \
-do { \
+ do { \
dR = (((sR-dR)*(A))/255)+dR; \
dG = (((sG-dG)*(A))/255)+dG; \
dB = (((sB-dB)*(A))/255)+dB; \
-} while(0)
+ } while(0)
-/* This is a very useful loop for optimizing blitters */
+/*!
+\brief 4-times unrolled DUFFs loop.
-/* 4-times unrolled loop */
+This is a very useful loop for optimizing blitters.
+*/
#define GFX_DUFFS_LOOP4(pixel_copy_increment, width) \
-{ int n = (width+3)/4; \
+ { int n = (width+3)/4; \
switch (width & 3) { \
case 0: do { pixel_copy_increment; \
case 3: pixel_copy_increment; \
case 2: pixel_copy_increment; \
case 1: pixel_copy_increment; \
- } while ( --n > 0 ); \
+ } while ( --n > 0 ); \
} \
-}
+ }
-/* Ends C function definitions when using C++ */
+
+
+ /* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
diff --git a/src/sdl-instead/SDL_rotozoom.c b/src/sdl-instead/SDL_rotozoom.c
index 1abf7f4..5a20279 100644
--- a/src/sdl-instead/SDL_rotozoom.c
+++ b/src/sdl-instead/SDL_rotozoom.c
@@ -1,1356 +1,1638 @@
-/*
-
- SDL_rotozoom.c - rotozoomer for 32bit or 8bit surfaces
-
- LGPL (c) A. Schiffler
+/*
+
+SDL_rotozoom.c - rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces
+
+LGPL (c) A. Schiffler
+
+*/
+
+#ifdef WIN32
+#include
+#endif
+
+#include
+#include
+
+#include "SDL_rotozoom.h"
+
+/* ---- Internally used structures */
+/*!
+\brief A 32 bit RGBA pixel.
*/
+typedef struct tColorRGBA {
+ Uint8 r;
+ Uint8 g;
+ Uint8 b;
+ Uint8 a;
+} tColorRGBA;
-#ifdef WIN32
-#include
-#endif
-
-#include
-#include
-
-#include "SDL_rotozoom.h"
-
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-
-
-/*
-
- 32bit integer-factor averaging Shrinker
-
- Shrinks 32bit RGBA/ABGR 'src' surface to 'dst' surface.
-
+/*!
+\brief A 8bit Y/palette pixel.
*/
-
-int shrinkSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory)
-{
- int x, y, dx, dy, sgap, dgap, ra, ga, ba, aa;
- int n_average;
- tColorRGBA *sp, *osp, *oosp;
- tColorRGBA *dp;
-
- /*
- * Averaging integer shrink
- */
-
- /* Precalculate division factor */
- n_average = factorx*factory;
-
- /*
- * Scan destination
- */
- sp = (tColorRGBA *) src->pixels;
- sgap = src->pitch - src->w * 4;
-
- dp = (tColorRGBA *) dst->pixels;
- dgap = dst->pitch - dst->w * 4;
-
- for (y = 0; y < dst->h; y++) {
-
- osp=sp;
- for (x = 0; x < dst->w; x++) {
-
- /* Trace out source box and accumulate */
- oosp=sp;
- ra=ga=ba=aa=0;
- for (dy=0; dy < factory; dy++) {
- for (dx=0; dx < factorx; dx++) {
- ra += sp->r;
- ga += sp->g;
- ba += sp->b;
- aa += sp->a;
-
- sp++;
- }
- /* src dx loop */
- sp = (tColorRGBA *)((Uint8*)sp + (src->pitch - 4*factorx)); // next y
- }
- /* src dy loop */
-
- /* next box-x */
- sp = (tColorRGBA *)((Uint8*)oosp + 4*factorx);
-
- /* Store result in destination */
- dp->r = ra/n_average;
- dp->g = ga/n_average;
- dp->b = ba/n_average;
- dp->a = aa/n_average;
-
- /*
- * Advance destination pointer
- */
- dp++;
- }
- /* dst x loop */
-
- /* next box-y */
- sp = (tColorRGBA *)((Uint8*)osp + src->pitch*factory);
-
- /*
- * Advance destination pointers
- */
- dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
- }
- /* dst y loop */
-
- return (0);
-}
-
-/*
-
- 8bit integer-factor averaging Shrinker
-
- Shrinks 8bit Y 'src' surface to 'dst' surface.
-
-*/
-
-int shrinkSurfaceY(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory)
-{
- int x, y, dx, dy, sgap, dgap, a;
- int n_average;
- Uint8 *sp, *osp, *oosp;
- Uint8 *dp;
-
- /*
- * Averaging integer shrink
- */
-
- /* Precalculate division factor */
- n_average = factorx*factory;
-
- /*
- * Scan destination
- */
- sp = (Uint8 *) src->pixels;
- sgap = src->pitch - src->w;
-
- dp = (Uint8 *) dst->pixels;
- dgap = dst->pitch - dst->w;
-
- for (y = 0; y < dst->h; y++) {
-
- osp=sp;
- for (x = 0; x < dst->w; x++) {
-
- /* Trace out source box and accumulate */
- oosp=sp;
- a=0;
- for (dy=0; dy < factory; dy++) {
- for (dx=0; dx < factorx; dx++) {
- a += (*sp);
- /* next x */
- sp++;
- }
- /* end src dx loop */
- /* next y */
- sp = (Uint8 *)((Uint8*)sp + (src->pitch - factorx));
- }
- /* end src dy loop */
-
- /* next box-x */
- sp = (Uint8 *)((Uint8*)oosp + factorx);
-
- /* Store result in destination */
- *dp = a/n_average;
-
- /*
- * Advance destination pointer
- */
- dp++;
- }
- /* end dst x loop */
-
- /* next box-y */
- sp = (Uint8 *)((Uint8*)osp + src->pitch*factory);
-
- /*
- * Advance destination pointers
- */
- dp = (Uint8 *)((Uint8 *)dp + dgap);
- }
- /* end dst y loop */
-
- return (0);
-}
-
-/*
-
- 32bit Zoomer with optional anti-aliasing by bilinear interpolation.
-
- Zoomes 32bit RGBA/ABGR 'src' surface to 'dst' surface.
-
-*/
-
-int zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, int smooth)
-{
- int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep, lx, ly;
- tColorRGBA *c00, *c01, *c10, *c11, *cswap;
- tColorRGBA *sp, *csp, *dp;
- int dgap;
-
- /*
- * Variable setup
- */
- if (smooth) {
- /*
- * For interpolation: assume source dimension is one pixel
- */
- /*
- * smaller to avoid overflow on right and bottom edge.
- */
- sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w);
- sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h);
- } else {
- sx = (int) (65536.0 * (float) src->w / (float) dst->w);
- sy = (int) (65536.0 * (float) src->h / (float) dst->h);
- }
-
- /*
- * Allocate memory for row increments
- */
- if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
- return (-1);
- }
- if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
- free(sax);
- return (-1);
- }
-
- /*
- * Precalculate row increments
- */
- sp = csp = (tColorRGBA *) src->pixels;
- dp = (tColorRGBA *) dst->pixels;
-
- if (flipx) csp += (src->w-1);
- if (flipy) csp += (src->pitch*(src->h-1));
-
- csx = 0;
- csax = sax;
- for (x = 0; x <= dst->w; x++) {
- *csax = csx;
- csax++;
- csx &= 0xffff;
- csx += sx;
- }
- csy = 0;
- csay = say;
- for (y = 0; y <= dst->h; y++) {
- *csay = csy;
- csay++;
- csy &= 0xffff;
- csy += sy;
- }
-
- dgap = dst->pitch - dst->w * 4;
-
- /*
- * Switch between interpolating and non-interpolating code
- */
- if (smooth) {
-
- /*
- * Interpolating Zoom
- */
-
- /*
- * Scan destination
- */
- ly = 0;
- csay = say;
- for (y = 0; y < dst->h; y++) {
- /*
- * Setup color source pointers
- */
- c00 = csp;
- c01 = csp;
- c01++;
- c10 = (tColorRGBA *) ((Uint8 *) csp + src->pitch);
- c11 = c10;
- c11++;
- csax = sax;
- if (flipx) {
- cswap = c00; c00=c01; c01=cswap;
- cswap = c10; c10=c11; c11=cswap;
- }
- if (flipy) {
- cswap = c00; c00=c10; c10=cswap;
- cswap = c01; c01=c11; c11=cswap;
- }
- lx = 0;
- for (x = 0; x < dst->w; x++) {
- /*
- * Interpolate colors
- */
- ex = (*csax & 0xffff);
- ey = (*csay & 0xffff);
- t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff;
- t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff;
- dp->r = (((t2 - t1) * ey) >> 16) + t1;
- t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff;
- t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff;
- dp->g = (((t2 - t1) * ey) >> 16) + t1;
- t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff;
- t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff;
- dp->b = (((t2 - t1) * ey) >> 16) + t1;
- t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff;
- t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff;
- dp->a = (((t2 - t1) * ey) >> 16) + t1;
-
- /*
- * Advance source pointers
- */
- csax++;
- sstep = (*csax >> 16);
- lx += sstep;
- if (lx >= src->w) sstep = 0;
- if (flipx) sstep = -sstep;
- c00 += sstep;
- c01 += sstep;
- c10 += sstep;
- c11 += sstep;
- /*
- * Advance destination pointer
- */
- dp++;
- }
- /*
- * Advance source pointer
- */
- csay++;
- sstep = (*csay >> 16);
- ly += sstep;
- if (ly >= src->h) sstep = 0;
- sstep *= src->pitch;
- if (flipy) sstep = -sstep;
- csp = (tColorRGBA *) ((Uint8 *) csp + sstep);
-
- /*
- * Advance destination pointers
- */
- dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
- }
- } else {
-
- /*
- * Non-Interpolating Zoom
- */
-
- csay = say;
- for (y = 0; y < dst->h; y++) {
- sp = csp;
- csax = sax;
- for (x = 0; x < dst->w; x++) {
- /*
- * Draw
- */
- *dp = *sp;
- /*
- * Advance source pointers
- */
- csax++;
- sstep = (*csax >> 16);
- if (flipx) sstep = -sstep;
- sp += sstep;
- /*
- * Advance destination pointer
- */
- dp++;
- }
- /*
- * Advance source pointer
- */
- csay++;
- sstep = (*csay >> 16) * src->pitch;
- if (flipy) sstep = -sstep;
- csp = (tColorRGBA *) ((Uint8 *) csp + sstep);
-
- /*
- * Advance destination pointers
- */
- dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
- }
- }
-
- /*
- * Remove temp arrays
- */
- free(sax);
- free(say);
-
- return (0);
-}
-
-/*
-
- 8bit Zoomer without smoothing.
-
- Zoomes 8bit palette/Y 'src' surface to 'dst' surface.
-
-*/
-
-int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy)
-{
- Uint32 x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, sstep;
- Uint8 *sp, *dp, *csp;
- int dgap;
-
- /*
- * Variable setup
- */
- sx = (Uint32) (65536.0 * (float) src->w / (float) dst->w);
- sy = (Uint32) (65536.0 * (float) src->h / (float) dst->h);
-
-
- /*
- * Allocate memory for row increments
- */
- if ((sax = (Uint32 *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
- return (-1);
- }
- if ((say = (Uint32 *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
- free(sax);
- return (-1);
- }
-
- /*
- * Pointer setup
- */
- sp = csp = (Uint8 *) src->pixels;
- dp = (Uint8 *) dst->pixels;
- dgap = dst->pitch - dst->w;
-
- if (flipx) csp += (src->w-1);
- if (flipy) csp = ( (Uint8*)csp + src->pitch*(src->h-1) );
-
- /*
- * Precalculate row increments
- */
- csx = 0;
- csax = sax;
- for (x = 0; x <= dst->w; x++) {
- *csax = csx;
- csax++;
- csx &= 0xffff;
- csx += sx;
- }
- csy = 0;
- csay = say;
- for (y = 0; y <= dst->h; y++) {
- *csay = csy;
- csay++;
- csy &= 0xffff;
- csy += sy;
- }
-
-
- /*
- * Draw
- */
- csay = say;
- for (y = 0; y < dst->h; y++) {
- csax = sax;
- sp = csp;
- for (x = 0; x < dst->w; x++) {
- /*
- * Draw
- */
- *dp = *sp;
- /*
- * Advance source pointers
- */
- csax++;
- sstep = (*csax >> 16);
- if (flipx) sstep = -sstep;
- sp += sstep;
- /*
- * Advance destination pointer
- */
- dp++;
- }
- /*
- * Advance source pointer (for row)
- */
- csay++;
- sstep = (*csay >> 16) * src->pitch;
- if (flipy) sstep = -sstep;
- csp = ((Uint8 *) csp + sstep);
-
- /*
- * Advance destination pointers
- */
- dp += dgap;
- }
-
- /*
- * Remove temp arrays
- */
- free(sax);
- free(say);
-
- return (0);
-}
-
-/*
-
- 32bit Rotozoomer with optional anti-aliasing by bilinear interpolation.
-
- Rotates and zoomes 32bit RGBA/ABGR 'src' surface to 'dst' surface.
-
-*/
-
-void transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth)
-{
- int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh;
- tColorRGBA c00, c01, c10, c11, cswap;
- tColorRGBA *pc, *sp;
- int gap;
-
- /*
- * Variable setup
- */
- xd = ((src->w - dst->w) << 15);
- yd = ((src->h - dst->h) << 15);
- ax = (cx << 16) - (icos * cx);
- ay = (cy << 16) - (isin * cx);
- sw = src->w - 1;
- sh = src->h - 1;
- pc = dst->pixels;
- gap = dst->pitch - dst->w * 4;
-
- /*
- * Switch between interpolating and non-interpolating code
- */
- if (smooth) {
- for (y = 0; y < dst->h; y++) {
- dy = cy - y;
- sdx = (ax + (isin * dy)) + xd;
- sdy = (ay - (icos * dy)) + yd;
- for (x = 0; x < dst->w; x++) {
- dx = (sdx >> 16);
- dy = (sdy >> 16);
- if ((dx > -1) && (dy > -1) && (dx < src->w) && (dy < src->h)) {
- if (flipx) dx = sw - dx;
- if (flipy) dy = sh - dy;
- sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
- sp += dx;
- c00 = *sp;
- sp += 1;
- c01 = *sp;
- sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch);
- c11 = *sp;
- sp -= 1;
- c10 = *sp;
- if (flipx) {
- cswap = c00; c00=c01; c01=cswap;
- cswap = c10; c10=c11; c11=cswap;
- }
- if (flipy) {
- cswap = c00; c00=c10; c10=cswap;
- cswap = c01; c01=c11; c11=cswap;
- }
- /*
- * Interpolate colors
- */
- ex = (sdx & 0xffff);
- ey = (sdy & 0xffff);
- t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff;
- t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff;
- pc->r = (((t2 - t1) * ey) >> 16) + t1;
- t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff;
- t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff;
- pc->g = (((t2 - t1) * ey) >> 16) + t1;
- t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff;
- t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff;
- pc->b = (((t2 - t1) * ey) >> 16) + t1;
- t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff;
- t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff;
- pc->a = (((t2 - t1) * ey) >> 16) + t1;
- }
- sdx += icos;
- sdy += isin;
- pc++;
- }
- pc = (tColorRGBA *) ((Uint8 *) pc + gap);
- }
- } else {
- for (y = 0; y < dst->h; y++) {
- dy = cy - y;
- sdx = (ax + (isin * dy)) + xd;
- sdy = (ay - (icos * dy)) + yd;
- for (x = 0; x < dst->w; x++) {
- dx = (short) (sdx >> 16);
- dy = (short) (sdy >> 16);
- if (flipx) dx = (src->w-1)-dx;
- if (flipy) dy = (src->h-1)-dy;
- if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) {
- sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
- sp += dx;
- *pc = *sp;
- }
- sdx += icos;
- sdy += isin;
- pc++;
- }
- pc = (tColorRGBA *) ((Uint8 *) pc + gap);
- }
- }
-}
-
-/*
-
- 8bit Rotozoomer without smoothing
-
- Rotates and zoomes 8bit palette/Y 'src' surface to 'dst' surface.
-
-*/
-
-void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy)
-{
- int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay, sw, sh;
- tColorY *pc, *sp;
- int gap;
-
- /*
- * Variable setup
- */
- xd = ((src->w - dst->w) << 15);
- yd = ((src->h - dst->h) << 15);
- ax = (cx << 16) - (icos * cx);
- ay = (cy << 16) - (isin * cx);
- sw = src->w - 1;
- sh = src->h - 1;
- pc = dst->pixels;
- gap = dst->pitch - dst->w;
- /*
- * Clear surface to colorkey
- */
- memset(pc, (unsigned char) (src->format->colorkey & 0xff), dst->pitch * dst->h);
- /*
- * Iterate through destination surface
- */
- for (y = 0; y < dst->h; y++) {
- dy = cy - y;
- sdx = (ax + (isin * dy)) + xd;
- sdy = (ay - (icos * dy)) + yd;
- for (x = 0; x < dst->w; x++) {
- dx = (short) (sdx >> 16);
- dy = (short) (sdy >> 16);
- if (flipx) dx = (src->w-1)-dx;
- if (flipy) dy = (src->h-1)-dy;
- if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) {
- sp = (tColorY *) (src->pixels);
- sp += (src->pitch * dy + dx);
- *pc = *sp;
- }
- sdx += icos;
- sdy += isin;
- pc++;
- }
- pc += gap;
- }
-}
-
-/*
-
- 32bit specialized 90degree rotator
-
- Rotates and zooms 'src' surface to 'dst' surface in 90degree increments.
-
- (contributed by Jeff Schiller)
-
-*/
-SDL_Surface* rotateSurface90Degrees(SDL_Surface* pSurf, int numClockwiseTurns)
-{
- int row, col, newWidth, newHeight;
- SDL_Surface* pSurfOut;
-
- /* Has to be a valid surface pointer and only 32-bit surfaces (for now) */
- if (!pSurf || pSurf->format->BitsPerPixel != 32) { return NULL; }
-
- /* normalize numClockwiseTurns */
- while(numClockwiseTurns < 0) { numClockwiseTurns += 4; }
- numClockwiseTurns = (numClockwiseTurns % 4);
-
- /* if it's even, our new width will be the same as the source surface */
- newWidth = (numClockwiseTurns % 2) ? (pSurf->h) : (pSurf->w);
- newHeight = (numClockwiseTurns % 2) ? (pSurf->w) : (pSurf->h);
- pSurfOut = SDL_CreateRGBSurface( pSurf->flags, newWidth, newHeight, pSurf->format->BitsPerPixel,
- pSurf->format->Rmask,
- pSurf->format->Gmask,
- pSurf->format->Bmask,
- pSurf->format->Amask);
- if(!pSurfOut) {
- return NULL;
- }
-
- if(numClockwiseTurns != 0) {
- SDL_LockSurface(pSurf);
- SDL_LockSurface(pSurfOut);
- switch(numClockwiseTurns) {
-
- /* rotate clockwise */
- case 1: /* rotated 90 degrees clockwise */
- {
- Uint32* srcBuf = NULL;
- Uint32* dstBuf = NULL;
-
- for (row = 0; row < pSurf->h; ++row) {
- srcBuf = (Uint32*)(pSurf->pixels) + (row*pSurf->pitch/4);
- dstBuf = (Uint32*)(pSurfOut->pixels) + (pSurfOut->w - row - 1);
- for (col = 0; col < pSurf->w; ++col) {
- *dstBuf = *srcBuf;
- ++srcBuf;
- dstBuf += pSurfOut->pitch/4;
- }
- /* end for(col) */
- }
- /* end for(row) */
- }
- break;
-
- case 2: /* rotated 180 degrees clockwise */
- {
- Uint32* srcBuf = NULL;
- Uint32* dstBuf = NULL;
-
- for(row = 0; row < pSurf->h; ++row) {
- srcBuf = (Uint32*)(pSurf->pixels) + (row*pSurf->pitch/4);
- dstBuf = (Uint32*)(pSurfOut->pixels) + ((pSurfOut->h - row - 1)*pSurfOut->pitch/4) + (pSurfOut->w - 1);
- for(col = 0; col < pSurf->w; ++col) {
- *dstBuf = *srcBuf;
- ++srcBuf;
- --dstBuf;
- }
- }
- }
- break;
-
- case 3:
- {
- Uint32* srcBuf = NULL;
- Uint32* dstBuf = NULL;
-
- for(row = 0; row < pSurf->h; ++row) {
- srcBuf = (Uint32*)(pSurf->pixels) + (row*pSurf->pitch/4);
- dstBuf = (Uint32*)(pSurfOut->pixels) + row + ((pSurfOut->h - 1)*pSurfOut->pitch/4);
- for(col = 0; col < pSurf->w; ++col) {
- *dstBuf = *srcBuf;
- ++srcBuf;
- dstBuf -= pSurfOut->pitch/4;
- }
- }
- }
- break;
- }
- /* end switch */
-
- SDL_UnlockSurface(pSurf);
- SDL_UnlockSurface(pSurfOut);
- }
- /* end if numClockwiseTurns > 0 */
- else {
- /* simply copy surface to output */
- if(SDL_BlitSurface(pSurf, NULL, pSurfOut, NULL)) {
- return NULL;
- }
- }
- return pSurfOut;
-}
-
-/*
-
- rotozoomSurface()
-
- Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface.
- 'angle' is the rotation in degrees. 'zoom' a scaling factor. If 'smooth' is 1
- then the destination 32bit surface is anti-aliased. If the surface is not 8bit
- or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
-
-*/
-
-#define VALUE_LIMIT 0.001
-
-/* Local rotozoom-size function with trig result return */
-
-void rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoomx, double zoomy, int *dstwidth, int *dstheight,
- double *canglezoom, double *sanglezoom)
-{
- double x, y, cx, cy, sx, sy;
- double radangle;
- int dstwidthhalf, dstheighthalf;
-
- /*
- * Determine destination width and height by rotating a centered source box
- */
- radangle = angle * (M_PI / 180.0);
- *sanglezoom = sin(radangle);
- *canglezoom = cos(radangle);
- *sanglezoom *= zoomx;
- *canglezoom *= zoomx;
- x = width / 2;
- y = height / 2;
- cx = *canglezoom * x;
- cy = *canglezoom * y;
- sx = *sanglezoom * x;
- sy = *sanglezoom * y;
-
- dstwidthhalf = MAX((int)
- ceil(MAX(MAX(MAX(fabs(cx + sy), fabs(cx - sy)), fabs(-cx + sy)), fabs(-cx - sy))), 1);
- dstheighthalf = MAX((int)
- ceil(MAX(MAX(MAX(fabs(sx + cy), fabs(sx - cy)), fabs(-sx + cy)), fabs(-sx - cy))), 1);
- *dstwidth = 2 * dstwidthhalf;
- *dstheight = 2 * dstheighthalf;
-}
-
-
-/* Publically available rotozoom-size function */
-
-void rotozoomSurfaceSizeXY(int width, int height, double angle, double zoomx, double zoomy, int *dstwidth, int *dstheight)
-{
- double dummy_sanglezoom, dummy_canglezoom;
-
- rotozoomSurfaceSizeTrig(width, height, angle, zoomx, zoomy, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom);
-}
-
-/* Publically available rotozoom-size function */
-
-void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight)
-{
- double dummy_sanglezoom, dummy_canglezoom;
-
- rotozoomSurfaceSizeTrig(width, height, angle, zoom, zoom, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom);
-}
-
-/* Publically available rotozoom function */
-
-SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth)
-{
- return rotozoomSurfaceXY(src, angle, zoom, zoom, smooth);
-}
-
-/* Publically available rotozoom function */
-
-SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth)
-{
- SDL_Surface *rz_src;
- SDL_Surface *rz_dst;
- double zoominv;
- double sanglezoom, canglezoom, sanglezoominv, canglezoominv;
- int dstwidthhalf, dstwidth, dstheighthalf, dstheight;
- int is32bit;
- int i, src_converted;
- int flipx,flipy;
- Uint8 r,g,b;
- Uint32 colorkey;
- int colorKeyAvailable = 0;
-
- /*
- * Sanity check
- */
- if (src == NULL)
- return (NULL);
-
- if( src->flags & SDL_SRCCOLORKEY )
- {
- colorkey = src->format->colorkey;
- SDL_GetRGB(colorkey, src->format, &r, &g, &b);
- colorKeyAvailable = 1;
- }
- /*
- * Determine if source surface is 32bit or 8bit
- */
- is32bit = (src->format->BitsPerPixel == 32);
- if ((is32bit) || (src->format->BitsPerPixel == 8)) {
- /*
- * Use source surface 'as is'
- */
- rz_src = src;
- src_converted = 0;
- } else {
- /*
- * New source surface is 32bit with a defined RGBA ordering
- */
- rz_src =
- SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32,
-#if SDL_BYTEORDER == SDL_LIL_ENDIAN
- 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
-#else
- 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff
-#endif
- );
- if(colorKeyAvailable)
- SDL_SetColorKey(src, 0, 0);
-
- SDL_BlitSurface(src, NULL, rz_src, NULL);
-
- if(colorKeyAvailable)
- SDL_SetColorKey(src, SDL_SRCCOLORKEY, colorkey);
- src_converted = 1;
- is32bit = 1;
- }
-
- /*
- * Sanity check zoom factor
- */
- flipx = (zoomx<0.0);
- if (flipx) zoomx=-zoomx;
- flipy = (zoomy<0.0);
- if (flipy) zoomy=-zoomy;
- if (zoomx < VALUE_LIMIT) zoomx = VALUE_LIMIT;
- if (zoomy < VALUE_LIMIT) zoomy = VALUE_LIMIT;
- zoominv = 65536.0 / (zoomx * zoomx);
-
- /*
- * Check if we have a rotozoom or just a zoom
- */
- if (fabs(angle) > VALUE_LIMIT) {
-
- /*
- * Angle!=0: full rotozoom
- */
- /*
- * -----------------------
- */
-
- /* Determine target size */
- rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoomx, zoomy, &dstwidth, &dstheight, &canglezoom, &sanglezoom);
-
- /*
- * Calculate target factors from sin/cos and zoom
- */
- sanglezoominv = sanglezoom;
- canglezoominv = canglezoom;
- sanglezoominv *= zoominv;
- canglezoominv *= zoominv;
-
- /* Calculate half size */
- dstwidthhalf = dstwidth / 2;
- dstheighthalf = dstheight / 2;
-
- /*
- * Alloc space to completely contain the rotated surface
- */
- rz_dst = NULL;
- if (is32bit) {
- /*
- * Target surface is 32bit with source RGBA/ABGR ordering
- */
- rz_dst =
- SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32,
- rz_src->format->Rmask, rz_src->format->Gmask,
- rz_src->format->Bmask, rz_src->format->Amask);
- } else {
- /*
- * Target surface is 8bit
- */
- rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
- }
-
- if (colorKeyAvailable == 1){
- colorkey = SDL_MapRGB(rz_dst->format, r, g, b);
-
- SDL_FillRect(rz_dst, NULL, colorkey );
- }
-
- /*
- * Lock source surface
- */
- SDL_LockSurface(rz_src);
- /*
- * Check which kind of surface we have
- */
- if (is32bit) {
- /*
- * Call the 32bit transformation routine to do the rotation (using alpha)
- */
- transformSurfaceRGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
- (int) (sanglezoominv), (int) (canglezoominv),
- flipx, flipy,
- smooth);
- /*
- * Turn on source-alpha support
- */
- SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
- } else {
- /*
- * Copy palette and colorkey info
- */
- for (i = 0; i < rz_src->format->palette->ncolors; i++) {
- rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
- }
- rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
- /*
- * Call the 8bit transformation routine to do the rotation
- */
- transformSurfaceY(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
- (int) (sanglezoominv), (int) (canglezoominv),
- flipx, flipy);
- SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
- }
- /*
- * Unlock source surface
- */
- SDL_UnlockSurface(rz_src);
-
- } else {
-
- /*
- * Angle=0: Just a zoom
- */
- /*
- * --------------------
- */
-
- /*
- * Calculate target size
- */
- zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight);
-
- /*
- * Alloc space to completely contain the zoomed surface
- */
- rz_dst = NULL;
- if (is32bit) {
- /*
- * Target surface is 32bit with source RGBA/ABGR ordering
- */
- rz_dst =
- SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32,
- rz_src->format->Rmask, rz_src->format->Gmask,
- rz_src->format->Bmask, rz_src->format->Amask);
- } else {
- /*
- * Target surface is 8bit
- */
- rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
- }
-
- if (colorKeyAvailable == 1){
- colorkey = SDL_MapRGB(rz_dst->format, r, g, b);
-
- SDL_FillRect(rz_dst, NULL, colorkey );
- }
-
- /*
- * Lock source surface
- */
- SDL_LockSurface(rz_src);
- /*
- * Check which kind of surface we have
- */
- if (is32bit) {
- /*
- * Call the 32bit transformation routine to do the zooming (using alpha)
- */
- zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth);
- /*
- * Turn on source-alpha support
- */
- SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
- } else {
- /*
- * Copy palette and colorkey info
- */
- for (i = 0; i < rz_src->format->palette->ncolors; i++) {
- rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
- }
- rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
- /*
- * Call the 8bit transformation routine to do the zooming
- */
- zoomSurfaceY(rz_src, rz_dst, flipx, flipy);
- SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
- }
- /*
- * Unlock source surface
- */
- SDL_UnlockSurface(rz_src);
- }
-
- /*
- * Cleanup temp surface
- */
- if (src_converted) {
- SDL_FreeSurface(rz_src);
- }
-
- /*
- * Return destination surface
- */
- return (rz_dst);
-}
-
-/*
-
- zoomSurface()
-
- Zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface.
- 'zoomx' and 'zoomy' are scaling factors for width and height. If 'smooth' is 1
- then the destination 32bit surface is anti-aliased. If the surface is not 8bit
- or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
-
-*/
-
-#define VALUE_LIMIT 0.001
-
-void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight)
-{
- /*
- * Sanity check zoom factors
- */
- if (zoomx < VALUE_LIMIT) {
- zoomx = VALUE_LIMIT;
- }
- if (zoomy < VALUE_LIMIT) {
- zoomy = VALUE_LIMIT;
- }
-
- /*
- * Calculate target size
- */
- *dstwidth = (int) ((double) width * zoomx);
- *dstheight = (int) ((double) height * zoomy);
- if (*dstwidth < 1) {
- *dstwidth = 1;
- }
- if (*dstheight < 1) {
- *dstheight = 1;
- }
-}
-
-SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth)
-{
- SDL_Surface *rz_src;
- SDL_Surface *rz_dst;
- int dstwidth, dstheight;
- int is32bit;
- int i, src_converted;
- int flipx, flipy;
- /*
- * Sanity check
- */
- if (src == NULL)
- return (NULL);
-
- /*
- * Determine if source surface is 32bit or 8bit
- */
- is32bit = (src->format->BitsPerPixel == 32);
- if ((is32bit) || (src->format->BitsPerPixel == 8)) {
- /*
- * Use source surface 'as is'
- */
- rz_src = src;
- src_converted = 0;
- } else {
- /*
- * New source surface is 32bit with a defined RGBA ordering
- */
- rz_src =
- SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32,
-#if SDL_BYTEORDER == SDL_LIL_ENDIAN
- 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
-#else
- 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff
-#endif
- );
- SDL_BlitSurface(src, NULL, rz_src, NULL);
- src_converted = 1;
- is32bit = 1;
- }
-
- flipx = (zoomx<0.0);
- if (flipx) zoomx = -zoomx;
- flipy = (zoomy<0.0);
- if (flipy) zoomy = -zoomy;
-
- /* Get size if target */
- zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight);
-
- /*
- * Alloc space to completely contain the zoomed surface
- */
- rz_dst = NULL;
- if (is32bit) {
- /*
- * Target surface is 32bit with source RGBA/ABGR ordering
- */
- rz_dst =
- SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32,
- rz_src->format->Rmask, rz_src->format->Gmask,
- rz_src->format->Bmask, rz_src->format->Amask);
- } else {
- /*
- * Target surface is 8bit
- */
- rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
- }
-
- /*
- * Lock source surface
- */
- SDL_LockSurface(rz_src);
- /*
- * Check which kind of surface we have
- */
- if (is32bit) {
- /*
- * Call the 32bit transformation routine to do the zooming (using alpha)
- */
- zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth);
- /*
- * Turn on source-alpha support
- */
- SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
- } else {
- /*
- * Copy palette and colorkey info
- */
- for (i = 0; i < rz_src->format->palette->ncolors; i++) {
- rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
- }
- rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
- /*
- * Call the 8bit transformation routine to do the zooming
- */
- zoomSurfaceY(rz_src, rz_dst, flipx, flipy);
- if (rz_src->flags & SDL_SRCCOLORKEY)
- SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
- }
- /*
- * Unlock source surface
- */
- SDL_UnlockSurface(rz_src);
-
- /*
- * Cleanup temp surface
- */
- if (src_converted) {
- SDL_FreeSurface(rz_src);
- }
-
- /*
- * Return destination surface
- */
- return (rz_dst);
-}
-
-SDL_Surface *shrinkSurface(SDL_Surface * src, int factorx, int factory)
-{
- SDL_Surface *rz_src;
- SDL_Surface *rz_dst;
- int dstwidth, dstheight;
- int is32bit;
- int i, src_converted;
-
- /*
- * Sanity check
- */
- if (src == NULL)
- return (NULL);
-
- /*
- * Determine if source surface is 32bit or 8bit
- */
- is32bit = (src->format->BitsPerPixel == 32);
- if ((is32bit) || (src->format->BitsPerPixel == 8)) {
- /*
- * Use source surface 'as is'
- */
- rz_src = src;
- src_converted = 0;
- } else {
- /*
- * New source surface is 32bit with a defined RGBA ordering
- */
- rz_src =
- SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32,
-#if SDL_BYTEORDER == SDL_LIL_ENDIAN
- 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
-#else
- 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff
-#endif
- );
- SDL_BlitSurface(src, NULL, rz_src, NULL);
- src_converted = 1;
- is32bit = 1;
- }
-
- /* Get size for target */
- dstwidth=rz_src->w/factorx;
- while (dstwidth*factorx>rz_src->w) { dstwidth--; }
- dstheight=rz_src->h/factory;
- while (dstheight*factory>rz_src->h) { dstheight--; }
-
- /*
- * Alloc space to completely contain the shrunken surface
- */
- rz_dst = NULL;
- if (is32bit) {
- /*
- * Target surface is 32bit with source RGBA/ABGR ordering
- */
- rz_dst =
- SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32,
- rz_src->format->Rmask, rz_src->format->Gmask,
- rz_src->format->Bmask, rz_src->format->Amask);
- } else {
- /*
- * Target surface is 8bit
- */
- rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
- }
-
- /*
- * Lock source surface
- */
- SDL_LockSurface(rz_src);
- /*
- * Check which kind of surface we have
- */
- if (is32bit) {
- /*
- * Call the 32bit transformation routine to do the shrinking (using alpha)
- */
- shrinkSurfaceRGBA(rz_src, rz_dst, factorx, factory);
- /*
- * Turn on source-alpha support
- */
- SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
- } else {
- /*
- * Copy palette and colorkey info
- */
- for (i = 0; i < rz_src->format->palette->ncolors; i++) {
- rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
- }
- rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
- /*
- * Call the 8bit transformation routine to do the shrinking
- */
- shrinkSurfaceY(rz_src, rz_dst, factorx, factory);
- if (rz_src->flags & SDL_SRCCOLORKEY)
- SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
- }
- /*
- * Unlock source surface
- */
- SDL_UnlockSurface(rz_src);
-
- /*
- * Cleanup temp surface
- */
- if (src_converted) {
- SDL_FreeSurface(rz_src);
- }
-
- /*
- * Return destination surface
- */
- return (rz_dst);
-}
+typedef struct tColorY {
+ Uint8 y;
+} tColorY;
+
+/*!
+\brief Returns maximum of two numbers a and b.
+*/
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+
+/*!
+\brief Number of guard rows added to destination surfaces.
+
+This is a simple but effective workaround for observed issues.
+These rows allocate extra memory and are then hidden from the surface.
+Rows are added to the end of destination surfaces when they are allocated.
+This catches any potential overflows which seem to happen with
+just the right src image dimensions and scale/rotation and can lead
+to a situation where the program can segfault.
+*/
+#define GUARD_ROWS (2)
+
+/*!
+\brief Lower limit of absolute zoom factor or rotation degrees.
+*/
+#define VALUE_LIMIT 0.001
+
+/*!
+\brief Returns colorkey info for a surface
+*/
+Uint32 _colorkey(SDL_Surface *src)
+{
+ Uint32 key = 0;
+#if (SDL_MINOR_VERSION == 3)
+ SDL_GetColorKey(src, &key);
+#else
+ if (src)
+ {
+ key = src->format->colorkey;
+ }
+#endif
+ return key;
+}
+
+
+/*!
+\brief Internal 32 bit integer-factor averaging Shrinker.
+
+Shrinks 32 bit RGBA/ABGR 'src' surface to 'dst' surface.
+Averages color and alpha values values of src pixels to calculate dst pixels.
+Assumes src and dst surfaces are of 32 bit depth.
+Assumes dst surface was allocated with the correct dimensions.
+
+\param src The surface to shrink (input).
+\param dst The shrunken surface (output).
+\param factorx The horizontal shrinking ratio.
+\param factory The vertical shrinking ratio.
+
+\return 0 for success or -1 for error.
+*/
+int _shrinkSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory)
+{
+ int x, y, dx, dy, sgap, dgap, ra, ga, ba, aa;
+ int n_average;
+ tColorRGBA *sp, *osp, *oosp;
+ tColorRGBA *dp;
+
+ /*
+ * Averaging integer shrink
+ */
+
+ /* Precalculate division factor */
+ n_average = factorx*factory;
+
+ /*
+ * Scan destination
+ */
+ sp = (tColorRGBA *) src->pixels;
+ sgap = src->pitch - src->w * 4;
+
+ dp = (tColorRGBA *) dst->pixels;
+ dgap = dst->pitch - dst->w * 4;
+
+ for (y = 0; y < dst->h; y++) {
+
+ osp=sp;
+ for (x = 0; x < dst->w; x++) {
+
+ /* Trace out source box and accumulate */
+ oosp=sp;
+ ra=ga=ba=aa=0;
+ for (dy=0; dy < factory; dy++) {
+ for (dx=0; dx < factorx; dx++) {
+ ra += sp->r;
+ ga += sp->g;
+ ba += sp->b;
+ aa += sp->a;
+
+ sp++;
+ }
+ /* src dx loop */
+ sp = (tColorRGBA *)((Uint8*)sp + (src->pitch - 4*factorx)); // next y
+ }
+ /* src dy loop */
+
+ /* next box-x */
+ sp = (tColorRGBA *)((Uint8*)oosp + 4*factorx);
+
+ /* Store result in destination */
+ dp->r = ra/n_average;
+ dp->g = ga/n_average;
+ dp->b = ba/n_average;
+ dp->a = aa/n_average;
+
+ /*
+ * Advance destination pointer
+ */
+ dp++;
+ }
+ /* dst x loop */
+
+ /* next box-y */
+ sp = (tColorRGBA *)((Uint8*)osp + src->pitch*factory);
+
+ /*
+ * Advance destination pointers
+ */
+ dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
+ }
+ /* dst y loop */
+
+ return (0);
+}
+
+/*!
+\brief Internal 8 bit integer-factor averaging shrinker.
+
+Shrinks 8bit Y 'src' surface to 'dst' surface.
+Averages color (brightness) values values of src pixels to calculate dst pixels.
+Assumes src and dst surfaces are of 8 bit depth.
+Assumes dst surface was allocated with the correct dimensions.
+
+\param src The surface to shrink (input).
+\param dst The shrunken surface (output).
+\param factorx The horizontal shrinking ratio.
+\param factory The vertical shrinking ratio.
+
+\return 0 for success or -1 for error.
+*/
+int _shrinkSurfaceY(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory)
+{
+ int x, y, dx, dy, sgap, dgap, a;
+ int n_average;
+ Uint8 *sp, *osp, *oosp;
+ Uint8 *dp;
+
+ /*
+ * Averaging integer shrink
+ */
+
+ /* Precalculate division factor */
+ n_average = factorx*factory;
+
+ /*
+ * Scan destination
+ */
+ sp = (Uint8 *) src->pixels;
+ sgap = src->pitch - src->w;
+
+ dp = (Uint8 *) dst->pixels;
+ dgap = dst->pitch - dst->w;
+
+ for (y = 0; y < dst->h; y++) {
+
+ osp=sp;
+ for (x = 0; x < dst->w; x++) {
+
+ /* Trace out source box and accumulate */
+ oosp=sp;
+ a=0;
+ for (dy=0; dy < factory; dy++) {
+ for (dx=0; dx < factorx; dx++) {
+ a += (*sp);
+ /* next x */
+ sp++;
+ }
+ /* end src dx loop */
+ /* next y */
+ sp = (Uint8 *)((Uint8*)sp + (src->pitch - factorx));
+ }
+ /* end src dy loop */
+
+ /* next box-x */
+ sp = (Uint8 *)((Uint8*)oosp + factorx);
+
+ /* Store result in destination */
+ *dp = a/n_average;
+
+ /*
+ * Advance destination pointer
+ */
+ dp++;
+ }
+ /* end dst x loop */
+
+ /* next box-y */
+ sp = (Uint8 *)((Uint8*)osp + src->pitch*factory);
+
+ /*
+ * Advance destination pointers
+ */
+ dp = (Uint8 *)((Uint8 *)dp + dgap);
+ }
+ /* end dst y loop */
+
+ return (0);
+}
+
+/*!
+\brief Internal 32 bit Zoomer with optional anti-aliasing by bilinear interpolation.
+
+Zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface.
+Assumes src and dst surfaces are of 32 bit depth.
+Assumes dst surface was allocated with the correct dimensions.
+
+\param src The surface to zoom (input).
+\param dst The zoomed surface (output).
+\param flipx Flag indicating if the image should be horizontally flipped.
+\param flipy Flag indicating if the image should be vertically flipped.
+\param smooth Antialiasing flag; set to SMOOTHING_ON to enable.
+
+\return 0 for success or -1 for error.
+*/
+int _zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, int smooth)
+{
+ int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep, lx, ly;
+ tColorRGBA *c00, *c01, *c10, *c11, *cswap;
+ tColorRGBA *sp, *csp, *dp;
+ int dgap;
+
+ /*
+ * Variable setup
+ */
+ if (smooth) {
+ /*
+ * For interpolation: assume source dimension is one pixel
+ * smaller to avoid overflow on right and bottom edge.
+ */
+ sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w);
+ sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h);
+ } else {
+ sx = (int) (65536.0 * (float) src->w / (float) dst->w);
+ sy = (int) (65536.0 * (float) src->h / (float) dst->h);
+ }
+
+ /*
+ * Allocate memory for row increments
+ */
+ if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
+ return (-1);
+ }
+ if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
+ free(sax);
+ return (-1);
+ }
+
+ /*
+ * Precalculate row increments
+ */
+ sp = csp = (tColorRGBA *) src->pixels;
+ dp = (tColorRGBA *) dst->pixels;
+
+ if (flipx) csp += (src->w-1);
+ if (flipy) csp += ((src->pitch/4)*(src->h-1));
+
+ csx = 0;
+ csax = sax;
+ for (x = 0; x <= dst->w; x++) {
+ *csax = csx;
+ csax++;
+ csx &= 0xffff;
+ csx += sx;
+ }
+ csy = 0;
+ csay = say;
+ for (y = 0; y <= dst->h; y++) {
+ *csay = csy;
+ csay++;
+ csy &= 0xffff;
+ csy += sy;
+ }
+
+ dgap = dst->pitch - dst->w * 4;
+
+ /*
+ * Switch between interpolating and non-interpolating code
+ */
+ if (smooth) {
+
+ /*
+ * Interpolating Zoom
+ */
+
+ /*
+ * Scan destination
+ */
+ csay = say;
+ ly = 0;
+ for (y = 0; y < dst->h; y++) {
+ /*
+ * Setup color source pointers
+ */
+ c00 = csp;
+ c01 = csp;
+ c01++;
+ c10 = csp;
+ c10 += src->pitch/4;
+ c11 = c10;
+ c11++;
+ if (flipx) {
+ cswap = c00; c00=c01; c01=cswap;
+ cswap = c10; c10=c11; c11=cswap;
+ }
+ if (flipy) {
+ cswap = c00; c00=c10; c10=cswap;
+ cswap = c01; c01=c11; c11=cswap;
+ }
+
+ csax = sax;
+ lx = 0;
+ for (x = 0; x < dst->w; x++) {
+ /*
+ * Draw and interpolate colors
+ */
+ ex = (*csax & 0xffff);
+ ey = (*csay & 0xffff);
+ t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff;
+ t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff;
+ dp->r = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff;
+ t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff;
+ dp->g = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff;
+ t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff;
+ dp->b = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff;
+ t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff;
+ dp->a = (((t2 - t1) * ey) >> 16) + t1;
+
+ /*
+ * Advance source pointers
+ */
+ csax++;
+ if (*csax > 0)
+ {
+ sstep = (*csax >> 16);
+ lx += sstep;
+ if (flipx) sstep = -sstep;
+ if (lx <= src->w)
+ {
+ c00 += sstep;
+ c01 += sstep;
+ c10 += sstep;
+ c11 += sstep;
+ }
+ }
+
+ /*
+ * Advance destination pointer
+ */
+ dp++;
+ }
+
+ /*
+ * Advance source pointer
+ */
+ csay++;
+ if (*csay > 0)
+ {
+ sstep = (*csay >> 16);
+ ly += sstep;
+ if (flipy) sstep = -sstep;
+ if (ly < src->h)
+ {
+ csp += (sstep * (src->pitch/4));
+ }
+ }
+
+ /*
+ * Advance destination pointers
+ */
+ dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
+ }
+ } else {
+
+ /*
+ * Non-Interpolating Zoom
+ */
+ csay = say;
+ for (y = 0; y < dst->h; y++) {
+ sp = csp;
+ csax = sax;
+ for (x = 0; x < dst->w; x++) {
+ /*
+ * Draw
+ */
+ *dp = *sp;
+ /*
+ * Advance source pointers
+ */
+ csax++;
+ if (*csax > 0)
+ {
+ sstep = (*csax >> 16);
+ if (flipx) sstep = -sstep;
+ sp += sstep;
+ }
+ /*
+ * Advance destination pointer
+ */
+ dp++;
+ }
+ /*
+ * Advance source pointer
+ */
+ csay++;
+ if (*csay > 0)
+ {
+ sstep = (*csay >> 16) * (src->pitch/4);
+ if (flipy) sstep = -sstep;
+ csp += sstep;
+ }
+
+ /*
+ * Advance destination pointers
+ */
+ dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
+ }
+ }
+
+ /*
+ * Remove temp arrays
+ */
+ free(sax);
+ free(say);
+
+ return (0);
+}
+
+/*!
+
+\brief Internal 8 bit Zoomer without smoothing.
+
+Zooms 8bit palette/Y 'src' surface to 'dst' surface.
+Assumes src and dst surfaces are of 8 bit depth.
+Assumes dst surface was allocated with the correct dimensions.
+
+\param src The surface to zoom (input).
+\param dst The zoomed surface (output).
+\param flipx Flag indicating if the image should be horizontally flipped.
+\param flipy Flag indicating if the image should be vertically flipped.
+
+\return 0 for success or -1 for error.
+*/
+int _zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy)
+{
+ int x, y;
+ Uint32 *sax, *say, *csax, *csay;
+ int csx, csy;
+ Uint8 *sp, *dp, *csp;
+ int dgap;
+
+ /*
+ * Allocate memory for row increments
+ */
+ if ((sax = (Uint32 *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
+ return (-1);
+ }
+ if ((say = (Uint32 *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
+ free(sax);
+ return (-1);
+ }
+
+ /*
+ * Pointer setup
+ */
+ sp = csp = (Uint8 *) src->pixels;
+ dp = (Uint8 *) dst->pixels;
+ dgap = dst->pitch - dst->w;
+
+ if (flipx) csp += (src->w-1);
+ if (flipy) csp = ( (Uint8*)csp + src->pitch*(src->h-1) );
+
+ /*
+ * Precalculate row increments
+ */
+ csx = 0;
+ csax = sax;
+ for (x = 0; x < dst->w; x++) {
+ csx += src->w;
+ *csax = 0;
+ while (csx >= dst->w) {
+ csx -= dst->w;
+ (*csax)++;
+ }
+ csax++;
+ }
+ csy = 0;
+ csay = say;
+ for (y = 0; y < dst->h; y++) {
+ csy += src->h;
+ *csay = 0;
+ while (csy >= dst->h) {
+ csy -= dst->h;
+ (*csay)++;
+ }
+ csay++;
+ }
+
+ /*
+ * Draw
+ */
+ csay = say;
+ for (y = 0; y < dst->h; y++) {
+ csax = sax;
+ sp = csp;
+ for (x = 0; x < dst->w; x++) {
+ /*
+ * Draw
+ */
+ *dp = *sp;
+ /*
+ * Advance source pointers
+ */
+ sp += (*csax) * (flipx ? -1 : 1);
+ csax++;
+ /*
+ * Advance destination pointer
+ */
+ dp++;
+ }
+ /*
+ * Advance source pointer (for row)
+ */
+ csp += ((*csay) * src->pitch) * (flipy ? -1 : 1);
+ csay++;
+
+ /*
+ * Advance destination pointers
+ */
+ dp += dgap;
+ }
+
+ /*
+ * Remove temp arrays
+ */
+ free(sax);
+ free(say);
+
+ return (0);
+}
+
+/*!
+\brief Internal 32 bit rotozoomer with optional anti-aliasing.
+
+Rotates and zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control
+parameters by scanning the destination surface and applying optionally anti-aliasing
+by bilinear interpolation.
+Assumes src and dst surfaces are of 32 bit depth.
+Assumes dst surface was allocated with the correct dimensions.
+
+\param src Source surface.
+\param dst Destination surface.
+\param cx Horizontal center coordinate.
+\param cy Vertical center coordinate.
+\param isin Integer version of sine of angle.
+\param icos Integer version of cosine of angle.
+\param flipx Flag indicating horizontal mirroring should be applied.
+\param flipy Flag indicating vertical mirroring should be applied.
+\param smooth Flag indicating anti-aliasing should be used.
+*/
+void _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth)
+{
+ int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh;
+ tColorRGBA c00, c01, c10, c11, cswap;
+ tColorRGBA *pc, *sp;
+ int gap;
+
+ /*
+ * Variable setup
+ */
+ xd = ((src->w - dst->w) << 15);
+ yd = ((src->h - dst->h) << 15);
+ ax = (cx << 16) - (icos * cx);
+ ay = (cy << 16) - (isin * cx);
+ sw = src->w - 1;
+ sh = src->h - 1;
+ pc = (tColorRGBA*) dst->pixels;
+ gap = dst->pitch - dst->w * 4;
+
+ /*
+ * Switch between interpolating and non-interpolating code
+ */
+ if (smooth) {
+ for (y = 0; y < dst->h; y++) {
+ dy = cy - y;
+ sdx = (ax + (isin * dy)) + xd;
+ sdy = (ay - (icos * dy)) + yd;
+ for (x = 0; x < dst->w; x++) {
+ dx = (sdx >> 16);
+ dy = (sdy >> 16);
+ if (flipx) dx = sw - dx;
+ if (flipy) dy = sh - dy;
+ if ((dx > -1) && (dy > -1) && (dx < (src->w-1)) && (dy < (src->h-1))) {
+ sp = (tColorRGBA *)src->pixels;;
+ sp += ((src->pitch/4) * dy);
+ sp += dx;
+ c00 = *sp;
+ sp += 1;
+ c01 = *sp;
+ sp += (src->pitch/4);
+ c11 = *sp;
+ sp -= 1;
+ c10 = *sp;
+ if (flipx) {
+ cswap = c00; c00=c01; c01=cswap;
+ cswap = c10; c10=c11; c11=cswap;
+ }
+ if (flipy) {
+ cswap = c00; c00=c10; c10=cswap;
+ cswap = c01; c01=c11; c11=cswap;
+ }
+ /*
+ * Interpolate colors
+ */
+ ex = (sdx & 0xffff);
+ ey = (sdy & 0xffff);
+ t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff;
+ t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff;
+ pc->r = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff;
+ t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff;
+ pc->g = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff;
+ t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff;
+ pc->b = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff;
+ t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff;
+ pc->a = (((t2 - t1) * ey) >> 16) + t1;
+ }
+ sdx += icos;
+ sdy += isin;
+ pc++;
+ }
+ pc = (tColorRGBA *) ((Uint8 *) pc + gap);
+ }
+ } else {
+ for (y = 0; y < dst->h; y++) {
+ dy = cy - y;
+ sdx = (ax + (isin * dy)) + xd;
+ sdy = (ay - (icos * dy)) + yd;
+ for (x = 0; x < dst->w; x++) {
+ dx = (short) (sdx >> 16);
+ dy = (short) (sdy >> 16);
+ if (flipx) dx = (src->w-1)-dx;
+ if (flipy) dy = (src->h-1)-dy;
+ if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) {
+ sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy);
+ sp += dx;
+ *pc = *sp;
+ }
+ sdx += icos;
+ sdy += isin;
+ pc++;
+ }
+ pc = (tColorRGBA *) ((Uint8 *) pc + gap);
+ }
+ }
+}
+
+/*!
+
+\brief Rotates and zooms 8 bit palette/Y 'src' surface to 'dst' surface without smoothing.
+
+Rotates and zooms 8 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control
+parameters by scanning the destination surface.
+Assumes src and dst surfaces are of 8 bit depth.
+Assumes dst surface was allocated with the correct dimensions.
+
+\param src Source surface.
+\param dst Destination surface.
+\param cx Horizontal center coordinate.
+\param cy Vertical center coordinate.
+\param isin Integer version of sine of angle.
+\param icos Integer version of cosine of angle.
+\param flipx Flag indicating horizontal mirroring should be applied.
+\param flipy Flag indicating vertical mirroring should be applied.
+*/
+void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy)
+{
+ int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay, sw, sh;
+ tColorY *pc, *sp;
+ int gap;
+
+ /*
+ * Variable setup
+ */
+ xd = ((src->w - dst->w) << 15);
+ yd = ((src->h - dst->h) << 15);
+ ax = (cx << 16) - (icos * cx);
+ ay = (cy << 16) - (isin * cx);
+ sw = src->w - 1;
+ sh = src->h - 1;
+ pc = (tColorY*) dst->pixels;
+ gap = dst->pitch - dst->w;
+ /*
+ * Clear surface to colorkey
+ */
+ memset(pc, (unsigned char) (_colorkey(src) & 0xff), dst->pitch * dst->h);
+ /*
+ * Iterate through destination surface
+ */
+ for (y = 0; y < dst->h; y++) {
+ dy = cy - y;
+ sdx = (ax + (isin * dy)) + xd;
+ sdy = (ay - (icos * dy)) + yd;
+ for (x = 0; x < dst->w; x++) {
+ dx = (short) (sdx >> 16);
+ dy = (short) (sdy >> 16);
+ if (flipx) dx = (src->w-1)-dx;
+ if (flipy) dy = (src->h-1)-dy;
+ if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) {
+ sp = (tColorY *) (src->pixels);
+ sp += (src->pitch * dy + dx);
+ *pc = *sp;
+ }
+ sdx += icos;
+ sdy += isin;
+ pc++;
+ }
+ pc += gap;
+ }
+}
+
+/*!
+\brief Rotates a 32 bit surface in increments of 90 degrees.
+
+Specialized 90 degree rotator which rotates a 'src' surface in 90 degree
+increments clockwise returning a new surface. Faster than rotozoomer since
+not scanning or interpolation takes place. Input surface must be 32 bit.
+(code contributed by J. Schiller, improved by C. Allport and A. Schiffler)
+
+\param src Source surface to rotate.
+\param numClockwiseTurns Number of clockwise 90 degree turns to apply to the source.
+
+\returns The new, rotated surface; or NULL for surfaces with incorrect input format.
+*/
+SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns)
+{
+ int row, col, newWidth, newHeight;
+ int bpp, src_ipr, dst_ipr;
+ SDL_Surface* dst;
+ Uint32* srcBuf;
+ Uint32* dstBuf;
+
+ /* Has to be a valid surface pointer and only 32-bit surfaces (for now) */
+ if (!src || src->format->BitsPerPixel != 32) { return NULL; }
+
+ /* normalize numClockwiseTurns */
+ while(numClockwiseTurns < 0) { numClockwiseTurns += 4; }
+ numClockwiseTurns = (numClockwiseTurns % 4);
+
+ /* if it's even, our new width will be the same as the source surface */
+ newWidth = (numClockwiseTurns % 2) ? (src->h) : (src->w);
+ newHeight = (numClockwiseTurns % 2) ? (src->w) : (src->h);
+ dst = SDL_CreateRGBSurface( src->flags, newWidth, newHeight, src->format->BitsPerPixel,
+ src->format->Rmask,
+ src->format->Gmask,
+ src->format->Bmask,
+ src->format->Amask);
+ if(!dst) {
+ return NULL;
+ }
+
+ if (SDL_MUSTLOCK(dst)) {
+ SDL_LockSurface(dst);
+ }
+ if (SDL_MUSTLOCK(dst)) {
+ SDL_LockSurface(dst);
+ }
+
+ /* Calculate int-per-row */
+ bpp = src->format->BitsPerPixel / 8;
+ src_ipr = src->pitch / bpp;
+ dst_ipr = dst->pitch / bpp;
+
+ switch(numClockwiseTurns) {
+ case 0: /* Make a copy of the surface */
+ {
+ /* Unfortunately SDL_BlitSurface cannot be used to make a copy of the surface
+ since it does not preserve alpha. */
+
+ if (src->pitch == dst->pitch) {
+ /* If the pitch is the same for both surfaces, the memory can be copied all at once. */
+ memcpy(dst->pixels, src->pixels, (src->h * src->pitch));
+ }
+ else
+ {
+ /* If the pitch differs, copy each row separately */
+ srcBuf = (Uint32*)(src->pixels);
+ dstBuf = (Uint32*)(dst->pixels);
+ for (row = 0; row < src->h; row++) {
+ memcpy(dstBuf, srcBuf, dst->w * bpp);
+ srcBuf += src_ipr;
+ dstBuf += dst_ipr;
+ } /* end for(col) */
+ } /* end for(row) */
+ }
+ break;
+
+ /* rotate clockwise */
+ case 1: /* rotated 90 degrees clockwise */
+ {
+ for (row = 0; row < src->h; ++row) {
+ srcBuf = (Uint32*)(src->pixels) + (row * src_ipr);
+ dstBuf = (Uint32*)(dst->pixels) + (dst->w - row - 1);
+ for (col = 0; col < src->w; ++col) {
+ *dstBuf = *srcBuf;
+ ++srcBuf;
+ dstBuf += dst_ipr;
+ }
+ /* end for(col) */
+ }
+ /* end for(row) */
+ }
+ break;
+
+ case 2: /* rotated 180 degrees clockwise */
+ {
+ for (row = 0; row < src->h; ++row) {
+ srcBuf = (Uint32*)(src->pixels) + (row * src_ipr);
+ dstBuf = (Uint32*)(dst->pixels) + ((dst->h - row - 1) * dst_ipr) + (dst->w - 1);
+ for (col = 0; col < src->w; ++col) {
+ *dstBuf = *srcBuf;
+ ++srcBuf;
+ --dstBuf;
+ }
+ }
+ }
+ break;
+
+ case 3:
+ {
+ for (row = 0; row < src->h; ++row) {
+ srcBuf = (Uint32*)(src->pixels) + (row * src_ipr);
+ dstBuf = (Uint32*)(dst->pixels) + row + ((dst->h - 1) * dst_ipr);
+ for (col = 0; col < src->w; ++col) {
+ *dstBuf = *srcBuf;
+ ++srcBuf;
+ dstBuf -= dst_ipr;
+ }
+ }
+ }
+ break;
+ }
+ /* end switch */
+
+ if (SDL_MUSTLOCK(src)) {
+ SDL_UnlockSurface(src);
+ }
+ if (SDL_MUSTLOCK(dst)) {
+ SDL_UnlockSurface(dst);
+ }
+
+ return dst;
+}
+
+
+/*!
+\brief Internal target surface sizing function for rotozooms with trig result return.
+
+\param width The source surface width.
+\param height The source surface height.
+\param angle The angle to rotate in degrees.
+\param zoomx The horizontal scaling factor.
+\param zoomy The vertical scaling factor.
+\param dstwidth The calculated width of the destination surface.
+\param dstheight The calculated height of the destination surface.
+\param canglezoom The sine of the angle adjusted by the zoom factor.
+\param sanglezoom The cosine of the angle adjusted by the zoom factor.
+
+*/
+void _rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoomx, double zoomy,
+ int *dstwidth, int *dstheight,
+ double *canglezoom, double *sanglezoom)
+{
+ double x, y, cx, cy, sx, sy;
+ double radangle;
+ int dstwidthhalf, dstheighthalf;
+
+ /*
+ * Determine destination width and height by rotating a centered source box
+ */
+ radangle = angle * (M_PI / 180.0);
+ *sanglezoom = sin(radangle);
+ *canglezoom = cos(radangle);
+ *sanglezoom *= zoomx;
+ *canglezoom *= zoomx;
+ x = width / 2;
+ y = height / 2;
+ cx = *canglezoom * x;
+ cy = *canglezoom * y;
+ sx = *sanglezoom * x;
+ sy = *sanglezoom * y;
+
+ dstwidthhalf = MAX((int)
+ ceil(MAX(MAX(MAX(fabs(cx + sy), fabs(cx - sy)), fabs(-cx + sy)), fabs(-cx - sy))), 1);
+ dstheighthalf = MAX((int)
+ ceil(MAX(MAX(MAX(fabs(sx + cy), fabs(sx - cy)), fabs(-sx + cy)), fabs(-sx - cy))), 1);
+ *dstwidth = 2 * dstwidthhalf;
+ *dstheight = 2 * dstheighthalf;
+}
+
+/*!
+\brief Returns the size of the resulting target surface for a rotozoomSurfaceXY() call.
+
+\param width The source surface width.
+\param height The source surface height.
+\param angle The angle to rotate in degrees.
+\param zoomx The horizontal scaling factor.
+\param zoomy The vertical scaling factor.
+\param dstwidth The calculated width of the rotozoomed destination surface.
+\param dstheight The calculated height of the rotozoomed destination surface.
+*/
+void rotozoomSurfaceSizeXY(int width, int height, double angle, double zoomx, double zoomy, int *dstwidth, int *dstheight)
+{
+ double dummy_sanglezoom, dummy_canglezoom;
+
+ _rotozoomSurfaceSizeTrig(width, height, angle, zoomx, zoomy, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom);
+}
+
+/*!
+\brief Returns the size of the resulting target surface for a rotozoomSurface() call.
+
+\param width The source surface width.
+\param height The source surface height.
+\param angle The angle to rotate in degrees.
+\param zoom The scaling factor.
+\param dstwidth The calculated width of the rotozoomed destination surface.
+\param dstheight The calculated height of the rotozoomed destination surface.
+*/
+void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight)
+{
+ double dummy_sanglezoom, dummy_canglezoom;
+
+ _rotozoomSurfaceSizeTrig(width, height, angle, zoom, zoom, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom);
+}
+
+/*!
+\brief Rotates and zooms a surface and optional anti-aliasing.
+
+Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface.
+'angle' is the rotation in degrees and 'zoom' a scaling factor. If 'smooth' is set
+then the destination 32bit surface is anti-aliased. If the surface is not 8bit
+or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
+
+\param src The surface to rotozoom.
+\param angle The angle to rotate in degrees.
+\param zoom The scaling factor.
+\param smooth Antialiasing flag; set to SMOOTHING_ON to enable.
+
+\return The new rotozoomed surface.
+*/
+SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth)
+{
+ return rotozoomSurfaceXY(src, angle, zoom, zoom, smooth);
+}
+
+/*!
+\brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing.
+
+Rotates and zooms a 32bit or 8bit 'src' surface to newly created 'dst' surface.
+'angle' is the rotation in degrees, 'zoomx and 'zoomy' scaling factors. If 'smooth' is set
+then the destination 32bit surface is anti-aliased. If the surface is not 8bit
+or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
+
+\param src The surface to rotozoom.
+\param angle The angle to rotate in degrees.
+\param zoomx The horizontal scaling factor.
+\param zoomy The vertical scaling factor.
+\param smooth Antialiasing flag; set to SMOOTHING_ON to enable.
+
+\return The new rotozoomed surface.
+*/
+SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth)
+{
+ SDL_Surface *rz_src;
+ SDL_Surface *rz_dst;
+ double zoominv;
+ double sanglezoom, canglezoom, sanglezoominv, canglezoominv;
+ int dstwidthhalf, dstwidth, dstheighthalf, dstheight;
+ int is32bit;
+ int i, src_converted;
+ int flipx,flipy;
+ Uint8 r,g,b;
+ Uint32 colorkey = 0;
+ int colorKeyAvailable = 0;
+
+ /*
+ * Sanity check
+ */
+ if (src == NULL)
+ return (NULL);
+
+ if (src->flags & SDL_SRCCOLORKEY)
+ {
+ colorkey = _colorkey(src);
+ SDL_GetRGB(colorkey, src->format, &r, &g, &b);
+ colorKeyAvailable = 1;
+ }
+ /*
+ * Determine if source surface is 32bit or 8bit
+ */
+ is32bit = (src->format->BitsPerPixel == 32);
+ if ((is32bit) || (src->format->BitsPerPixel == 8)) {
+ /*
+ * Use source surface 'as is'
+ */
+ rz_src = src;
+ src_converted = 0;
+ } else {
+ /*
+ * New source surface is 32bit with a defined RGBA ordering
+ */
+ rz_src =
+ SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
+#else
+ 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff
+#endif
+ );
+ if(colorKeyAvailable)
+ SDL_SetColorKey(src, 0, 0);
+
+ SDL_BlitSurface(src, NULL, rz_src, NULL);
+
+ if(colorKeyAvailable)
+ SDL_SetColorKey(src, SDL_SRCCOLORKEY, colorkey);
+ src_converted = 1;
+ is32bit = 1;
+ }
+
+ /*
+ * Sanity check zoom factor
+ */
+ flipx = (zoomx<0.0);
+ if (flipx) zoomx=-zoomx;
+ flipy = (zoomy<0.0);
+ if (flipy) zoomy=-zoomy;
+ if (zoomx < VALUE_LIMIT) zoomx = VALUE_LIMIT;
+ if (zoomy < VALUE_LIMIT) zoomy = VALUE_LIMIT;
+ zoominv = 65536.0 / (zoomx * zoomx);
+
+ /*
+ * Check if we have a rotozoom or just a zoom
+ */
+ if (fabs(angle) > VALUE_LIMIT) {
+
+ /*
+ * Angle!=0: full rotozoom
+ */
+ /*
+ * -----------------------
+ */
+
+ /* Determine target size */
+ _rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoomx, zoomy, &dstwidth, &dstheight, &canglezoom, &sanglezoom);
+
+ /*
+ * Calculate target factors from sin/cos and zoom
+ */
+ sanglezoominv = sanglezoom;
+ canglezoominv = canglezoom;
+ sanglezoominv *= zoominv;
+ canglezoominv *= zoominv;
+
+ /* Calculate half size */
+ dstwidthhalf = dstwidth / 2;
+ dstheighthalf = dstheight / 2;
+
+ /*
+ * Alloc space to completely contain the rotated surface
+ */
+ rz_dst = NULL;
+ if (is32bit) {
+ /*
+ * Target surface is 32bit with source RGBA/ABGR ordering
+ */
+ rz_dst =
+ SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32,
+ rz_src->format->Rmask, rz_src->format->Gmask,
+ rz_src->format->Bmask, rz_src->format->Amask);
+ } else {
+ /*
+ * Target surface is 8bit
+ */
+ rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
+ }
+
+ /* Check target */
+ if (rz_dst == NULL)
+ return NULL;
+
+ /* Adjust for guard rows */
+ rz_dst->h = dstheight;
+
+ if (colorKeyAvailable == 1){
+ colorkey = SDL_MapRGB(rz_dst->format, r, g, b);
+
+ SDL_FillRect(rz_dst, NULL, colorkey );
+ }
+
+ /*
+ * Lock source surface
+ */
+ if (SDL_MUSTLOCK(rz_src)) {
+ SDL_LockSurface(rz_src);
+ }
+
+ /*
+ * Check which kind of surface we have
+ */
+ if (is32bit) {
+ /*
+ * Call the 32bit transformation routine to do the rotation (using alpha)
+ */
+ _transformSurfaceRGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
+ (int) (sanglezoominv), (int) (canglezoominv),
+ flipx, flipy,
+ smooth);
+ /*
+ * Turn on source-alpha support
+ */
+ SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
+ SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
+ } else {
+ /*
+ * Copy palette and colorkey info
+ */
+ for (i = 0; i < rz_src->format->palette->ncolors; i++) {
+ rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
+ }
+ rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
+ /*
+ * Call the 8bit transformation routine to do the rotation
+ */
+ transformSurfaceY(rz_src, rz_dst, dstwidthhalf, dstheighthalf,
+ (int) (sanglezoominv), (int) (canglezoominv),
+ flipx, flipy);
+ SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
+ }
+ /*
+ * Unlock source surface
+ */
+ if (SDL_MUSTLOCK(rz_src)) {
+ SDL_UnlockSurface(rz_src);
+ }
+
+ } else {
+
+ /*
+ * Angle=0: Just a zoom
+ */
+ /*
+ * --------------------
+ */
+
+ /*
+ * Calculate target size
+ */
+ zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight);
+
+ /*
+ * Alloc space to completely contain the zoomed surface
+ */
+ rz_dst = NULL;
+ if (is32bit) {
+ /*
+ * Target surface is 32bit with source RGBA/ABGR ordering
+ */
+ rz_dst =
+ SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32,
+ rz_src->format->Rmask, rz_src->format->Gmask,
+ rz_src->format->Bmask, rz_src->format->Amask);
+ } else {
+ /*
+ * Target surface is 8bit
+ */
+ rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
+ }
+
+ /* Check target */
+ if (rz_dst == NULL)
+ return NULL;
+
+ /* Adjust for guard rows */
+ rz_dst->h = dstheight;
+
+ if (colorKeyAvailable == 1){
+ colorkey = SDL_MapRGB(rz_dst->format, r, g, b);
+
+ SDL_FillRect(rz_dst, NULL, colorkey );
+ }
+
+ /*
+ * Lock source surface
+ */
+ if (SDL_MUSTLOCK(rz_src)) {
+ SDL_LockSurface(rz_src);
+ }
+
+ /*
+ * Check which kind of surface we have
+ */
+ if (is32bit) {
+ /*
+ * Call the 32bit transformation routine to do the zooming (using alpha)
+ */
+ _zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth);
+
+ /*
+ * Turn on source-alpha support
+ */
+ SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
+ SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
+ } else {
+ /*
+ * Copy palette and colorkey info
+ */
+ for (i = 0; i < rz_src->format->palette->ncolors; i++) {
+ rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
+ }
+ rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
+
+ /*
+ * Call the 8bit transformation routine to do the zooming
+ */
+ _zoomSurfaceY(rz_src, rz_dst, flipx, flipy);
+ SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
+ }
+
+ /*
+ * Unlock source surface
+ */
+ if (SDL_MUSTLOCK(rz_src)) {
+ SDL_UnlockSurface(rz_src);
+ }
+ }
+
+ /*
+ * Cleanup temp surface
+ */
+ if (src_converted) {
+ SDL_FreeSurface(rz_src);
+ }
+
+ /*
+ * Return destination surface
+ */
+ return (rz_dst);
+}
+
+/*!
+\brief Calculates the size of the target surface for a zoomSurface() call.
+
+The minimum size of the target surface is 1. The input factors can be positive or negative.
+
+\param width The width of the source surface to zoom.
+\param height The height of the source surface to zoom.
+\param zoomx The horizontal zoom factor.
+\param zoomy The vertical zoom factor.
+\param dstwidth Pointer to an integer to store the calculated width of the zoomed target surface.
+\param dstheight Pointer to an integer to store the calculated height of the zoomed target surface.
+*/
+void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight)
+{
+ /*
+ * Make zoom factors positive
+ */
+ int flipx, flipy;
+ flipx = (zoomx<0.0);
+ if (flipx) zoomx = -zoomx;
+ flipy = (zoomy<0.0);
+ if (flipy) zoomy = -zoomy;
+
+ /*
+ * Sanity check zoom factors
+ */
+ if (zoomx < VALUE_LIMIT) {
+ zoomx = VALUE_LIMIT;
+ }
+ if (zoomy < VALUE_LIMIT) {
+ zoomy = VALUE_LIMIT;
+ }
+
+ /*
+ * Calculate target size
+ */
+ *dstwidth = (int) ((double) width * zoomx);
+ *dstheight = (int) ((double) height * zoomy);
+ if (*dstwidth < 1) {
+ *dstwidth = 1;
+ }
+ if (*dstheight < 1) {
+ *dstheight = 1;
+ }
+}
+
+/*!
+\brief Zoom a surface by independent horizontal and vertical factors with optional smoothing.
+
+Zooms a 32bit or 8bit 'src' surface to newly created 'dst' surface.
+'zoomx' and 'zoomy' are scaling factors for width and height. If 'smooth' is on
+then the destination 32bit surface is anti-aliased. If the surface is not 8bit
+or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
+If zoom factors are negative, the image is flipped on the axes.
+
+\param src The surface to zoom.
+\param zoomx The horizontal zoom factor.
+\param zoomy The vertical zoom factor.
+\param smooth Antialiasing flag; set to SMOOTHING_ON to enable.
+
+\return The new, zoomed surface.
+*/
+SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth)
+{
+ SDL_Surface *rz_src;
+ SDL_Surface *rz_dst;
+ int dstwidth, dstheight;
+ int is32bit;
+ int i, src_converted;
+ int flipx, flipy;
+
+ /*
+ * Sanity check
+ */
+ if (src == NULL)
+ return (NULL);
+
+ /*
+ * Determine if source surface is 32bit or 8bit
+ */
+ is32bit = (src->format->BitsPerPixel == 32);
+ if ((is32bit) || (src->format->BitsPerPixel == 8)) {
+ /*
+ * Use source surface 'as is'
+ */
+ rz_src = src;
+ src_converted = 0;
+ } else {
+ /*
+ * New source surface is 32bit with a defined RGBA ordering
+ */
+ rz_src =
+ SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
+#else
+ 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff
+#endif
+ );
+ SDL_BlitSurface(src, NULL, rz_src, NULL);
+ src_converted = 1;
+ is32bit = 1;
+ }
+
+ flipx = (zoomx<0.0);
+ if (flipx) zoomx = -zoomx;
+ flipy = (zoomy<0.0);
+ if (flipy) zoomy = -zoomy;
+
+ /* Get size if target */
+ zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight);
+
+ /*
+ * Alloc space to completely contain the zoomed surface
+ */
+ rz_dst = NULL;
+ if (is32bit) {
+ /*
+ * Target surface is 32bit with source RGBA/ABGR ordering
+ */
+ rz_dst =
+ SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32,
+ rz_src->format->Rmask, rz_src->format->Gmask,
+ rz_src->format->Bmask, rz_src->format->Amask);
+ } else {
+ /*
+ * Target surface is 8bit
+ */
+ rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
+ }
+
+ /* Check target */
+ if (rz_dst == NULL)
+ return NULL;
+
+ /* Adjust for guard rows */
+ rz_dst->h = dstheight;
+
+ /*
+ * Lock source surface
+ */
+ if (SDL_MUSTLOCK(rz_src)) {
+ SDL_LockSurface(rz_src);
+ }
+
+ /*
+ * Check which kind of surface we have
+ */
+ if (is32bit) {
+ /*
+ * Call the 32bit transformation routine to do the zooming (using alpha)
+ */
+ _zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth);
+ /*
+ * Turn on source-alpha support
+ */
+ SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
+ } else {
+ /*
+ * Copy palette and colorkey info
+ */
+ for (i = 0; i < rz_src->format->palette->ncolors; i++) {
+ rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
+ }
+ rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
+ /*
+ * Call the 8bit transformation routine to do the zooming
+ */
+ _zoomSurfaceY(rz_src, rz_dst, flipx, flipy);
+ SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
+ }
+ /*
+ * Unlock source surface
+ */
+ if (SDL_MUSTLOCK(rz_src)) {
+ SDL_UnlockSurface(rz_src);
+ }
+
+ /*
+ * Cleanup temp surface
+ */
+ if (src_converted) {
+ SDL_FreeSurface(rz_src);
+ }
+
+ /*
+ * Return destination surface
+ */
+ return (rz_dst);
+}
+
+/*!
+\brief Shrink a surface by an integer ratio using averaging.
+
+Shrinks a 32bit or 8bit 'src' surface to a newly created 'dst' surface.
+'factorx' and 'factory' are the shrinking ratios (i.e. 2=1/2 the size,
+3=1/3 the size, etc.) The destination surface is antialiased by averaging
+the source box RGBA or Y information. If the surface is not 8bit
+or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
+The input surface is not modified. The output surface is newly allocated.
+
+\param src The surface to shrink.
+\param factorx The horizontal shrinking ratio.
+\param factory The vertical shrinking ratio.
+
+\return The new, shrunken surface.
+*/
+SDL_Surface *shrinkSurface(SDL_Surface *src, int factorx, int factory)
+{
+ SDL_Surface *rz_src;
+ SDL_Surface *rz_dst;
+ int dstwidth, dstheight;
+ int is32bit;
+ int i, src_converted;
+
+ /*
+ * Sanity check
+ */
+ if (src == NULL)
+ return (NULL);
+
+ /*
+ * Determine if source surface is 32bit or 8bit
+ */
+ is32bit = (src->format->BitsPerPixel == 32);
+ if ((is32bit) || (src->format->BitsPerPixel == 8)) {
+ /*
+ * Use source surface 'as is'
+ */
+ rz_src = src;
+ src_converted = 0;
+ } else {
+ /*
+ * New source surface is 32bit with a defined RGBA ordering
+ */
+ rz_src =
+ SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
+#else
+ 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff
+#endif
+ );
+ SDL_BlitSurface(src, NULL, rz_src, NULL);
+ src_converted = 1;
+ is32bit = 1;
+ }
+
+ /* Get size for target */
+ dstwidth=rz_src->w/factorx;
+ while (dstwidth*factorx>rz_src->w) { dstwidth--; }
+ dstheight=rz_src->h/factory;
+ while (dstheight*factory>rz_src->h) { dstheight--; }
+
+ /*
+ * Alloc space to completely contain the shrunken surface
+ * (with added guard rows)
+ */
+ rz_dst = NULL;
+ if (is32bit) {
+ /*
+ * Target surface is 32bit with source RGBA/ABGR ordering
+ */
+ rz_dst =
+ SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 32,
+ rz_src->format->Rmask, rz_src->format->Gmask,
+ rz_src->format->Bmask, rz_src->format->Amask);
+ } else {
+ /*
+ * Target surface is 8bit
+ */
+ rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
+ }
+
+ /* Check target */
+ if (rz_dst == NULL)
+ return NULL;
+
+ /* Adjust for guard rows */
+ rz_dst->h = dstheight;
+
+ /*
+ * Lock source surface
+ */
+ if (SDL_MUSTLOCK(rz_src)) {
+ SDL_LockSurface(rz_src);
+ }
+
+ /*
+ * Check which kind of surface we have
+ */
+ if (is32bit) {
+ /*
+ * Call the 32bit transformation routine to do the shrinking (using alpha)
+ */
+ _shrinkSurfaceRGBA(rz_src, rz_dst, factorx, factory);
+ /*
+ * Turn on source-alpha support
+ */
+ SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
+ } else {
+ /*
+ * Copy palette and colorkey info
+ */
+ for (i = 0; i < rz_src->format->palette->ncolors; i++) {
+ rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
+ }
+ rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
+ /*
+ * Call the 8bit transformation routine to do the shrinking
+ */
+ _shrinkSurfaceY(rz_src, rz_dst, factorx, factory);
+ SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, _colorkey(rz_src));
+ }
+
+ /*
+ * Unlock source surface
+ */
+ if (SDL_MUSTLOCK(rz_src)) {
+ SDL_UnlockSurface(rz_src);
+ }
+
+ /*
+ * Cleanup temp surface
+ */
+ if (src_converted) {
+ SDL_FreeSurface(rz_src);
+ }
+
+ /*
+ * Return destination surface
+ */
+ return (rz_dst);
+}
diff --git a/src/sdl-instead/SDL_rotozoom.h b/src/sdl-instead/SDL_rotozoom.h
index 9773866..0fce281 100644
--- a/src/sdl-instead/SDL_rotozoom.h
+++ b/src/sdl-instead/SDL_rotozoom.h
@@ -1,9 +1,9 @@
/*
- SDL_rotozoom - rotozoomer
+SDL_rotozoom - rotozoomer
- LGPL (c) A. Schiffler
+LGPL (c) A. Schiffler
*/
@@ -23,93 +23,79 @@ extern "C" {
#include "SDL.h"
-/* ---- Defines */
+ /* ---- Defines */
+ /*!
+ \brief Disable anti-aliasing (no smoothing).
+ */
#define SMOOTHING_OFF 0
+
+ /*!
+ \brief Enable anti-aliasing (smoothing).
+ */
#define SMOOTHING_ON 1
-/* ---- Structures */
+ /* ---- Function Prototypes */
- typedef struct tColorRGBA {
- Uint8 r;
- Uint8 g;
- Uint8 b;
- Uint8 a;
- } tColorRGBA;
+#if defined(WIN32) || defined(WIN64)
+# if defined(DLL_EXPORT) && !defined(LIBSDL_GFX_DLL_IMPORT)
+# define SDL_ROTOZOOM_SCOPE __declspec(dllexport)
+# else
+# ifdef LIBSDL_GFX_DLL_IMPORT
+# define SDL_ROTOZOOM_SCOPE __declspec(dllimport)
+# endif
+# endif
+#endif
+#ifndef SDL_ROTOZOOM_SCOPE
+# define SDL_ROTOZOOM_SCOPE extern
+#endif
- typedef struct tColorY {
- Uint8 y;
- } tColorY;
+ /*
+
+ Rotozoom functions
+
+ */
+
+ SDL_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth);
+
+ SDL_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurfaceXY
+ (SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth);
-/* ---- Prototypes */
+ SDL_ROTOZOOM_SCOPE void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth,
+ int *dstheight);
-#define DLLINTERFACE
+ SDL_ROTOZOOM_SCOPE void rotozoomSurfaceSizeXY
+ (int width, int height, double angle, double zoomx, double zoomy,
+ int *dstwidth, int *dstheight);
-/*
-
- rotozoomSurface()
+ /*
- Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface.
- 'angle' is the rotation in degrees. 'zoom' a scaling factor. If 'smooth' is 1
- then the destination 32bit surface is anti-aliased. If the surface is not 8bit
- or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
+ Zooming functions
-*/
+ */
- DLLINTERFACE SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth);
+ SDL_ROTOZOOM_SCOPE SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth);
- DLLINTERFACE SDL_Surface *rotozoomSurfaceXY
- (SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth);
+ SDL_ROTOZOOM_SCOPE void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight);
-/* Returns the size of the target surface for a rotozoomSurface() call */
+ /*
- DLLINTERFACE void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth,
- int *dstheight);
+ Shrinking functions
- DLLINTERFACE void rotozoomSurfaceSizeXY
- (int width, int height, double angle, double zoomx, double zoomy,
- int *dstwidth, int *dstheight);
+ */
-/*
-
- zoomSurface()
+ SDL_ROTOZOOM_SCOPE SDL_Surface *shrinkSurface(SDL_Surface * src, int factorx, int factory);
- Zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface.
- 'zoomx' and 'zoomy' are scaling factors for width and height. If 'smooth' is 1
- then the destination 32bit surface is anti-aliased. If the surface is not 8bit
- or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
+ /*
-*/
+ Specialized rotation functions
- DLLINTERFACE SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth);
+ */
-/* Returns the size of the target surface for a zoomSurface() call */
+ SDL_ROTOZOOM_SCOPE SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns);
- DLLINTERFACE void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight);
-
-
-/*
- shrinkSurface()
-
- Shrinks a 32bit or 8bit 'src' surface ti a newly created 'dst' surface.
- 'factorx' and 'factory' are the shrinking ratios (i.e. 2=1/2 the size,
- 3=1/3 the size, etc.) The destination surface is antialiased by averaging
- the source box RGBA or Y information. If the surface is not 8bit
- or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly.
-*/
-
- DLLINTERFACE SDL_Surface *shrinkSurface(SDL_Surface * src, int factorx, int factory);
-
-/*
-
- Other functions
-
-*/
-
- DLLINTERFACE SDL_Surface* rotateSurface90Degrees(SDL_Surface* pSurf, int numClockwiseTurns);
-
-/* Ends C function definitions when using C++ */
+ /* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
diff --git a/src/sdl-instead/game.c b/src/sdl-instead/game.c
index ac5ff82..5f5845c 100644
--- a/src/sdl-instead/game.c
+++ b/src/sdl-instead/game.c
@@ -644,8 +644,7 @@ int game_change_hz(int hz)
}
unsigned int timer_counter = 0;
-
-gtimer_t timer_han = NULL;
+gtimer_t timer_han = NULL_TIMER;
static void anigif_do(void *data)
{
@@ -832,7 +831,7 @@ void game_release_theme(void)
void game_done(int err)
{
gfx_del_timer(timer_han);
- timer_han = NULL;
+ timer_han = NULL_TIMER;
if (opt_autosave && curgame_dir && !err)
game_save(0);
@@ -1681,7 +1680,7 @@ inv:
}
{ /* highlight new scene, to avoid flickering */
int x, y;
- gfx_cursor(&x, &y, NULL, NULL);
+ gfx_cursor(&x, &y);
game_highlight(x, y, 1);
}
game_cursor(CURSOR_DRAW);
@@ -2085,7 +2084,7 @@ void game_cursor(int on)
int oh = h;
if (on != CURSOR_DRAW) {
- gfx_cursor(&xc, &yc, NULL, NULL);
+ gfx_cursor(&xc, &yc);
xc -= game_theme.cur_x;
yc -= game_theme.cur_y;
}
@@ -2096,7 +2095,7 @@ void game_cursor(int on)
grab = gfx_grab_screen(xc, yc, w, h);
if (mouse_focus())
gfx_draw(cur, xc, yc);
-
+
if (on != CURSOR_DRAW) {
gfx_update(xc, yc, w, h);
gfx_update(ox, oy, ow, oh);
@@ -2218,7 +2217,7 @@ static void select_frame(int prev)
struct el *elem = NULL;
int x, y, w, h;
- gfx_cursor(&x, &y, NULL, NULL);
+ gfx_cursor(&x, &y);
elem = look_obj(x, y);
@@ -2338,7 +2337,7 @@ static int select_ref(int prev, int last)
int x, y;
struct el *elem = NULL;
xref_t xref = NULL;
- gfx_cursor(&x, &y, NULL, NULL);
+ gfx_cursor(&x, &y);
xref = look_xref(x, y, &elem);
@@ -2379,7 +2378,7 @@ static void game_scroll_up(int count)
{
int xm, ym;
struct el *o;
- gfx_cursor(&xm, &ym, NULL, NULL);
+ gfx_cursor(&xm, &ym);
o = look_obj(xm, ym);
if (o && (o->id == el_scene || o->id == el_inv)) {
scroll_up(o->id, count);
@@ -2390,7 +2389,7 @@ static void game_scroll_down(int count)
{
int xm, ym;
struct el *o;
- gfx_cursor(&xm, &ym, NULL, NULL);
+ gfx_cursor(&xm, &ym);
o = look_obj(xm, ym);
if (o && (o->id == el_scene || o->id == el_inv)) {
scroll_down(o->id, count);
@@ -2401,7 +2400,7 @@ static int game_scroll_pup(void)
{
int xm, ym;
struct el *o;
- gfx_cursor(&xm, &ym, NULL, NULL);
+ gfx_cursor(&xm, &ym);
o = look_obj(xm, ym);
if (o && (o->id == el_scene || o->id == el_inv)) {
return scroll_pup(o->id);
@@ -2413,7 +2412,7 @@ static int game_scroll_pdown(void)
{
int xm, ym;
struct el *o;
- gfx_cursor(&xm, &ym, NULL, NULL);
+ gfx_cursor(&xm, &ym);
o = look_obj(xm, ym);
if (o && (o->id == el_scene || o->id == el_inv)) {
return scroll_pdown(o->id);
@@ -2423,8 +2422,6 @@ static int game_scroll_pdown(void)
static int is_key(struct inp_event *ev, const char *name)
{
- if (!ev->sym)
- return -1;
return strcmp(ev->sym, name);
}
@@ -2713,7 +2710,7 @@ int game_loop(void)
|| !is_key(&ev, ".")
#endif
)) {
- gfx_cursor(&x, &y, NULL, NULL);
+ gfx_cursor(&x, &y);
game_highlight(-1, -1, 0); /* reset */
game_click(x, y, 0, 0);
@@ -2840,7 +2837,7 @@ int game_loop(void)
game_highlight(x, y, 1);
else {
int x, y;
- gfx_cursor(&x, &y, NULL, NULL);
+ gfx_cursor(&x, &y);
game_highlight(x, y, 1);
}
game_cursor(CURSOR_ON);
diff --git a/src/sdl-instead/graphics.c b/src/sdl-instead/graphics.c
index 1d48f21..4809fcf 100644
--- a/src/sdl-instead/graphics.c
+++ b/src/sdl-instead/graphics.c
@@ -588,7 +588,10 @@ img_t gfx_alpha_img(img_t src, int alpha)
else
img = gfx_new(Surf(src)->w, Surf(src)->h);
if (!img)
- return NULL;
+ return NULL;
+#if SDL_VERSION_ATLEAST(1,3,0)
+ SDL_SetAlpha(img, SDL_SRCALPHA, 255);
+#endif
ptr = (Uint32*)img->pixels;
size = img->w * img->h;
while (size --) {
@@ -604,7 +607,11 @@ img_t gfx_alpha_img(img_t src, int alpha)
void gfx_set_alpha(img_t src, int alpha)
{
+#if SDL_VERSION_ATLEAST(1,3,0)
+ SDL_SetAlpha((SDL_Surface *)src, SDL_SRCALPHA, alpha);
+#else
SDL_SetAlpha((SDL_Surface *)src, SDL_SRCALPHA | SDL_RLEACCEL, alpha);
+#endif
}
img_t gfx_combine(img_t src, img_t dst)
@@ -769,7 +776,11 @@ static img_t _gfx_load_image(char *filename)
rwop = SDL_RWFromFile(filename, "rb");
if (rwop) {
if (IMG_isBMP(rwop))
+#if SDL_VERSION_ATLEAST(1,3,0)
+ SDL_SetAlpha(img, 0, SDL_ALPHA_OPAQUE);
+#else
SDL_SetAlpha(img, SDL_RLEACCEL, SDL_ALPHA_OPAQUE);
+#endif
SDL_RWclose(rwop);
}
}
@@ -3596,22 +3607,16 @@ void txt_layout_real_size(layout_t lay, int *pw, int *ph)
*ph = h;
}
-void gfx_cursor(int *xp, int *yp, int *w, int *h)
+void gfx_cursor(int *xp, int *yp)
{
int x, y;
- SDL_Cursor *c = SDL_GetCursor();
- if (!c)
- return;
SDL_GetMouseState(&x, &y);
- if (w)
- *w = c->area.w - c->hot_x;
- if (h)
- *h = c->area.h - c->hot_y;
if (xp)
*xp = x;
if (yp)
*yp = y;
}
+
void gfx_warp_cursor(int x, int y)
{
SDL_WarpMouse(x, y);
@@ -3685,7 +3690,11 @@ void gfx_done(void)
gtimer_t gfx_add_timer(int delay, int (*fn)(int, void*), void *aux)
{
+#if SDL_VERSION_ATLEAST(1,3,0)
+ return (gtimer_t)SDL_AddTimer(delay, (SDL_TimerCallback)fn, aux);
+#else
return (gtimer_t)SDL_AddTimer(delay, (SDL_NewTimerCallback)fn, aux);
+#endif
}
void gfx_del_timer(gtimer_t han)
diff --git a/src/sdl-instead/graphics.h b/src/sdl-instead/graphics.h
index 34fe32c..095641f 100644
--- a/src/sdl-instead/graphics.h
+++ b/src/sdl-instead/graphics.h
@@ -1,6 +1,6 @@
#ifndef __GRAPHICS_H__
#define __GRAPHICS_H__
-
+#include
/* #define GFX_CACHE_SIZE 64
#define GFX_MAX_CACHED_W 256
#define GFX_MAX_CACHED_H 256
@@ -8,7 +8,13 @@
#define LINK_CACHE_SIZE 64
*/
+#if SDL_VERSION_ATLEAST(1,3,0)
+typedef int gtimer_t;
+#define NULL_TIMER 0
+#else
typedef void* gtimer_t;
+#define NULL_TIMER NULL
+#endif
typedef void* img_t;
typedef void* fnt_t;
typedef void* layout_t;
@@ -81,7 +87,7 @@ extern img_t gfx_display_alpha(img_t src);
extern img_t gfx_scale(img_t src, float xscale, float yscale);
extern void gfx_draw_bg(img_t p, int x, int y, int width, int height);
extern void gfx_draw_from(img_t p, int x, int y, int xx, int yy, int width, int height);
-extern void gfx_cursor(int *xp, int *yp, int *w, int *h);
+extern void gfx_cursor(int *xp, int *yp);
extern void gfx_warp_cursor(int x, int y);
extern void gfx_change_screen(img_t src, int steps);
extern int gfx_fading(void);
diff --git a/src/sdl-instead/input.c b/src/sdl-instead/input.c
index 08f5b67..d89ce9e 100644
--- a/src/sdl-instead/input.c
+++ b/src/sdl-instead/input.c
@@ -67,10 +67,9 @@ int input(struct inp_event *inp, int wait)
rc = SDL_PollEvent(&event);
if (!rc)
return 0;
- inp->sym = NULL;
+ inp->sym[0] = 0;
inp->type = 0;
inp->count = 1;
-
switch(event.type){
case SDL_ACTIVEEVENT:
if (event.active.state & SDL_APPACTIVE) {
@@ -88,7 +87,11 @@ int input(struct inp_event *inp, int wait)
mouse_cursor(1); /* is it hack?*/
}
}
+#if SDL_VERSION_ATLEAST(1,3,0)
+ if (SDL_PeepEvents(&peek, 1, SDL_PEEKEVENT, SDL_ACTIVEEVENT, SDL_ACTIVEEVENT) > 0)
+#else
if (SDL_PeepEvents(&peek, 1, SDL_PEEKEVENT, SDL_EVENTMASK(SDL_ACTIVEEVENT)) > 0)
+#endif
return AGAIN; /* to avoid flickering */
return 0;
case SDL_USEREVENT: {
@@ -102,19 +105,27 @@ int input(struct inp_event *inp, int wait)
case SDL_KEYDOWN: //A key has been pressed
inp->type = KEY_DOWN;
inp->code = event.key.keysym.scancode;
- inp->sym = SDL_GetKeyName(event.key.keysym.sym);
+ strncpy(inp->sym, SDL_GetKeyName(event.key.keysym.sym), sizeof(inp->sym));
+ inp->sym[sizeof(inp->sym) - 1] = 0;
+ tolow(inp->sym);
break;
case SDL_KEYUP:
inp->type = KEY_UP;
inp->code = event.key.keysym.scancode;
- inp->sym = SDL_GetKeyName(event.key.keysym.sym);
+ strncpy(inp->sym, SDL_GetKeyName(event.key.keysym.sym), sizeof(inp->sym));
+ inp->sym[sizeof(inp->sym) - 1] = 0;
+ tolow(inp->sym);
break;
case SDL_MOUSEMOTION:
m_focus = 1; /* ahhh */
inp->type = MOUSE_MOTION;
inp->x = event.button.x;
inp->y = event.button.y;
+#if SDL_VERSION_ATLEAST(1,3,0)
+ while (SDL_PeepEvents(&peek, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION) > 0) {
+#else
while (SDL_PeepEvents(&peek, 1, SDL_GETEVENT, SDL_EVENTMASK (SDL_MOUSEMOTION)) > 0) {
+#endif
inp->x = peek.button.x;
inp->y = peek.button.y;
}
@@ -139,7 +150,11 @@ int input(struct inp_event *inp, int wait)
inp->type = MOUSE_WHEEL_UP;
else if (event.button.button == 5)
inp->type = MOUSE_WHEEL_DOWN;
+#if SDL_VERSION_ATLEAST(1,3,0)
+ while (SDL_PeepEvents(&peek, 1, SDL_GETEVENT, SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONDOWN) > 0) {
+#else
while (SDL_PeepEvents(&peek, 1, SDL_GETEVENT, SDL_EVENTMASK (SDL_MOUSEBUTTONDOWN)) > 0) {
+#endif
if (!((event.button.button == 4 &&
inp->type == MOUSE_WHEEL_UP) ||
(event.button.button == 5 &&
diff --git a/src/sdl-instead/input.h b/src/sdl-instead/input.h
index 9b7e52b..11ab78e 100644
--- a/src/sdl-instead/input.h
+++ b/src/sdl-instead/input.h
@@ -14,7 +14,7 @@
struct inp_event {
int type;
int code;
- char *sym;
+ char sym[64];
int x;
int y;
int count;
diff --git a/src/sdl-instead/instead.c b/src/sdl-instead/instead.c
index 9dae920..9858678 100644
--- a/src/sdl-instead/instead.c
+++ b/src/sdl-instead/instead.c
@@ -7,7 +7,7 @@
/* the Lua interpreter */
-static gtimer_t instead_timer = NULL;
+static gtimer_t instead_timer = NULL_TIMER;
static int instead_timer_nr = 0;
char *fromgame(const char *s);
@@ -29,7 +29,7 @@ static int report (lua_State *L, int status)
lua_pop(L, 1);
status = -1;
gfx_del_timer(instead_timer); /* to avoid error loops */
- instead_timer = NULL;
+ instead_timer = NULL_TIMER;
}
return status;
}
@@ -491,7 +491,7 @@ static int luaB_set_timer(lua_State *L) {
const char *delay = luaL_optstring(L, 1, NULL);
int d;
gfx_del_timer(instead_timer);
- instead_timer = NULL;
+ instead_timer = NULL_TIMER;
if (!delay)
d = 0;
else
@@ -613,7 +613,7 @@ int instead_init(void)
void instead_done(void)
{
gfx_del_timer(instead_timer);
- instead_timer = NULL;
+ instead_timer = NULL_TIMER;
#ifdef _HAVE_ICONV
if (fromcp)
free(fromcp);
diff --git a/src/sdl-instead/sound.c b/src/sdl-instead/sound.c
index d5b40a9..e1116ab 100644
--- a/src/sdl-instead/sound.c
+++ b/src/sdl-instead/sound.c
@@ -18,7 +18,7 @@ static mus_t mus;
static char *next_mus = NULL;
static int next_fadein = 0;
static int next_loop = -1;
-static SDL_TimerID timer_id = NULL;
+static SDL_TimerID timer_id = NULL_TIMER;
static int sound_on = 0;
@@ -42,7 +42,7 @@ static void mus_callback(void *aux)
next_mus = NULL;
}
SDL_RemoveTimer(timer_id);
- timer_id = NULL;
+ timer_id = NULL_TIMER;
}
static Uint32 callback(Uint32 interval, void *aux)
@@ -273,7 +273,7 @@ void snd_done(void)
Mix_HaltChannel(-1);
Mix_HaltMusic();
- timer_id = NULL;
+ timer_id = NULL_TIMER;
if (mus)
snd_free_mus(mus);
mus = NULL;