summaryrefslogtreecommitdiff
path: root/Examples/AnimExample.c
blob: 28d5357540770c936393bed73c758b08f6e4dfe7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
	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.
*/

#include <exec/types.h>
#include <graphics/gfxbase.h>
#include <intuition/intuition.h>
#include <libraries/iff.h>			/* Our iff header file */

struct Library *IntuitionBase,*IFFBase, *OpenLibrary();
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
};

struct Screen *screen1,*screen2, *OpenScreen();
ULONG *ifffile;

void SetOverscan(screen)		/* Adjust the screen position for overscan */
register struct Screen *screen;
{
	register WORD cols,rows,x=screen->Width,y=screen->Height;
	register struct ViewPort *vp=&(screen->ViewPort);

	cols = GfxBase->NormalDisplayColumns>>1;
	rows = GfxBase->NormalDisplayRows; if(rows>300) rows>>=1;
	x -= cols; if(vp->Modes & HIRES) x -= cols;
	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 */
	{
		if(GfxBase->ActiView->DxOffset-x < 96)
			x=GfxBase->ActiView->DxOffset-96;
	}
	vp->DxOffset = -x; vp->DyOffset = -y;
	MakeScreen(screen); RethinkDisplay();
}

void Fail(text)			/* Print error message, free resources and exit */
char *text;
{
	printf("%s, IFFError = %ld\n",text,IFFError());

	if(ifffile) CloseIFF(ifffile);
	if(screen1) CloseScreen(screen1);
	if(screen2) CloseScreen(screen2);

	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);
	}

	GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L);
	IntuitionBase = OpenLibrary("intuition.library",0L);

	if(!(IFFBase = OpenLibrary(IFFNAME,IFFVERSION))) {
		printf("Copy the iff.library to your LIBS: directory!\n");
		exit(10);
	}

	if(!(ifffile=OpenIFF(argv[1]))) Fail("Error opening file");
	form=ifffile+3; /* Skip FORM....ANIM */

	if(ifffile[2] != ID_ANIM) Fail("Not an ANIM file");
	if(!(bmhd=GetBMHD(form))) Fail("BitMapHeader not found");

	ns.Width     = bmhd->w;
	ns.Height    = bmhd->h;
	ns.Depth     = bmhd->nPlanes;
	ns.ViewModes = GetViewModes(form);

	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(!DecodePic(form,&screen1->BitMap)) Fail("Can't decode picture");
	DecodePic(form,&screen2->BitMap);
	ScreenToFront(screen2);
	if((delay=atol(argv[2])) > 1) Delay(delay);

	/* 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);

	loopform=FindChunk(form,0L);		/* FORM to start loop at */
	for(i=0; i<atol(argv[3]); ++i)		/* Loop n times */
	{
		for(form=loopform; *form==ID_FORM; form=FindChunk(form,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);
		}
	}
	Fail("done"); 	/* Normal termination */
}