From c180844aee7ea6779e48fabdd9d3e489c1cf5a83 Mon Sep 17 00:00:00 2001
From: "p.kosyh"
Date: Fri, 2 Oct 2009 17:18:09 +0000
Subject: [PATCH] anigif next stage..
---
Rules.make.standalone | 4 +-
src/sdl-instead/SDL_anigif.c | 1485 +++++++++++++++++-----------------
src/sdl-instead/SDL_anigif.h | 122 +--
src/sdl-instead/game.c | 2 +
src/sdl-instead/graphics.c | 53 +-
5 files changed, 856 insertions(+), 810 deletions(-)
diff --git a/Rules.make.standalone b/Rules.make.standalone
index 0843ff9..88b5292 100644
--- a/Rules.make.standalone
+++ b/Rules.make.standalone
@@ -16,8 +16,8 @@ LUA_LFLAGS=$(shell pkg-config --libs lua5.1)
# for arch linux, fedora (may be others) use this
#
-# LUA_CFLAGS=$(shell pkg-config --cflags lua)
-# LUA_LFLAGS=$(shell pkg-config --libs lua)
+LUA_CFLAGS=$(shell pkg-config --cflags lua)
+LUA_LFLAGS=$(shell pkg-config --libs lua)
#
SDL_CFLAGS=$(shell sdl-config --cflags)
diff --git a/src/sdl-instead/SDL_anigif.c b/src/sdl-instead/SDL_anigif.c
index 7674743..f96366e 100644
--- a/src/sdl-instead/SDL_anigif.c
+++ b/src/sdl-instead/SDL_anigif.c
@@ -1,738 +1,747 @@
-/*
- SDL_anigif: An example animated GIF image loading library for use with SDL
- SDL_image Copyright (C) 1997-2006 Sam Lantinga
- Animated GIF "derived work" Copyright (C) 2006 Doug McFadyen
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include
-#include
-#include "SDL_anigif.h"
-
-
-
-/* Code from here to end of file has been adapted from XPaint: */
-/* +-------------------------------------------------------------------+ */
-/* | Copyright 1990, 1991, 1993 David Koblas. | */
-/* | Copyright 1996 Torsten Martinsen. | */
-/* | Permission to use, copy, modify, and distribute this software | */
-/* | and its documentation for any purpose and without fee is hereby | */
-/* | granted, provided that the above copyright notice appear in all | */
-/* | copies and that both that copyright notice and this permission | */
-/* | notice appear in supporting documentation. This software is | */
-/* | provided "as is" without express or implied warranty. | */
-/* +-------------------------------------------------------------------+ */
-/* Adapted for use in SDL by Sam Lantinga -- 7/20/98 */
-/* Animated GIF support by Doug McFadyen -- 10/19/06 */
-
-#define MAXCOLORMAPSIZE 256
-
-#define TRUE 1
-#define FALSE 0
-
-#define CM_RED 0
-#define CM_GREEN 1
-#define CM_BLUE 2
-
-#define MAX_LWZ_BITS 12
-
-#define INTERLACE 0x40
-#define LOCALCOLORMAP 0x80
-#define BitSet(byte,bit) (((byte) & (bit)) == (bit))
-#define LM_to_uint(a,b) (((b)<<8)|(a))
-
-#define SDL_SetError(t) ((void)0) /* We're not SDL so ignore error reporting */
-
-
-typedef struct
-{
- unsigned int Width;
- unsigned int Height;
- unsigned char ColorMap[3][MAXCOLORMAPSIZE];
- unsigned int BitPixel;
- unsigned int ColorResolution;
- unsigned int Background;
- unsigned int AspectRatio;
-} gifscreen;
-
-typedef struct
-{
- int transparent;
- int delayTime;
- int inputFlag;
- int disposal;
-} gif89;
-
-typedef struct
-{
- /* global data */
- SDL_RWops* src;
- gifscreen gs;
- gif89 g89;
- int zerodatablock;
- /* AG_LoadGIF_RW data */
- unsigned char localColorMap[3][MAXCOLORMAPSIZE];
- /* GetCode data */
- unsigned char buf[280];
- int curbit, lastbit, done, lastbyte;
- /* LWZReadByte data */
- int fresh, code, incode;
- int codesize, setcodesize;
- int maxcode, maxcodesize;
- int firstcode, oldcode;
- int clearcode, endcode;
- int table[2][(1 << MAX_LWZ_BITS)];
- int stack[(1 << (MAX_LWZ_BITS))*2], *sp;
-} gifdata;
-
-
-
-static int ReadColorMap( gifdata* gd, int number, unsigned char buffer[3][MAXCOLORMAPSIZE] );
-static int DoExtension( gifdata* gd, int label );
-static int GetDataBlock( gifdata* gd, unsigned char* buf );
-static int GetCode( gifdata* gd, int code_size, int flag );
-static int LWZReadByte( gifdata* gd, int flag, int input_code_size );
-static SDL_Surface* ReadImage( gifdata* gd, int len, int height, int, unsigned char cmap[3][MAXCOLORMAPSIZE], int interlace, int ignore );
-
-
-
-int AG_isGIF( SDL_RWops* src )
-{
- int isGIF = FALSE;
-
- if ( src )
- {
- int start = SDL_RWtell( src );
- char magic[6];
-
- if ( SDL_RWread(src,magic,sizeof(magic),1) )
- {
- if ( (strncmp(magic,"GIF",3) == 0) && ((memcmp(magic+3,"87a",3) == 0) || (memcmp(magic+3,"89a",3) == 0)) )
- {
- isGIF = TRUE;
- }
- }
-
- SDL_RWseek( src, start, SEEK_SET );
- }
-
- return isGIF;
-}
-
-int AG_LoadGIF( const char* file, AG_Frame* frames, int size )
-{
- int n = 0;
-
- SDL_RWops* src = SDL_RWFromFile( file, "rb" );
-
- if ( src )
- {
- n = AG_LoadGIF_RW( src, frames, size );
- SDL_RWclose( src );
- }
-
- return n;
-}
-
-
-
-void AG_FreeSurfaces( AG_Frame* frames, int nFrames )
-{
- int i;
-
- if ( frames )
- {
- for ( i = 0; i < nFrames; i++ )
- {
- if ( frames[i].surface )
- {
- SDL_FreeSurface( frames[i].surface );
- frames[i].surface = NULL;
- }
- }
- }
-}
-
-
-
-int AG_ConvertSurfacesToDisplayFormat( AG_Frame* frames, int nFrames )
-{
- int i;
- int n = 0;
-
- if ( frames )
- {
- for ( i = 0; i < nFrames; i++ )
- {
- if ( frames[i].surface )
- {
- SDL_Surface* surface = (frames[i].surface->flags & SDL_SRCCOLORKEY) ? SDL_DisplayFormatAlpha(frames[i].surface) : SDL_DisplayFormat(frames[i].surface);
-
- if ( surface )
- {
- SDL_FreeSurface( frames[i].surface );
- frames[i].surface = surface;
- n++;
- }
- }
- }
- }
-
- return n;
-}
-
-
-
-int AG_NormalizeSurfacesToDisplayFormat( AG_Frame* frames, int nFrames )
-{
- int n = 0;
-
- if ( nFrames > 0 && frames && frames[0].surface )
- {
- SDL_Surface* mainSurface = (frames[0].surface->flags & SDL_SRCCOLORKEY) ? SDL_DisplayFormatAlpha(frames[0].surface) : SDL_DisplayFormat(frames[0].surface);
- const int newDispose = (frames[0].surface->flags & SDL_SRCCOLORKEY) ? AG_DISPOSE_RESTORE_BACKGROUND : AG_DISPOSE_NONE;
-
- if ( mainSurface )
- {
- int i;
- int lastDispose = AG_DISPOSE_NA;
- int iRestore = 0;
- const Uint8 alpha = (frames[0].disposal == AG_DISPOSE_NONE) ? SDL_ALPHA_OPAQUE : SDL_ALPHA_TRANSPARENT;
-
- SDL_FillRect( mainSurface, NULL, SDL_MapRGBA(mainSurface->format,0,0,0,alpha) );
-
- for ( i = 0; i < nFrames; i++ )
- {
- if ( frames[i].surface )
- {
- SDL_Surface* surface = SDL_ConvertSurface( mainSurface, mainSurface->format, mainSurface->flags );
-
- if ( surface )
- {
- SDL_Rect r;
-
- if ( lastDispose == AG_DISPOSE_NONE )
- SDL_BlitSurface( frames[i-1].surface, NULL, surface, NULL );
-
- if ( lastDispose == AG_DISPOSE_RESTORE_PREVIOUS )
- SDL_BlitSurface( frames[iRestore].surface, NULL, surface, NULL );
- if ( frames[i].disposal != AG_DISPOSE_RESTORE_PREVIOUS )
- iRestore = i;
-
- r.x = (Sint16)frames[i].x;
- r.y = (Sint16)frames[i].y;
- SDL_BlitSurface( frames[i].surface, NULL, surface, &r );
-
- SDL_FreeSurface( frames[i].surface );
- frames[i].surface = surface;
- frames[i].x = frames[i].y = 0;
- lastDispose = frames[i].disposal;
- frames[i].disposal = newDispose;
- n++;
- }
- }
- }
-
- SDL_FreeSurface( mainSurface );
- }
- }
-
- return n;
-}
-
-
-
-int AG_LoadGIF_RW( SDL_RWops* src, AG_Frame* frames, int maxFrames )
-{
- int start;
- unsigned char buf[16];
- unsigned char c;
- int useGlobalColormap;
- int bitPixel;
- int iFrame = 0;
- char version[4];
- SDL_Surface* image = NULL;
- gifdata* gd;
-
- if ( src == NULL )
- return 0;
-
- gd = malloc( sizeof(*gd) );
- memset( gd, 0, sizeof(*gd) );
- gd->src = src;
-
- start = SDL_RWtell( src );
-
- if ( !SDL_RWread(src,buf,6,1) )
- {
- SDL_SetError( "error reading magic number" );
- goto done;
- }
-
- if ( strncmp((char*)buf,"GIF",3) != 0 )
- {
- SDL_SetError( "not a GIF file" );
- goto done;
- }
-
- strncpy( version, (char*)buf+3, 3 );
- version[3] = '\0';
-
- if ( (strcmp(version,"87a") != 0) && (strcmp(version,"89a") != 0) )
- {
- SDL_SetError( "bad version number, not '87a' or '89a'" );
- goto done;
- }
-
- gd->g89.transparent = -1;
- gd->g89.delayTime = -1;
- gd->g89.inputFlag = -1;
- gd->g89.disposal = AG_DISPOSE_NA;
-
- if ( !SDL_RWread(src,buf,7,1) )
- {
- SDL_SetError( "failed to read screen descriptor" );
- goto done;
- }
-
- gd->gs.Width = LM_to_uint(buf[0],buf[1]);
- gd->gs.Height = LM_to_uint(buf[2],buf[3]);
- gd->gs.BitPixel = 2 << (buf[4] & 0x07);
- gd->gs.ColorResolution = (((buf[4] & 0x70) >> 3) + 1);
- gd->gs.Background = buf[5];
- gd->gs.AspectRatio = buf[6];
-
- if ( BitSet(buf[4],LOCALCOLORMAP) ) /* Global Colormap */
- {
- if ( ReadColorMap(gd,gd->gs.BitPixel,gd->gs.ColorMap) )
- {
- SDL_SetError( "error reading global colormap" );
- goto done;
- }
- }
-
- do
- {
- if ( !SDL_RWread(src,&c,1,1) )
- {
- SDL_SetError( "EOF / read error on image data" );
- goto done;
- }
-
- if ( c == ';' ) /* GIF terminator */
- goto done;
-
- if ( c == '!' ) /* Extension */
- {
- if ( !SDL_RWread(src,&c,1,1) )
- {
- SDL_SetError( "EOF / read error on extention function code" );
- goto done;
- }
- DoExtension( gd, c );
- continue;
- }
-
- if ( c != ',' ) /* Not a valid start character */
- continue;
-
- if ( !SDL_RWread(src,buf,9,1) )
- {
- SDL_SetError( "couldn't read left/top/width/height" );
- goto done;
- }
-
- useGlobalColormap = !BitSet(buf[8],LOCALCOLORMAP);
- bitPixel = 1 << ((buf[8] & 0x07) + 1);
-
- if ( !useGlobalColormap )
- {
- if ( ReadColorMap(gd,bitPixel,gd->localColorMap) )
- {
- SDL_SetError( "error reading local colormap" );
- goto done;
- }
- image = ReadImage( gd, LM_to_uint(buf[4],buf[5]), LM_to_uint(buf[6],buf[7]), bitPixel, gd->localColorMap, BitSet(buf[8],INTERLACE), (frames==NULL) );
- }
- else
- {
- image = ReadImage( gd, LM_to_uint(buf[4],buf[5]), LM_to_uint(buf[6],buf[7]), gd->gs.BitPixel, gd->gs.ColorMap, BitSet(buf[8],INTERLACE), (frames==NULL) );
- }
-
- if ( frames )
- {
- if ( image == NULL )
- goto done;
-
- if ( gd->g89.transparent >= 0 )
- SDL_SetColorKey( image, SDL_SRCCOLORKEY, gd->g89.transparent );
-
- frames[iFrame].surface = image;
- frames[iFrame].x = LM_to_uint(buf[0], buf[1]);
- frames[iFrame].y = LM_to_uint(buf[2], buf[3]);
- frames[iFrame].disposal = gd->g89.disposal;
- frames[iFrame].delay = gd->g89.delayTime*10;
-/* gd->g89.transparent = -1; ** Hmmm, not sure if this should be reset for each frame? */
- }
-
- iFrame++;
- } while ( iFrame < maxFrames || frames == NULL );
-
-done:
- if ( image == NULL )
- SDL_RWseek( src, start, SEEK_SET );
-
- free( gd );
-
- return iFrame;
-}
-
-
-
-static int ReadColorMap( gifdata* gd, int number, unsigned char buffer[3][MAXCOLORMAPSIZE] )
-{
- int i;
- unsigned char rgb[3];
- int flag;
-
- flag = TRUE;
-
- for ( i = 0; i < number; ++i )
- {
- if ( !SDL_RWread(gd->src,rgb,sizeof(rgb),1) )
- {
- SDL_SetError( "bad colormap" );
- return 1;
- }
-
- buffer[CM_RED][i] = rgb[0];
- buffer[CM_GREEN][i] = rgb[1];
- buffer[CM_BLUE][i] = rgb[2];
- flag &= (rgb[0] == rgb[1] && rgb[1] == rgb[2]);
- }
-
- return FALSE;
-}
-
-
-
-static int DoExtension( gifdata* gd, int label )
-{
- unsigned char buf[256];
-
- switch ( label )
- {
- case 0x01: /* Plain Text Extension */
- break;
-
- case 0xff: /* Application Extension */
- break;
-
- case 0xfe: /* Comment Extension */
- while ( GetDataBlock(gd,buf) != 0 )
- ;
- return FALSE;
-
- case 0xf9: /* Graphic Control Extension */
- (void)GetDataBlock( gd, buf );
- gd->g89.disposal = (buf[0] >> 2) & 0x7;
- gd->g89.inputFlag = (buf[0] >> 1) & 0x1;
- gd->g89.delayTime = LM_to_uint(buf[1],buf[2]);
- if ( (buf[0] & 0x1) != 0 )
- gd->g89.transparent = buf[3];
-
- while ( GetDataBlock(gd,buf) != 0 )
- ;
- return FALSE;
- }
-
- while ( GetDataBlock(gd,buf) != 0 )
- ;
-
- return FALSE;
-}
-
-
-
-static int GetDataBlock( gifdata* gd, unsigned char* buf )
-{
- unsigned char count;
-
- if ( !SDL_RWread(gd->src,&count,1,1) )
- {
- /* pm_message("error in getting DataBlock size" ); */
- return -1;
- }
-
- gd->zerodatablock = count == 0;
-
- if ( (count != 0) && !SDL_RWread(gd->src,buf,count,1) )
- {
- /* pm_message("error in reading DataBlock" ); */
- return -1;
- }
-
- return count;
-}
-
-
-
-static int GetCode( gifdata* gd, int code_size, int flag )
-{
- int i, j, ret;
- int count;
-
- if ( flag )
- {
- gd->curbit = 0;
- gd->lastbit = 0;
- gd->done = FALSE;
- return 0;
- }
-
- if ( (gd->curbit + code_size) >= gd->lastbit )
- {
- if ( gd->done )
- {
- if ( gd->curbit >= gd->lastbit )
- SDL_SetError( "ran off the end of my bits" );
- return -1;
- }
-
- gd->buf[0] = gd->buf[gd->lastbyte - 2];
- gd->buf[1] = gd->buf[gd->lastbyte - 1];
-
- if ( (count = GetDataBlock(gd, &gd->buf[2])) == 0 )
- gd->done = TRUE;
-
- gd->lastbyte = 2 + count;
- gd->curbit = (gd->curbit - gd->lastbit) + 16;
- gd->lastbit = (2 + count)*8;
- }
-
- ret = 0;
- for ( i = gd->curbit, j = 0; j < code_size; ++i, ++j )
- ret |= ((gd->buf[i / 8] & (1 << (i % 8))) != 0) << j;
-
- gd->curbit += code_size;
-
- return ret;
-}
-
-
-
-static int LWZReadByte( gifdata* gd, int flag, int input_code_size )
-{
- int i, code, incode;
-
- if ( flag )
- {
- gd->setcodesize = input_code_size;
- gd->codesize = gd->setcodesize + 1;
- gd->clearcode = 1 << gd->setcodesize;
- gd->endcode = gd->clearcode + 1;
- gd->maxcodesize = gd->clearcode*2;
- gd->maxcode = gd->clearcode + 2;
-
- GetCode( gd, 0, TRUE );
-
- gd->fresh = TRUE;
-
- for ( i = 0; i < gd->clearcode; ++i )
- {
- gd->table[0][i] = 0;
- gd->table[1][i] = i;
- }
-
- for ( ; i < (1 << MAX_LWZ_BITS); ++i )
- gd->table[0][i] = gd->table[1][0] = 0;
-
- gd->sp = gd->stack;
- return 0;
- }
- else if ( gd->fresh )
- {
- gd->fresh = FALSE;
- do
- {
- gd->firstcode = gd->oldcode = GetCode( gd, gd->codesize, FALSE );
- } while ( gd->firstcode == gd->clearcode );
- return gd->firstcode;
- }
-
- if ( gd->sp > gd->stack )
- return *--gd->sp;
-
- while ( (code = GetCode(gd,gd->codesize,FALSE)) >= 0 )
- {
- if ( code == gd->clearcode )
- {
- for ( i = 0; i < gd->clearcode; ++i )
- {
- gd->table[0][i] = 0;
- gd->table[1][i] = i;
- }
-
- for ( ; i < (1 << MAX_LWZ_BITS); ++i )
- gd->table[0][i] = gd->table[1][i] = 0;
-
- gd->codesize = gd->setcodesize + 1;
- gd->maxcodesize = gd->clearcode*2;
- gd->maxcode = gd->clearcode + 2;
- gd->sp = gd->stack;
- gd->firstcode = gd->oldcode = GetCode( gd, gd->codesize, FALSE );
- return gd->firstcode;
- }
- else if ( code == gd->endcode )
- {
- int count;
- unsigned char buf[260];
-
- if ( gd->zerodatablock )
- return -2;
-
- while ( (count = GetDataBlock(gd,buf)) > 0 )
- ;
-
- if ( count != 0 )
- {
- /* pm_message("missing EOD in data stream (common occurence)"); */
- }
- return -2;
- }
-
- incode = code;
-
- if ( code >= gd->maxcode )
- {
- *gd->sp++ = gd->firstcode;
- code = gd->oldcode;
- }
-
- while ( code >= gd->clearcode )
- {
- *gd->sp++ = gd->table[1][code];
- if ( code == gd->table[0][code] )
- SDL_SetError( "circular table entry BIG ERROR" );
- code = gd->table[0][code];
- }
-
- *gd->sp++ = gd->firstcode = gd->table[1][code];
-
- if ( (code = gd->maxcode) < (1 << MAX_LWZ_BITS) )
- {
- gd->table[0][code] = gd->oldcode;
- gd->table[1][code] = gd->firstcode;
- ++gd->maxcode;
- if ( (gd->maxcode >= gd->maxcodesize) && (gd->maxcodesize < (1 << MAX_LWZ_BITS)) )
- {
- gd->maxcodesize *= 2;
- ++gd->codesize;
- }
- }
-
- gd->oldcode = incode;
-
- if ( gd->sp > gd->stack )
- return *--gd->sp;
- }
-
- return code;
-}
-
-
-
-static SDL_Surface* ReadImage( gifdata* gd, int len, int height, int cmapSize, unsigned char cmap[3][MAXCOLORMAPSIZE], int interlace, int ignore )
-{
- SDL_Surface* image;
- unsigned char c;
- int i, v;
- int xpos = 0, ypos = 0, pass = 0;
-
- /* Initialize the compression routines */
- if ( !SDL_RWread(gd->src,&c,1,1) )
- {
- SDL_SetError( "EOF / read error on image data" );
- return NULL;
- }
-
- if ( LWZReadByte(gd,TRUE,c) < 0 )
- {
- SDL_SetError( "error reading image" );
- return NULL;
- }
-
- /* If this is an "uninteresting picture" ignore it. */
- if ( ignore )
- {
- while ( LWZReadByte(gd,FALSE,c) >= 0 )
- ;
- return NULL;
- }
-
- image = SDL_AllocSurface( SDL_SWSURFACE, len, height, 8, 0, 0, 0, 0 );
-
- for ( i = 0; i < cmapSize; i++ )
- {
- image->format->palette->colors[i].r = cmap[CM_RED][i];
- image->format->palette->colors[i].g = cmap[CM_GREEN][i];
- image->format->palette->colors[i].b = cmap[CM_BLUE][i];
- }
-
- while ( (v = LWZReadByte(gd,FALSE,c)) >= 0 )
- {
- ((Uint8*)image->pixels)[xpos + ypos*image->pitch] = (Uint8)v;
- ++xpos;
-
- if ( xpos == len )
- {
- xpos = 0;
- if ( interlace )
- {
- switch ( pass )
- {
- case 0:
- case 1: ypos += 8; break;
- case 2: ypos += 4; break;
- case 3: ypos += 2; break;
- }
-
- if ( ypos >= height )
- {
- ++pass;
- switch ( pass )
- {
- case 1: ypos = 4; break;
- case 2: ypos = 2; break;
- case 3: ypos = 1; break;
- default: goto fini;
- }
- }
- }
- else
- {
- ++ypos;
- }
- }
-
- if ( ypos >= height )
- break;
- }
-
-fini:
- return image;
-}
-
+/*
+ SDL_anigif: An example animated GIF image loading library for use with SDL
+ SDL_image Copyright (C) 1997-2006 Sam Lantinga
+ Animated GIF "derived work" Copyright (C) 2006 Doug McFadyen
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include
+#include
+#include "SDL_anigif.h"
+
+
+
+/* Code from here to end of file has been adapted from XPaint: */
+/* +-------------------------------------------------------------------+ */
+/* | Copyright 1990, 1991, 1993 David Koblas. | */
+/* | Copyright 1996 Torsten Martinsen. | */
+/* | Permission to use, copy, modify, and distribute this software | */
+/* | and its documentation for any purpose and without fee is hereby | */
+/* | granted, provided that the above copyright notice appear in all | */
+/* | copies and that both that copyright notice and this permission | */
+/* | notice appear in supporting documentation. This software is | */
+/* | provided "as is" without express or implied warranty. | */
+/* +-------------------------------------------------------------------+ */
+/* Adapted for use in SDL by Sam Lantinga -- 7/20/98 */
+/* Animated GIF support by Doug McFadyen -- 10/19/06 */
+
+#define MAXCOLORMAPSIZE 256
+
+#define TRUE 1
+#define FALSE 0
+
+#define CM_RED 0
+#define CM_GREEN 1
+#define CM_BLUE 2
+
+#define MAX_LWZ_BITS 12
+
+#define INTERLACE 0x40
+#define LOCALCOLORMAP 0x80
+#define BitSet(byte,bit) (((byte) & (bit)) == (bit))
+#define LM_to_uint(a,b) (((b)<<8)|(a))
+
+#define SDL_SetError(t) ((void)0) /* We're not SDL so ignore error reporting */
+
+
+typedef struct
+{
+ unsigned int Width;
+ unsigned int Height;
+ unsigned char ColorMap[3][MAXCOLORMAPSIZE];
+ unsigned int BitPixel;
+ unsigned int ColorResolution;
+ unsigned int Background;
+ unsigned int AspectRatio;
+} gifscreen;
+
+typedef struct
+{
+ int transparent;
+ int delayTime;
+ int inputFlag;
+ int disposal;
+} gif89;
+
+typedef struct
+{
+ /* global data */
+ SDL_RWops* src;
+ int loop;
+ gifscreen gs;
+ gif89 g89;
+ int zerodatablock;
+ /* AG_LoadGIF_RW data */
+ unsigned char localColorMap[3][MAXCOLORMAPSIZE];
+ /* GetCode data */
+ unsigned char buf[280];
+ int curbit, lastbit, done, lastbyte;
+ /* LWZReadByte data */
+ int fresh, code, incode;
+ int codesize, setcodesize;
+ int maxcode, maxcodesize;
+ int firstcode, oldcode;
+ int clearcode, endcode;
+ int table[2][(1 << MAX_LWZ_BITS)];
+ int stack[(1 << (MAX_LWZ_BITS))*2], *sp;
+} gifdata;
+
+
+
+static int ReadColorMap( gifdata* gd, int number, unsigned char buffer[3][MAXCOLORMAPSIZE] );
+static int DoExtension( gifdata* gd, int label );
+static int GetDataBlock( gifdata* gd, unsigned char* buf );
+static int GetCode( gifdata* gd, int code_size, int flag );
+static int LWZReadByte( gifdata* gd, int flag, int input_code_size );
+static SDL_Surface* ReadImage( gifdata* gd, int len, int height, int, unsigned char cmap[3][MAXCOLORMAPSIZE], int interlace, int ignore );
+
+
+
+int AG_isGIF( SDL_RWops* src )
+{
+ int isGIF = FALSE;
+
+ if ( src )
+ {
+ int start = SDL_RWtell( src );
+ char magic[6];
+
+ if ( SDL_RWread(src,magic,sizeof(magic),1) )
+ {
+ if ( (strncmp(magic,"GIF",3) == 0) && ((memcmp(magic+3,"87a",3) == 0) || (memcmp(magic+3,"89a",3) == 0)) )
+ {
+ isGIF = TRUE;
+ }
+ }
+
+ SDL_RWseek( src, start, SEEK_SET );
+ }
+
+ return isGIF;
+}
+
+int AG_LoadGIF( const char* file, AG_Frame* frames, int size, int *loop )
+{
+ int n = 0;
+
+ SDL_RWops* src = SDL_RWFromFile( file, "rb" );
+
+ if ( src )
+ {
+ n = AG_LoadGIF_RW( src, frames, size, loop );
+ SDL_RWclose( src );
+ }
+
+ return n;
+}
+
+
+
+void AG_FreeSurfaces( AG_Frame* frames, int nFrames )
+{
+ int i;
+
+ if ( frames )
+ {
+ for ( i = 0; i < nFrames; i++ )
+ {
+ if ( frames[i].surface )
+ {
+ SDL_FreeSurface( frames[i].surface );
+ frames[i].surface = NULL;
+ }
+ }
+ }
+}
+
+
+
+int AG_ConvertSurfacesToDisplayFormat( AG_Frame* frames, int nFrames )
+{
+ int i;
+ int n = 0;
+
+ if ( frames )
+ {
+ for ( i = 0; i < nFrames; i++ )
+ {
+ if ( frames[i].surface )
+ {
+ SDL_Surface* surface = (frames[i].surface->flags & SDL_SRCCOLORKEY) ? SDL_DisplayFormatAlpha(frames[i].surface) : SDL_DisplayFormat(frames[i].surface);
+
+ if ( surface )
+ {
+ SDL_FreeSurface( frames[i].surface );
+ frames[i].surface = surface;
+ n++;
+ }
+ }
+ }
+ }
+
+ return n;
+}
+
+
+
+int AG_NormalizeSurfacesToDisplayFormat( AG_Frame* frames, int nFrames )
+{
+ int n = 0;
+
+ if ( nFrames > 0 && frames && frames[0].surface )
+ {
+ SDL_Surface* mainSurface = (frames[0].surface->flags & SDL_SRCCOLORKEY) ? SDL_DisplayFormatAlpha(frames[0].surface) : SDL_DisplayFormat(frames[0].surface);
+ const int newDispose = (frames[0].surface->flags & SDL_SRCCOLORKEY) ? AG_DISPOSE_RESTORE_BACKGROUND : AG_DISPOSE_NONE;
+
+ if ( mainSurface )
+ {
+ int i;
+ int lastDispose = AG_DISPOSE_NA;
+ int iRestore = 0;
+ const Uint8 alpha = (frames[0].disposal == AG_DISPOSE_NONE) ? SDL_ALPHA_OPAQUE : SDL_ALPHA_TRANSPARENT;
+
+ SDL_FillRect( mainSurface, NULL, SDL_MapRGBA(mainSurface->format,0,0,0,alpha) );
+
+ for ( i = 0; i < nFrames; i++ )
+ {
+ if ( frames[i].surface )
+ {
+ SDL_Surface* surface = SDL_ConvertSurface( mainSurface, mainSurface->format, mainSurface->flags );
+
+ if ( surface )
+ {
+ SDL_Rect r;
+
+ if ( lastDispose == AG_DISPOSE_NONE )
+ SDL_BlitSurface( frames[i-1].surface, NULL, surface, NULL );
+
+ if ( lastDispose == AG_DISPOSE_RESTORE_PREVIOUS )
+ SDL_BlitSurface( frames[iRestore].surface, NULL, surface, NULL );
+ if ( frames[i].disposal != AG_DISPOSE_RESTORE_PREVIOUS )
+ iRestore = i;
+
+ r.x = (Sint16)frames[i].x;
+ r.y = (Sint16)frames[i].y;
+ SDL_BlitSurface( frames[i].surface, NULL, surface, &r );
+
+ SDL_FreeSurface( frames[i].surface );
+ frames[i].surface = surface;
+ frames[i].x = frames[i].y = 0;
+ lastDispose = frames[i].disposal;
+ frames[i].disposal = newDispose;
+ n++;
+ }
+ }
+ }
+
+ SDL_FreeSurface( mainSurface );
+ }
+ }
+
+ return n;
+}
+
+
+
+int AG_LoadGIF_RW( SDL_RWops* src, AG_Frame* frames, int maxFrames, int *loop)
+{
+ int start;
+ unsigned char buf[16];
+ unsigned char c;
+ int useGlobalColormap;
+ int bitPixel;
+ int iFrame = 0;
+ char version[4];
+ SDL_Surface* image = NULL;
+ gifdata* gd;
+
+ if ( src == NULL )
+ return 0;
+
+ gd = malloc( sizeof(*gd) );
+ memset( gd, 0, sizeof(*gd) );
+ gd->src = src;
+
+ start = SDL_RWtell( src );
+
+ if ( !SDL_RWread(src,buf,6,1) )
+ {
+ SDL_SetError( "error reading magic number" );
+ goto done;
+ }
+
+ if ( strncmp((char*)buf,"GIF",3) != 0 )
+ {
+ SDL_SetError( "not a GIF file" );
+ goto done;
+ }
+
+ strncpy( version, (char*)buf+3, 3 );
+ version[3] = '\0';
+
+ if ( (strcmp(version,"87a") != 0) && (strcmp(version,"89a") != 0) )
+ {
+ SDL_SetError( "bad version number, not '87a' or '89a'" );
+ goto done;
+ }
+
+ gd->g89.transparent = -1;
+ gd->g89.delayTime = -1;
+ gd->g89.inputFlag = -1;
+ gd->g89.disposal = AG_DISPOSE_NA;
+
+ if ( !SDL_RWread(src,buf,7,1) )
+ {
+ SDL_SetError( "failed to read screen descriptor" );
+ goto done;
+ }
+
+ gd->gs.Width = LM_to_uint(buf[0],buf[1]);
+ gd->gs.Height = LM_to_uint(buf[2],buf[3]);
+ gd->gs.BitPixel = 2 << (buf[4] & 0x07);
+ gd->gs.ColorResolution = (((buf[4] & 0x70) >> 3) + 1);
+ gd->gs.Background = buf[5];
+ gd->gs.AspectRatio = buf[6];
+
+ if ( BitSet(buf[4],LOCALCOLORMAP) ) /* Global Colormap */
+ {
+ if ( ReadColorMap(gd,gd->gs.BitPixel,gd->gs.ColorMap) )
+ {
+ SDL_SetError( "error reading global colormap" );
+ goto done;
+ }
+ }
+
+ do
+ {
+ if ( !SDL_RWread(src,&c,1,1) )
+ {
+ SDL_SetError( "EOF / read error on image data" );
+ goto done;
+ }
+
+ if ( c == ';' ) /* GIF terminator */
+ goto done;
+
+ if ( c == '!' ) /* Extension */
+ {
+ if ( !SDL_RWread(src,&c,1,1) )
+ {
+ SDL_SetError( "EOF / read error on extention function code" );
+ goto done;
+ }
+ DoExtension( gd, c );
+ continue;
+ }
+
+ if ( c != ',' ) /* Not a valid start character */
+ continue;
+
+ if ( !SDL_RWread(src,buf,9,1) )
+ {
+ SDL_SetError( "couldn't read left/top/width/height" );
+ goto done;
+ }
+
+ useGlobalColormap = !BitSet(buf[8],LOCALCOLORMAP);
+ bitPixel = 1 << ((buf[8] & 0x07) + 1);
+
+ if ( !useGlobalColormap )
+ {
+ if ( ReadColorMap(gd,bitPixel,gd->localColorMap) )
+ {
+ SDL_SetError( "error reading local colormap" );
+ goto done;
+ }
+ image = ReadImage( gd, LM_to_uint(buf[4],buf[5]), LM_to_uint(buf[6],buf[7]), bitPixel, gd->localColorMap, BitSet(buf[8],INTERLACE), (frames==NULL) );
+ }
+ else
+ {
+ image = ReadImage( gd, LM_to_uint(buf[4],buf[5]), LM_to_uint(buf[6],buf[7]), gd->gs.BitPixel, gd->gs.ColorMap, BitSet(buf[8],INTERLACE), (frames==NULL) );
+ }
+
+ if ( frames )
+ {
+ if ( image == NULL )
+ goto done;
+
+ if ( gd->g89.transparent >= 0 )
+ SDL_SetColorKey( image, SDL_SRCCOLORKEY, gd->g89.transparent );
+
+ frames[iFrame].surface = image;
+ frames[iFrame].x = LM_to_uint(buf[0], buf[1]);
+ frames[iFrame].y = LM_to_uint(buf[2], buf[3]);
+ frames[iFrame].disposal = gd->g89.disposal;
+ frames[iFrame].delay = gd->g89.delayTime*10;
+/* gd->g89.transparent = -1; ** Hmmm, not sure if this should be reset for each frame? */
+ }
+
+ iFrame++;
+ } while ( iFrame < maxFrames || frames == NULL );
+
+done:
+ if ( image == NULL )
+ SDL_RWseek( src, start, SEEK_SET );
+ if (loop)
+ *loop = gd->loop;
+ free( gd );
+
+ return iFrame;
+}
+
+
+
+static int ReadColorMap( gifdata* gd, int number, unsigned char buffer[3][MAXCOLORMAPSIZE] )
+{
+ int i;
+ unsigned char rgb[3];
+ int flag;
+
+ flag = TRUE;
+
+ for ( i = 0; i < number; ++i )
+ {
+ if ( !SDL_RWread(gd->src,rgb,sizeof(rgb),1) )
+ {
+ SDL_SetError( "bad colormap" );
+ return 1;
+ }
+
+ buffer[CM_RED][i] = rgb[0];
+ buffer[CM_GREEN][i] = rgb[1];
+ buffer[CM_BLUE][i] = rgb[2];
+ flag &= (rgb[0] == rgb[1] && rgb[1] == rgb[2]);
+ }
+
+ return FALSE;
+}
+
+
+
+static int DoExtension( gifdata* gd, int label )
+{
+ unsigned char buf[256];
+ switch ( label )
+ {
+ case 0x01: /* Plain Text Extension */
+ break;
+ case 0xff: /* Application Extension */
+ if (GetDataBlock( gd, buf ) != 11)
+ break;
+ if (strncmp((char*)buf, "NETSCAPE2.0", 11))
+ break;
+ if (GetDataBlock( gd, buf ) != 3)
+ break;
+ if (buf[0] != 1)
+ break;
+ gd->loop = buf[1] | (buf[2] << 8);
+ break;
+
+ case 0xfe: /* Comment Extension */
+ while ( GetDataBlock(gd,buf) != 0 )
+ ;
+ return FALSE;
+
+ case 0xf9: /* Graphic Control Extension */
+ (void)GetDataBlock( gd, buf );
+ gd->g89.disposal = (buf[0] >> 2) & 0x7;
+ gd->g89.inputFlag = (buf[0] >> 1) & 0x1;
+ gd->g89.delayTime = LM_to_uint(buf[1],buf[2]);
+ if ( (buf[0] & 0x1) != 0 )
+ gd->g89.transparent = buf[3];
+
+ while ( GetDataBlock(gd,buf) != 0 )
+ ;
+ return FALSE;
+ }
+
+ while ( GetDataBlock(gd,buf) != 0 )
+ ;
+
+ return FALSE;
+}
+
+
+
+static int GetDataBlock( gifdata* gd, unsigned char* buf )
+{
+ unsigned char count;
+
+ if ( !SDL_RWread(gd->src,&count,1,1) )
+ {
+ /* pm_message("error in getting DataBlock size" ); */
+ return -1;
+ }
+
+ gd->zerodatablock = count == 0;
+
+ if ( (count != 0) && !SDL_RWread(gd->src,buf,count,1) )
+ {
+ /* pm_message("error in reading DataBlock" ); */
+ return -1;
+ }
+
+ return count;
+}
+
+
+
+static int GetCode( gifdata* gd, int code_size, int flag )
+{
+ int i, j, ret;
+ int count;
+
+ if ( flag )
+ {
+ gd->curbit = 0;
+ gd->lastbit = 0;
+ gd->done = FALSE;
+ return 0;
+ }
+
+ if ( (gd->curbit + code_size) >= gd->lastbit )
+ {
+ if ( gd->done )
+ {
+ if ( gd->curbit >= gd->lastbit )
+ SDL_SetError( "ran off the end of my bits" );
+ return -1;
+ }
+
+ gd->buf[0] = gd->buf[gd->lastbyte - 2];
+ gd->buf[1] = gd->buf[gd->lastbyte - 1];
+
+ if ( (count = GetDataBlock(gd, &gd->buf[2])) == 0 )
+ gd->done = TRUE;
+
+ gd->lastbyte = 2 + count;
+ gd->curbit = (gd->curbit - gd->lastbit) + 16;
+ gd->lastbit = (2 + count)*8;
+ }
+
+ ret = 0;
+ for ( i = gd->curbit, j = 0; j < code_size; ++i, ++j )
+ ret |= ((gd->buf[i / 8] & (1 << (i % 8))) != 0) << j;
+
+ gd->curbit += code_size;
+
+ return ret;
+}
+
+
+
+static int LWZReadByte( gifdata* gd, int flag, int input_code_size )
+{
+ int i, code, incode;
+
+ if ( flag )
+ {
+ gd->setcodesize = input_code_size;
+ gd->codesize = gd->setcodesize + 1;
+ gd->clearcode = 1 << gd->setcodesize;
+ gd->endcode = gd->clearcode + 1;
+ gd->maxcodesize = gd->clearcode*2;
+ gd->maxcode = gd->clearcode + 2;
+
+ GetCode( gd, 0, TRUE );
+
+ gd->fresh = TRUE;
+
+ for ( i = 0; i < gd->clearcode; ++i )
+ {
+ gd->table[0][i] = 0;
+ gd->table[1][i] = i;
+ }
+
+ for ( ; i < (1 << MAX_LWZ_BITS); ++i )
+ gd->table[0][i] = gd->table[1][0] = 0;
+
+ gd->sp = gd->stack;
+ return 0;
+ }
+ else if ( gd->fresh )
+ {
+ gd->fresh = FALSE;
+ do
+ {
+ gd->firstcode = gd->oldcode = GetCode( gd, gd->codesize, FALSE );
+ } while ( gd->firstcode == gd->clearcode );
+ return gd->firstcode;
+ }
+
+ if ( gd->sp > gd->stack )
+ return *--gd->sp;
+
+ while ( (code = GetCode(gd,gd->codesize,FALSE)) >= 0 )
+ {
+ if ( code == gd->clearcode )
+ {
+ for ( i = 0; i < gd->clearcode; ++i )
+ {
+ gd->table[0][i] = 0;
+ gd->table[1][i] = i;
+ }
+
+ for ( ; i < (1 << MAX_LWZ_BITS); ++i )
+ gd->table[0][i] = gd->table[1][i] = 0;
+
+ gd->codesize = gd->setcodesize + 1;
+ gd->maxcodesize = gd->clearcode*2;
+ gd->maxcode = gd->clearcode + 2;
+ gd->sp = gd->stack;
+ gd->firstcode = gd->oldcode = GetCode( gd, gd->codesize, FALSE );
+ return gd->firstcode;
+ }
+ else if ( code == gd->endcode )
+ {
+ int count;
+ unsigned char buf[260];
+
+ if ( gd->zerodatablock )
+ return -2;
+
+ while ( (count = GetDataBlock(gd,buf)) > 0 )
+ ;
+
+ if ( count != 0 )
+ {
+ /* pm_message("missing EOD in data stream (common occurence)"); */
+ }
+ return -2;
+ }
+
+ incode = code;
+
+ if ( code >= gd->maxcode )
+ {
+ *gd->sp++ = gd->firstcode;
+ code = gd->oldcode;
+ }
+
+ while ( code >= gd->clearcode )
+ {
+ *gd->sp++ = gd->table[1][code];
+ if ( code == gd->table[0][code] )
+ SDL_SetError( "circular table entry BIG ERROR" );
+ code = gd->table[0][code];
+ }
+
+ *gd->sp++ = gd->firstcode = gd->table[1][code];
+
+ if ( (code = gd->maxcode) < (1 << MAX_LWZ_BITS) )
+ {
+ gd->table[0][code] = gd->oldcode;
+ gd->table[1][code] = gd->firstcode;
+ ++gd->maxcode;
+ if ( (gd->maxcode >= gd->maxcodesize) && (gd->maxcodesize < (1 << MAX_LWZ_BITS)) )
+ {
+ gd->maxcodesize *= 2;
+ ++gd->codesize;
+ }
+ }
+
+ gd->oldcode = incode;
+
+ if ( gd->sp > gd->stack )
+ return *--gd->sp;
+ }
+
+ return code;
+}
+
+
+
+static SDL_Surface* ReadImage( gifdata* gd, int len, int height, int cmapSize, unsigned char cmap[3][MAXCOLORMAPSIZE], int interlace, int ignore )
+{
+ SDL_Surface* image;
+ unsigned char c;
+ int i, v;
+ int xpos = 0, ypos = 0, pass = 0;
+
+ /* Initialize the compression routines */
+ if ( !SDL_RWread(gd->src,&c,1,1) )
+ {
+ SDL_SetError( "EOF / read error on image data" );
+ return NULL;
+ }
+
+ if ( LWZReadByte(gd,TRUE,c) < 0 )
+ {
+ SDL_SetError( "error reading image" );
+ return NULL;
+ }
+
+ /* If this is an "uninteresting picture" ignore it. */
+ if ( ignore )
+ {
+ while ( LWZReadByte(gd,FALSE,c) >= 0 )
+ ;
+ return NULL;
+ }
+
+ image = SDL_AllocSurface( SDL_SWSURFACE, len, height, 8, 0, 0, 0, 0 );
+
+ for ( i = 0; i < cmapSize; i++ )
+ {
+ image->format->palette->colors[i].r = cmap[CM_RED][i];
+ image->format->palette->colors[i].g = cmap[CM_GREEN][i];
+ image->format->palette->colors[i].b = cmap[CM_BLUE][i];
+ }
+
+ while ( (v = LWZReadByte(gd,FALSE,c)) >= 0 )
+ {
+ ((Uint8*)image->pixels)[xpos + ypos*image->pitch] = (Uint8)v;
+ ++xpos;
+
+ if ( xpos == len )
+ {
+ xpos = 0;
+ if ( interlace )
+ {
+ switch ( pass )
+ {
+ case 0:
+ case 1: ypos += 8; break;
+ case 2: ypos += 4; break;
+ case 3: ypos += 2; break;
+ }
+
+ if ( ypos >= height )
+ {
+ ++pass;
+ switch ( pass )
+ {
+ case 1: ypos = 4; break;
+ case 2: ypos = 2; break;
+ case 3: ypos = 1; break;
+ default: goto fini;
+ }
+ }
+ }
+ else
+ {
+ ++ypos;
+ }
+ }
+
+ if ( ypos >= height )
+ break;
+ }
+
+fini:
+ return image;
+}
+
diff --git a/src/sdl-instead/SDL_anigif.h b/src/sdl-instead/SDL_anigif.h
index b7f41e2..1fe8c67 100644
--- a/src/sdl-instead/SDL_anigif.h
+++ b/src/sdl-instead/SDL_anigif.h
@@ -1,61 +1,61 @@
-/*
- SDL_anigif: An example animated GIF image loading library for use with SDL
- SDL_image Copyright (C) 1997-2006 Sam Lantinga
- Animated GIF "derived work" Copyright (C) 2006 Doug McFadyen
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifndef _SDL_ANIGIF_H
-#define _SDL_ANIGIF_H
-
-#include
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-
-
-typedef struct
-{
- SDL_Surface* surface; /* SDL surface for this frame */
- int x, y; /* Frame offset position */
- int disposal; /* Disposal code */
- int delay; /* Frame delay in ms */
- int user; /* User data (not used by aniGIF) */
-} AG_Frame;
-
-#define AG_DISPOSE_NA 0 /* No disposal specified */
-#define AG_DISPOSE_NONE 1 /* Do not dispose */
-#define AG_DISPOSE_RESTORE_BACKGROUND 2 /* Restore to background */
-#define AG_DISPOSE_RESTORE_PREVIOUS 3 /* Restore to previous */
-
-
-
-extern DECLSPEC int AG_isGIF( SDL_RWops* src );
-extern DECLSPEC int AG_LoadGIF( const char* file, AG_Frame* frames, int maxFrames );
-extern DECLSPEC void AG_FreeSurfaces( AG_Frame* frames, int nFrames );
-extern DECLSPEC int AG_ConvertSurfacesToDisplayFormat( AG_Frame* frames, int nFrames );
-extern DECLSPEC int AG_NormalizeSurfacesToDisplayFormat( AG_Frame* frames, int nFrames );
-extern DECLSPEC int AG_LoadGIF_RW( SDL_RWops* src, AG_Frame* frames, int size );
-
-
-
-#ifdef __cplusplus
- }
-#endif
-#include "close_code.h"
-
-#endif /* _SDL_ANIGIF_H */
+/*
+ SDL_anigif: An example animated GIF image loading library for use with SDL
+ SDL_image Copyright (C) 1997-2006 Sam Lantinga
+ Animated GIF "derived work" Copyright (C) 2006 Doug McFadyen
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef _SDL_ANIGIF_H
+#define _SDL_ANIGIF_H
+
+#include
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+
+typedef struct
+{
+ SDL_Surface* surface; /* SDL surface for this frame */
+ int x, y; /* Frame offset position */
+ int disposal; /* Disposal code */
+ int delay; /* Frame delay in ms */
+ int user; /* User data (not used by aniGIF) */
+} AG_Frame;
+
+#define AG_DISPOSE_NA 0 /* No disposal specified */
+#define AG_DISPOSE_NONE 1 /* Do not dispose */
+#define AG_DISPOSE_RESTORE_BACKGROUND 2 /* Restore to background */
+#define AG_DISPOSE_RESTORE_PREVIOUS 3 /* Restore to previous */
+
+
+
+extern DECLSPEC int AG_isGIF( SDL_RWops* src );
+extern DECLSPEC int AG_LoadGIF( const char* file, AG_Frame* frames, int maxFrames, int *loop );
+extern DECLSPEC void AG_FreeSurfaces( AG_Frame* frames, int nFrames );
+extern DECLSPEC int AG_ConvertSurfacesToDisplayFormat( AG_Frame* frames, int nFrames );
+extern DECLSPEC int AG_NormalizeSurfacesToDisplayFormat( AG_Frame* frames, int nFrames );
+extern DECLSPEC int AG_LoadGIF_RW( SDL_RWops* src, AG_Frame* frames, int size, int *loop );
+
+
+
+#ifdef __cplusplus
+ }
+#endif
+#include "close_code.h"
+
+#endif /* _SDL_ANIGIF_H */
diff --git a/src/sdl-instead/game.c b/src/sdl-instead/game.c
index b45070f..75068bc 100644
--- a/src/sdl-instead/game.c
+++ b/src/sdl-instead/game.c
@@ -1182,8 +1182,10 @@ inv:
if (new_pict || new_place) {
img_t offscreen;
game_cursor(CURSOR_CLEAR);
+ gfx_stop_gif(el_img(el_spic));
offscreen = gfx_screen(oldscreen);
gfx_change_screen(offscreen);
+ gfx_start_gif(el_img(el_spic));
gfx_free_image(offscreen);
// input_clear();
goto err;
diff --git a/src/sdl-instead/graphics.c b/src/sdl-instead/graphics.c
index 9610588..81edf3e 100644
--- a/src/sdl-instead/graphics.c
+++ b/src/sdl-instead/graphics.c
@@ -231,6 +231,7 @@ struct _anigif_t {
struct _anigif_t *prev;
int cur_frame;
int nr_frames;
+ int loop;
int x;
int y;
int drawn;
@@ -254,7 +255,8 @@ static anigif_t anigif_find(anigif_t g)
return NULL;
}
extern int timer_counter;
-static void anigif_frame(anigif_t g)
+
+static void anigif_disposal(anigif_t g)
{
SDL_Rect dest;
SDL_Rect clip;
@@ -290,12 +292,24 @@ static void anigif_frame(anigif_t g)
if (img) { /* draw bg */
SDL_BlitSurface(Surf(img), NULL, screen, &dest);
}
- dest.x = g->x;
- dest.y = g->y;
+ SDL_SetClipRect(screen, &clip);
+}
+
+static void anigif_frame(anigif_t g)
+{
+ SDL_Rect dest;
+ SDL_Rect clip;
+
+ AG_Frame *frame;
+ frame = &g->frames[g->cur_frame];
+ SDL_GetClipRect(screen, &clip);
+
+ dest.x = g->x + frame->x;
+ dest.y = g->y + frame->y;
dest.w = frame->surface->w;
dest.h = frame->surface->h;
- dest.x += frame->x;
- dest.y += frame->y;
+
+ SDL_SetClipRect(screen, &g->clip);
SDL_BlitSurface(frame->surface, NULL, screen, &dest);
g->delay = timer_counter;
SDL_SetClipRect(screen, &clip);
@@ -516,10 +530,12 @@ img_t gfx_load_image(char *filename)
SDL_Surface *img;
int nr;
- nr = AG_LoadGIF(filename, NULL, 0);
+ nr = AG_LoadGIF(filename, NULL, 0, NULL);
if (nr > 0) { /* anigif logic */
+ int loop = 0;
anigif_t agif = malloc(sizeof(struct _anigif_t) + nr * sizeof(AG_Frame));
- AG_LoadGIF(filename, agif->frames, nr);
+ AG_LoadGIF(filename, agif->frames, nr, &loop);
+ agif->loop = loop;
agif->nr_frames = nr;
agif->cur_frame = 0;
agif->drawn = 0;
@@ -608,17 +624,36 @@ int gfx_frame_gif(img_t img)
{
anigif_t ag;
ag = is_anigif(img);
+
if (!ag)
return 0;
+
if (!ag->drawn)
return 0;
+
+ if (ag->loop == -1)
+ return 0;
+
if ((timer_counter - ag->delay) < (ag->frames[ag->cur_frame].delay / HZ))
return 0;
+
+ anigif_disposal(ag);
ag->cur_frame ++;
+
if (ag->cur_frame >= ag->nr_frames) {
- ag->cur_frame = 0;
+ if (!ag->loop || ag->loop > 1)
+ ag->cur_frame = 0;
+ else
+ ag->cur_frame --; /* last one */
+ if (ag->loop) {
+ ag->loop --;
+ if (!ag->loop)
+ ag->loop = -1; /* disabled */
+ }
+
}
- anigif_frame(ag);
+ if (ag->loop != -1)
+ anigif_frame(ag);
return 1;
}