<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.hard-light.org/index.php?action=history&amp;feed=atom&amp;title=ANI_formal_definition</id>
	<title>ANI formal definition - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.hard-light.org/index.php?action=history&amp;feed=atom&amp;title=ANI_formal_definition"/>
	<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=ANI_formal_definition&amp;action=history"/>
	<updated>2026-11-15T20:22:53Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=ANI_formal_definition&amp;diff=26403&amp;oldid=prev</id>
		<title>Goober5000: categorize</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=ANI_formal_definition&amp;diff=26403&amp;oldid=prev"/>
		<updated>2009-10-30T02:23:41Z</updated>

		<summary type="html">&lt;p&gt;categorize&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:23, 30 October 2009&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l143&quot;&gt;Line 143:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 143:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Note to this source: the header must be loaded into the structure anifile.header. The image data must then be loaded into memory and available at pointer char *cf. The bitmap data is then loaded into anifile.frames[i].buffer.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Note to this source: the header must be loaded into the structure anifile.header. The image data must then be loaded into memory and available at pointer char *cf. The bitmap data is then loaded into anifile.frames[i].buffer.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[Category:File Types]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Goober5000</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=ANI_formal_definition&amp;diff=26400&amp;oldid=prev</id>
		<title>Goober5000: moved ANI Formal Definition to ANI formal definition:&amp;#32;wiki format for titles</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=ANI_formal_definition&amp;diff=26400&amp;oldid=prev"/>
		<updated>2009-10-30T02:22:42Z</updated>

		<summary type="html">&lt;p&gt;moved &lt;a href=&quot;/index.php/ANI_Formal_Definition&quot; class=&quot;mw-redirect&quot; title=&quot;ANI Formal Definition&quot;&gt;ANI Formal Definition&lt;/a&gt; to &lt;a href=&quot;/index.php/ANI_formal_definition&quot; title=&quot;ANI formal definition&quot;&gt;ANI formal definition&lt;/a&gt;: wiki format for titles&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:22, 30 October 2009&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Goober5000</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=ANI_formal_definition&amp;diff=26399&amp;oldid=prev</id>
		<title>Goober5000: capitalization</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=ANI_formal_definition&amp;diff=26399&amp;oldid=prev"/>
		<updated>2009-10-30T02:22:28Z</updated>

		<summary type="html">&lt;p&gt;capitalization&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 02:22, 30 October 2009&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;This information is copied from the &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;DEscent &lt;/del&gt;Developer&#039;s Network [http://web.archive.org/web/20010619181602/descent-freespace.com/ddn/specs/ani/ Ani specs page]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;This information is copied from the &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Descent &lt;/ins&gt;Developer&#039;s Network [http://web.archive.org/web/20010619181602/descent-freespace.com/ddn/specs/ani/ Ani specs page]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Introduction==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Introduction==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Goober5000</name></author>
	</entry>
	<entry>
		<id>https://wiki.hard-light.org/index.php?title=ANI_formal_definition&amp;diff=26391&amp;oldid=prev</id>
		<title>The E: Even more info from the DDN</title>
		<link rel="alternate" type="text/html" href="https://wiki.hard-light.org/index.php?title=ANI_formal_definition&amp;diff=26391&amp;oldid=prev"/>
		<updated>2009-10-29T14:18:59Z</updated>

		<summary type="html">&lt;p&gt;Even more info from the DDN&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;This information is copied from the DEscent Developer&amp;#039;s Network [http://web.archive.org/web/20010619181602/descent-freespace.com/ddn/specs/ani/ Ani specs page]&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
The ANI file format is similar to the 256-color-PCX compression. It was however improved to provide transparent pixels as well as of course multiple images that make together the ANImation. All original ANI files are in FREESPACE.VP in Conflict, Descent: FreeSpace. In FreeSpace 2 they have been divided over several VP files.&lt;br /&gt;
&lt;br /&gt;
This document was written by Heiko Herrmann with help by John Slagel of Volition Inc. (header information) and Garry Knudson (image data).&lt;br /&gt;
&lt;br /&gt;
==File format==&lt;br /&gt;
The file begins with a fixed-size header and a variable number of keyframe definitions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;//Definitions&lt;br /&gt;
typedef struct ani_header&lt;br /&gt;
{&lt;br /&gt;
    short        should_be_zero;      // always 0&lt;br /&gt;
    short        version;             // &amp;gt;= 2&lt;br /&gt;
    short        fps;                 // played with &amp;lt;fps&amp;gt; frames per second&lt;br /&gt;
    pal          rgb;                 // ?&lt;br /&gt;
    short        w,h;                 // width, height&lt;br /&gt;
    short        nframes;             // number of frames&lt;br /&gt;
    char         packer_code;         // code used for compressed (repeated) bytes&lt;br /&gt;
    pal          palette[256];        // rgb-palette&lt;br /&gt;
    short        num_keys;            // ?&lt;br /&gt;
} ani_header;&lt;br /&gt;
&lt;br /&gt;
typedef struct ani_key&lt;br /&gt;
{&lt;br /&gt;
    short twobyte;&lt;br /&gt;
    short startcount;&lt;br /&gt;
} ani_key;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//File format&lt;br /&gt;
ani_header anifile.header;&lt;br /&gt;
for(i=0; i&amp;lt;anifile.header.num_keys; i++)&lt;br /&gt;
 ani_key anifile.key[i];&lt;br /&gt;
