diff options
-rw-r--r-- | Examples/AnimExample.c | 309 |
1 files changed, 223 insertions, 86 deletions
diff --git a/Examples/AnimExample.c b/Examples/AnimExample.c index 28d5357..e45696d 100644 --- a/Examples/AnimExample.c +++ b/Examples/AnimExample.c @@ -1,32 +1,52 @@ /* - AnimExample.c - A simple DPaint animation player by Christian A. Weber. - This program is in the public domain, use and abuse at your own risk. - Requires the iff.library in the LIBS: dircetory. Compiles with - Lattice C V5.04 (LC -v -L AnimExample), should also work with Manx. +** +** $Id: AnimExample.c,v 21.1 92/05/28 17:09:27 chris Exp $ +** $Revision: 21.1 $ +** +** $Filename: Examples/AnimExample.c $ +** $Author: Christian A. Weber $ +** $Release: 21.1 $ +** $Date: 92/05/28 17:09:27 $ +** +** A simple DPaint ANIM player. To compile with Lattice C 5.x, just +** type 'lmk'. For other compilers you may have to do minor changes. +** +** THIS IS PD. NO WARRANTY. USE AT YOUR OWN RISK. +** */ -#include <exec/types.h> +#include <proto/exec.h> +#include <proto/graphics.h> #include <graphics/gfxbase.h> -#include <intuition/intuition.h> -#include <libraries/iff.h> /* Our iff header file */ +#include <proto/intuition.h> +#include <dos/dos.h> -struct Library *IntuitionBase,*IFFBase, *OpenLibrary(); +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +/* +** If you don't want to put non-Commodore files in the standard +** include directories, use the SASCOptions program to add the place +** where you store those non-standard files to your include path. +*/ +#include <libraries/iff.h> + +struct Library *IntuitionBase, *IFFBase; struct GfxBase *GfxBase; -struct NewScreen ns = -{ - 0,0,0,0,0,0,0, NULL, CUSTOMSCREEN|SCREENBEHIND|SCREENQUIET, NULL, - (STRPTR)"Anim Player Example by Christian A. Weber", NULL, NULL -}; +int delay; -struct Screen *screen1,*screen2, *OpenScreen(); -ULONG *ifffile; +/**************************************************************************** +** Adjust the screen position for overscan pictures in an OS 1.3 compatible +** way. There are more clever ways to do this under Kickstart 2.x, so you +** may want to modify this code. +*/ -void SetOverscan(screen) /* Adjust the screen position for overscan */ -register struct Screen *screen; +void SetOverscan(struct Screen *screen) { - register WORD cols,rows,x=screen->Width,y=screen->Height; - register struct ViewPort *vp=&(screen->ViewPort); + WORD cols, rows, x=screen->Width, y=screen->Height; + struct ViewPort *vp = &(screen->ViewPort); cols = GfxBase->NormalDisplayColumns>>1; rows = GfxBase->NormalDisplayRows; if(rows>300) rows>>=1; @@ -34,96 +54,213 @@ register struct Screen *screen; y -= rows; if(vp->Modes & LACE) y -= rows; x >>=1; if(x<0) x=0; y >>=1; if(y<0) y=0; if(y>32) y=32; - if(vp->Modes & HAM) /* Correct overscan HAM color distortions */ + /* + ** To avoid color distortions in HAM mode, we must limit the + ** left edge of the screen to the leftmost value the hardware + ** can display. + */ + if(vp->Modes & HAM) { if(GfxBase->ActiView->DxOffset-x < 96) - x=GfxBase->ActiView->DxOffset-96; + x = GfxBase->ActiView->DxOffset-96; } vp->DxOffset = -x; vp->DyOffset = -y; - MakeScreen(screen); RethinkDisplay(); + MakeScreen(screen); + RethinkDisplay(); } -void Fail(text) /* Print error message, free resources and exit */ -char *text; + +/**************************************************************************** +** Load an IFF file and if it's an ANIM, display the animation on a screen. +** To keep things simple, the double-buffering is done with ScreenToFront(). +** If you want speed, you should use a smarter way. +*/ + +void DisplayANIM(char *filename) { - printf("%s, IFFError = %ld\n",text,IFFError()); + IFFL_HANDLE iff; - if(ifffile) CloseIFF(ifffile); - if(screen1) CloseScreen(screen1); - if(screen2) CloseScreen(screen2); + if(iff = IFFL_OpenIFF(filename, IFFL_MODE_READ) ) + { + IFFL_HANDLE form, loopform; + struct IFFL_BMHD *bmhd; + struct Screen *screen1,*screen2; + struct NewScreen ns; - if(IFFBase) CloseLibrary(IFFBase); /* MUST ALWAYS BE CLOSED !! */ - CloseLibrary(IntuitionBase); - CloseLibrary(GfxBase); - exit(0); -} -void main(argc,argv) -int argc; -char **argv; -{ - register LONG count,i,delay; - register ULONG *form,*loopform; - struct BitMapHeader *bmhd; - UWORD colortable[128]; - - if((argc != 4) || !strcmp(argv[1],"?")) { - printf("Format: %s filename <delaytime> <# of loops>\n",argv[0]); - exit(20); - } + /* + ** First of all, check the file type, and exit if it's not ANIM. + */ + if( ((ULONG *)iff)[2] != ID_ANIM) + { + puts("Not an ANIM file."); + goto end; + } - GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L); - IntuitionBase = OpenLibrary("intuition.library",0L); + /* + ** In an ANIM file, each animation frame has its own FORM. + ** We set up a pointer to the first of these sub-FORMs to get + ** BMHD and the initial ILBM picture. + */ + form = (IFFL_HANDLE)((UBYTE *)iff + 12); - if(!(IFFBase = OpenLibrary(IFFNAME,IFFVERSION))) { - printf("Copy the iff.library to your LIBS: directory!\n"); - exit(10); - } + if( !(bmhd = IFFL_GetBMHD(form)) ) + { + puts("This file has no bitmap header."); + goto end; + } + + /* + ** Initialize the NewScreen structure, and open two screens. + */ + memset(&ns, 0, sizeof(ns) ); + + ns.Type = CUSTOMSCREEN | SCREENQUIET | SCREENBEHIND; + ns.Width = bmhd->w; + ns.Height = bmhd->h; + ns.Depth = bmhd->nPlanes; + ns.ViewModes = IFFL_GetViewModes(form); + + if(screen1 = OpenScreen(&ns) ) + { + if(screen2 = OpenScreen(&ns) ) + { + LONG count, d; + UWORD colortable[256]; + + SetOverscan(screen1); + SetOverscan(screen2); - if(!(ifffile=OpenIFF(argv[1]))) Fail("Error opening file"); - form=ifffile+3; /* Skip FORM....ANIM */ + count = IFFL_GetColorTab(form, colortable); - if(ifffile[2] != ID_ANIM) Fail("Not an ANIM file"); - if(!(bmhd=GetBMHD(form))) Fail("BitMapHeader not found"); + /* Fix for old broken HAM pictures */ + if(count>32L) count = 32L; - ns.Width = bmhd->w; - ns.Height = bmhd->h; - ns.Depth = bmhd->nPlanes; - ns.ViewModes = GetViewModes(form); + LoadRGB4(&(screen1->ViewPort), colortable, count); + LoadRGB4(&(screen2->ViewPort), colortable, count); - if(!(screen1 = OpenScreen(&ns))) Fail("Can't open screen 1!"); - if(!(screen2 = OpenScreen(&ns))) Fail("Can't open screen 2!"); - SetOverscan(screen1); SetOverscan(screen2); - count = GetColorTab(form,colortable); - if(count>32L) count = 32L; /* Some HAM pictures have 64 colors ?! */ - LoadRGB4(&(screen1->ViewPort),colortable,count); - LoadRGB4(&(screen2->ViewPort),colortable,count); + /* + ** Decode and display the first frame + */ + if( !IFFL_DecodePic(form, &screen1->BitMap) ) + { + puts("Can't decode picture"); + goto error; + } - /* Decode and display the first frame: */ - if(!DecodePic(form,&screen1->BitMap)) Fail("Can't decode picture"); - DecodePic(form,&screen2->BitMap); - ScreenToFront(screen2); - if((delay=atol(argv[2])) > 1) Delay(delay); + IFFL_DecodePic(form, &screen2->BitMap); + ScreenToFront(screen2); + for(d=0; d < delay; ++d) WaitTOF(); - /* Decode and display the second frame: copy and modify the first one */ - form=FindChunk(ifffile+3,0L); /* First FORM containing a DLTA */ - if(!ModifyFrame(form,&screen1->BitMap)) Fail("Can't decode frame"); - ScreenToFront(screen1); - if(delay>1) Delay(delay); + /* + ** Decode and display the second frame by + ** copying the first frame over and modifying it with + ** the first DLTA FORM. + */ + form = IFFL_FindChunk(form, 0L); + if( !IFFL_ModifyFrame(form, &screen1->BitMap) ) + { + puts("Can't decode frame 1"); + goto error; + } + ScreenToFront(screen1); + for(d=0; d < delay; ++d) WaitTOF(); - loopform=FindChunk(form,0L); /* FORM to start loop at */ - for(i=0; i<atol(argv[3]); ++i) /* Loop n times */ + loopform = IFFL_FindChunk(form, 0L); + + /* + ** Main loop + */ + for(;;) + { + for(form = loopform; *(ULONG *)form == ID_FORM; ) + { + /* + ** Wait for the left mouse button. Yeah I know + ** it's dirty, so don't use it in real apps :) + */ + if(!(*(UBYTE *)0xbfe001 & 0x40)) + goto error; + + /* + ** Prepare the next frame and flip screens + */ + if(IFFL_ModifyFrame(form, &screen2->BitMap) ) + { + struct Screen *dummy; + + dummy=screen1; screen1=screen2; screen2=dummy; + ScreenToFront(screen1); + for(d=0; d < delay; ++d) WaitTOF(); + } + else + { + puts("Can't decode frame."); + goto error; + } + + form = IFFL_FindChunk(form, 0L); + } + } +error: + CloseScreen(screen2); + } + else puts("Can't open 2nd screen."); + + CloseScreen(screen1); + } + else puts("Can't open 1st screen."); +end: + IFFL_CloseIFF(iff); + } + else printf("Can't open file '%s'\n",filename); +} + + +/**************************************************************************** +** Main program +*/ + +LONG main( int argc, char **argv ) +{ + /* + ** Check command line args + */ + if( (argc != 3) || !strcmp(argv[1], "?") ) + { + printf("Usage: %s filename <delaytime>\n", argv[0]); + return RETURN_FAIL; + } + + delay = atoi(argv[2]); + + /* + ** Open the libraries we need + */ + if(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L) ) { - for(form=loopform; *form==ID_FORM; form=FindChunk(form,0L)) + if(IntuitionBase = OpenLibrary("intuition.library", 0L) ) { - register struct Screen *dummy; - if(!ModifyFrame(form,&screen2->BitMap)) Fail("Can't decode frame"); - dummy=screen1; screen1=screen2; screen2=dummy; /* Flip screens */ - ScreenToFront(screen1); - if(delay>1) Delay(delay); + if(IFFBase = OpenLibrary(IFFNAME, IFFVERSION) ) + { + /* + ** Now show the animation ... + */ + DisplayANIM(argv[1]); + + printf("IFFL_IFFError value is %ld\n", IFFL_IFFError() ); + + CloseLibrary(IFFBase); /* THIS IS VERY IMPORTANT! */ + } + else printf("Can't open iff.library V%ld+\n", IFFVERSION); + + CloseLibrary(IntuitionBase); } + + CloseLibrary((struct Library *)GfxBase); } - Fail("done"); /* Normal termination */ + + return RETURN_OK; } |