int anifile.endcount;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
A keyframe is a frame that is provided *as is*, that means with no transparent pixels. So drawing that frame is not dependant of having the data from the previous frame (which is needed for transparent pixels). Usually ANImations have only one keyframe (the initial image = frame no.1). Some have more This is used for the following purposes:&lt;br /&gt;
&lt;br /&gt;
The main hall ANImations have only key frames so that they can be played backwards (when moving the mouse away from a room in the main hall).&lt;br /&gt;
The weapon/ship ANImations have 2 (one additional) key frames: the second is the so-called &amp;quot;loop point&amp;quot;: everything before is the animation how the weapon/ship appears in the briefings screen, everything after is the part that loops endless - the rotation.&lt;br /&gt;
The header is followed by the actual image data, as discussed below.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
==Image data==&lt;br /&gt;
To understand the image data format, I chose to provide some code here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// ANI reader example code&lt;br /&gt;
// Taken from Descent Manager ANIVIEW32 - an adaption of a code part of FSView&lt;br /&gt;
// Written by Garry Knudson and Heiko Herrmann&lt;br /&gt;
// Copyright 1998-2000 by Descent Network Team&lt;br /&gt;
//&lt;br /&gt;
// Note: the header must be loaded into the structure anifile.header.&lt;br /&gt;
// The image data must then be loaded into memory and available at pointer char *cf.&lt;br /&gt;
// The bitmap data is then loaded into anifile.frames[i].buffer&lt;br /&gt;
&lt;br /&gt;
byte runvalue,runcount;&lt;br /&gt;
int cur,max;&lt;br /&gt;
byte *p,*p2;&lt;br /&gt;
byte flagbyte;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
max=anifile.header.w;&lt;br /&gt;
if(anifile.header.w % 4!=0) {   //Garry Knudson 9-23-99&lt;br /&gt;
 max += (4-(anifile.header.w%4));&lt;br /&gt;
}&lt;br /&gt;
max=max * anifile.header.h;&lt;br /&gt;
&lt;br /&gt;
byte *cur_frame=new byte[max];&lt;br /&gt;
byte *last_frame=new byte[max];&lt;br /&gt;
&lt;br /&gt;
memset(last_frame,anifile.header.rgb.r+256*anifile.header.rgb.g+65536*anifile.header.rgb.b,max);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Load frames &lt;br /&gt;
for (i=0;i&amp;lt;anifile.header.nframes;i++)&lt;br /&gt;
{&lt;br /&gt;
 cf=readfrombuffer(cf,&amp;amp;flagbyte,1);&lt;br /&gt;
 cur=0;&lt;br /&gt;
&lt;br /&gt;
 /*char x[256];&lt;br /&gt;
 sprintf(x,&amp;quot;Frame %i: %i\n&amp;quot;,i,anif-&amp;gt;GetPosition());&lt;br /&gt;
 OutputDebugString(x);*/&lt;br /&gt;
&lt;br /&gt;
 p=cur_frame;&lt;br /&gt;
 if(i&amp;gt;0)&lt;br /&gt;
  p2=last_frame; //for transparent pixels&lt;br /&gt;
 else&lt;br /&gt;
  p2=cur_frame;&lt;br /&gt;
&lt;br /&gt;
 int x0,y0;&lt;br /&gt;
 runcount=0;&lt;br /&gt;
 cur=0;&lt;br /&gt;
 for(y0=0;y0&amp;lt;anifile.header.h;y0++)&lt;br /&gt;
 {&lt;br /&gt;
  for(x0=0;x0&amp;lt;anifile.header.w;x0++)&lt;br /&gt;
  {&lt;br /&gt;
   if (runcount&amp;gt;0)&lt;br /&gt;
   {&lt;br /&gt;
    runcount--;&lt;br /&gt;
   }&lt;br /&gt;
   else&lt;br /&gt;
   {&lt;br /&gt;
    cf=readfrombuffer(cf,&amp;amp;runvalue,1);&lt;br /&gt;
    if(runvalue==anifile.header.packer_code)&lt;br /&gt;
    {&lt;br /&gt;
     cf=readfrombuffer(cf,&amp;amp;runcount,1);&lt;br /&gt;
     if(runcount&amp;lt;2)&lt;br /&gt;
      runvalue=anifile.header.packer_code;&lt;br /&gt;
     else&lt;br /&gt;
      cf=readfrombuffer(cf,&amp;amp;runvalue,1);&lt;br /&gt;
    }&lt;br /&gt;
   }&lt;br /&gt;
   *p=runvalue;&lt;br /&gt;
   if(runvalue==254) //if transparent pixel, then use the pixel from the last frame&lt;br /&gt;
    *p=*p2;&lt;br /&gt;
   p++; p2++; cur++;&lt;br /&gt;
  }&lt;br /&gt;
  if(anifile.header.w % 4!=0) {   //Garry Knudson 9-23-99&lt;br /&gt;
   p +=(4-(anifile.header.w%4));&lt;br /&gt;
   p2 +=(4-(anifile.header.w%4));&lt;br /&gt;
   cur +=(4-(anifile.header.w%4));&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 //Process frame&lt;br /&gt;
 anifile.frames[i].buffer=new byte[max];&lt;br /&gt;
 memcpy(last_frame,cur_frame,max);&lt;br /&gt;
 memcpy(anifile.frames[i].buffer,cur_frame,max);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---------------&lt;br /&gt;
&lt;br /&gt;
char *readfrombuffer(char *org,void *dest,int num)&lt;br /&gt;
{&lt;br /&gt;
 memcpy(dest,org,num);&lt;br /&gt;
 org+=num;&lt;br /&gt;
 return org;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note to this source: the header must be loaded into the structure anifile.header. The image data must then be loaded into memory and available at pointer char *cf. The bitmap data is then loaded into anifile.frames[i].buffer.&lt;/div&gt;</summary>
		<author><name>The E</name></author>
	</entry>
</feed>