/************************************************************************/
/*									*/
/* Create IFF-ILBM files for all the sprites				*/
/*									*/
/************************************************************************/

#include <proto/iffparse.h>

#define MYLIB_GRAPHICS
#include <MyLib.h>

/************************************************************************/

struct DosLibrary *DOSBase;
struct Library *UtilityBase;
struct GfxBase *GfxBase;
struct Library *IFFParseBase;

/************************************************************************/

#include "Colors.h"

#include "bitmaps/bitmaps/oblong.h"
#include "bitmaps/bitmaps/rect.h"
#include "bitmaps/bitmaps/edge.h"
#include "bitmaps/bitmaps/fill0.h"
#include "bitmaps/bitmaps/fill1.h"
#include "bitmaps/bitmaps/fill2.h"
#include "bitmaps/bitmaps/fill3.h"
#include "bitmaps/bitmaps/ghosting.h"

#include "bitmaps/icon/solidm.h"
#include "bitmaps/icon/solidr.h"
#include "bitmaps/icon/solidi.h"
#include "bitmaps/icon/solids.h"
#include "bitmaps/icon/solidt.h"
#include "bitmaps/icon/shellm.h"
#include "bitmaps/icon/shellr.h"
#include "bitmaps/icon/shelli.h"
#include "bitmaps/icon/shells.h"
#include "bitmaps/icon/shellt.h"

#include "bitmaps/board/cherry.h"
#include "bitmaps/board/ball.h"
#include "bitmaps/board/digits.h"
#include "bitmaps/board/seat.h"

#include "bitmaps/apple/aplnorm.h"
#include "bitmaps/apple/aplrock.h"
#include "bitmaps/apple/aplspl.h"
#include "bitmaps/apple/apldcy.h"
#include "bitmaps/apple/aplrot.h"
#include "bitmaps/apple/gstnorm.h"
#include "bitmaps/apple/gstrock.h"
#include "bitmaps/apple/aplsmall.h"

#include "bitmaps/player/hplyrw1.h"
#include "bitmaps/player/splyrw1.h"
#include "bitmaps/player/hplyrw2.h"
#include "bitmaps/player/hplyrs1.h"
#include "bitmaps/player/hplyrs2.h"
#include "bitmaps/player/hplyrf.h"
#include "bitmaps/player/hplyrp1.h"
#include "bitmaps/player/hplyrp2.h"
#include "bitmaps/player/hplyrh1.h"
#include "bitmaps/player/hplyrh2.h"
#include "bitmaps/player/splyrw2.h"
#include "bitmaps/player/splyrs1.h"
#include "bitmaps/player/splyrs2.h"
#include "bitmaps/player/splyrf.h"
#include "bitmaps/player/splyrp1.h"
#include "bitmaps/player/splyrp2.h"
#include "bitmaps/player/splyrd1.h"
#include "bitmaps/player/splyrd2.h"
#include "bitmaps/player/splyrh1.h"
#include "bitmaps/player/splyrh2.h"

#include "bitmaps/normal/hden.h"
#include "bitmaps/normal/sden.h"
#include "bitmaps/normal/hnormw1.h"
#include "bitmaps/normal/hnormw2.h"
#include "bitmaps/normal/hnormf.h"
#include "bitmaps/normal/snormw1.h"
#include "bitmaps/normal/snormw2.h"
#include "bitmaps/normal/snormf.h"

#include "bitmaps/munch/hmnchw1.h"
#include "bitmaps/munch/hmnchw2.h"
#include "bitmaps/munch/hmnchf.h"
#include "bitmaps/munch/smnchw1.h"
#include "bitmaps/munch/smnchw2.h"
#include "bitmaps/munch/smnchf.h"

#include "bitmaps/xtra/hxtraw1.h"
#include "bitmaps/xtra/hxtraw2.h"
#include "bitmaps/xtra/hxtraf.h"
#include "bitmaps/xtra/sxtraw1.h"
#include "bitmaps/xtra/sxtraw2.h"
#include "bitmaps/xtra/sxtraf.h"
#include "bitmaps/xtra/xtrfaint.h"
#include "bitmaps/xtra/xtrbold.h"

#include "bitmaps/drone/hdronw1.h"
#include "bitmaps/drone/hdronw2.h"
#include "bitmaps/drone/hdronf.h"
#include "bitmaps/drone/sdronw1.h"
#include "bitmaps/drone/sdronw2.h"
#include "bitmaps/drone/sdronf.h"

#include "bitmaps/chomp/hchmpo.h"
#include "bitmaps/chomp/hchmpc.h"
#include "bitmaps/chomp/schmpo.h"
#include "bitmaps/chomp/schmpc.h"

#include "bitmaps/prize/cake.h"
#include "bitmaps/prize/spanner.h"
#include "bitmaps/prize/brolly.h"
#include "bitmaps/prize/mushrm.h"
#include "bitmaps/prize/clock.h"
#include "bitmaps/prize/gem1.h"
#include "bitmaps/prize/gem2.h"
#include "bitmaps/prize/gem3.h"

#include "bitmaps/edit/path.h"
#include "bitmaps/edit/red.h"
#include "bitmaps/edit/green.h"
#include "bitmaps/edit/blue.h"

#if 0
#define aplnorm_bits	noapple_bits
#define aplnorm_noswap	noapple_noswap
#define aplnorm_swap	noapple_swap
#undef aplnorm_width
#undef aplnorm_height
#undef aplnorm_depth
#include "apple/aplnorm.h"
#undef aplnorm_swap
#undef aplnorm_noswap
#undef aplnorm_bits

#define noapple_width	aplnorm_width
#define noapple_height	aplnorm_height
#define noapple_depth	aplnorm_depth
#else
#define gstnorm_bits	noapple_bits
#define gstnorm_noswap	noapple_noswap
#define gstnorm_swap	noapple_swap
#undef gstnorm_width
#undef gstnorm_height
#undef gstnorm_depth
#include "bitmaps/apple/gstnorm.h"
#undef gstnorm_swap
#undef gstnorm_noswap
#undef gstnorm_bits

#define noapple_width	gstnorm_width
#define noapple_height	gstnorm_height
#define noapple_depth	gstnorm_depth
#endif

/************************************************************************/

#define special_width 11
#define special_height 4
#define special_depth 4

static const UBYTE special_bits[]=
{		/* 1234 5678 9AB- ---- */
#if 0
  0xAA,0xA0,	/* 1010 1010 1010 0000 */
  0x66,0x60,	/* 0110 0110 0110 0000 */
  0x1e,0x00,	/* 0001 1110 0000 0000 */
  0x01,0xe0	/* 0000 0001 1110 0000 */
#else
  0x55,0x05,	/* 0101 0101 0000 0101 */
  0x66,0x06,	/* 0110 0110 0000 0110 */
  0x78,0x00,	/* 0111 1000 0000 0000 */
  0x80,0x07	/* 1000 0000 0000 0111 */
#endif
};

static const ULONG special_noswap[]=
{
  0x0b54,		/* (mono) */
  COLOR_RED_BACK,	/* 1	(white) */
  COLOR_RED_FORE,	/* 2	(black) */
  COLOR_GREEN_BACK,	/* 3	(white) */

  COLOR_GREEN_FORE,	/* 4	(black) */
  COLOR_BLUE_BACK,	/* 5	(white) */
  COLOR_BLUE_FORE,	/* 6	(black) */
  COLOR_DRONE_BACK,	/* 7	(white) */

  COLOR_DRONE_FORE,	/* 8	(black) */
  COLOR_BLACK,		/* 9	(black) */
  COLOR_WHITE,		/* 10	(white) */
  COLOR_BORDER,		/* 11	(black) */

  ~0,			/* 12 */
  ~0,			/* 13 */
  ~0,			/* 14 */
  ~0			/* 15 */
};

/************************************************************************/

#define mredspecial_width 10
#define mredspecial_height 4
#define mredspecial_depth 4

static const UBYTE mredspecial_bits[]=
{		/* 8765 4321 ---- -BA9 */
  0x55,0x05,	/* 0101 0101 0000 0101 */
  0x66,0x06,	/* 0110 0110 0000 0110 */
  0x78,0x00,	/* 0111 1000 0000 0000 */
  0x80,0x07	/* 1000 0000 0000 0111 */
};

static const ULONG mredspecial_noswap[]=
{
  0x04d4,		/* (mono) */
  COLOR_RED_BACK,	/* 1	(white) */
  COLOR_RED_FORE,	/* 2	(black) */
  COLOR_GREEN_BACK,	/* 3	(white) */

  COLOR_GREEN_FORE,	/* 4	(black) */
  COLOR_BLUE_BACK,	/* 5	(white) */
  COLOR_BLUE_FORE,	/* 6	(black) */
  COLOR_BLACK,		/* 7	(black) */

  COLOR_WHITE,		/* 8	(white) */
  COLOR_RED,		/* 9	(white) */
  COLOR_BLACK,		/* 10	(black) */
  ~0,			/* 11 */

  ~0,			/* 12 */
  ~0,			/* 13 */
  ~0,			/* 14 */
  ~0			/* 15 */
};

/************************************************************************/
/*									*/
/* The colors to use for the sprites					*/
/* [0] -> mris								*/
/* [1] -> msit								*/
/*									*/
/************************************************************************/

static const ULONG Colors[COLORS][2] =
{
  {0xffffff,0xffffff},		/* White */
  {0x000000,0x000000},		/* Black */
  {0x77BB77,0x77BB77},		/* GreenBack */
  {0x007700,0x007700},		/* GreenFore */
  {0xBB7777,0xBB7777},		/* RedBack */
  {0x770000,0x770000},		/* RedFore */
  {0x7777BB,0x7777BB},		/* BlueBack */
  {0x000077,0x000077},		/* BlueFore */
  {0xFFFFFF,0xFFFFFF},		/* Background */
  {0x000000,0x000000},		/* Foreground */
  {0x000000,0x000000},		/* BorderColor */
  {0xEE0000,0xEE0000},		/* Cherry */
  {0xDD9955,0xDD9955},		/* CherryStalk */
  {0xEEDD00,0xEEDD00},		/* Apple1 */
  {0xDD3300,0xDD3300},		/* Apple2 */
  {0xBBBBBB,0xBBBBBB},		/* AppleFaint */
  {0x0000DD,0x6666FF},		/* Player */
  {0xFFFFFF,0xFFFFFF},		/* PlayerBobble */
  {0xFFCCCC,0xFFCCCC},		/* PlayerSkin */
  {0xDD9955,0x773322},		/* PlayerBoot */
  {0xEE0000,0xEE0000},		/* Normal */
  {0x000000,0x000000},		/* LetterGot */
  {0xBBBBBB,0xBBBBBB},		/* LetterNotGot */
  {0xFFFF77,0xFF00FF},		/* Ball */
  {0xAA3333,0xAA3333},		/* DroneBack */
  {0x992222,0x992222},		/* DroneFore */
  {0xDDDDDD,0xDDDDDD},		/* Gem1 */
  {0xBBBBBB,0xBBBBBB},		/* Gem2 */
  {0xFFFF00,0xFFFF00},		/* Munch1 */
  {0xCCCCCC,0xFFFF00},		/* Munch2 */
  {0x0000DD,0x00FF00},		/* Drone */
  {0xEE0000,0xEE0000},		/* DroneTongue */
  {0xEEFF00,0xEEFF00},		/* Extra */
  {0xFFFFFF,0xCCFF00},		/* Chomp */
  {0x77FFFF,0x77FFFF},		/* ChompLip */
  {0xEE0000,0xEE0000},		/* ChompTongue */
  {0xEE0000,0xEE0000},		/* Seat */
  {0xFFFF77,0xFFFF77},		/* Cake */
  {0xDD9955,0xDD9955},		/* CakeIcing */
  {0xEE0000,0xEE0000},		/* CakeJam */
  {0xAAAAAA,0xAAAAAA},		/* Spanner */
  {0x000000,0x000000},		/* SpannerShadow */
  {0xFFFFFF,0xFFFFFF},		/* Brolly1 */
  {0xEE0000,0xEE0000},		/* Brolly2 */
  {0xDD9955,0xDD9955},		/* BrollyHandle */
  {0xFFFFFF,0xFFFFFF},		/* MushroomStalk */
  {0xEE0000,0xEE0000},		/* MushroomCap */
  {0xFFFFFF,0xFFFFFF},		/* ClockFace */
  {0x00DD00,0x00DD00},		/* ClockBell */
  {0x0000DD,0x00DD00},		/* ClockRim */

  {0xFF0000,0xFF0000},		/* Red */
};

/************************************************************************/

struct Sprite
{
  const char *Path;
  const char *Name;
  const UBYTE *Bitmap;
  ULONG Depth;
  WORD Width, Height;
  ULONG *Colors;
};

struct MyBitmap
{
  struct BitMap Bitmap;
  ULONG ColorCount;
  ULONG ColorTable[1];
};

/************************************************************************/

static const ULONG bitmaps_noswap[]=
{
  0,
  COLOR_WHITE
};

#define oblong_noswap	bitmaps_noswap
#define rect_noswap	bitmaps_noswap
#define edge_noswap	bitmaps_noswap
#define fill0_noswap	NULL
#define fill1_noswap	NULL
#define fill2_noswap	NULL
#define fill3_noswap	NULL
#define ghosting_noswap	bitmaps_noswap

#define oblong_depth	1
#define rect_depth	1
#define edge_depth	1
#define fill0_depth	1
#define fill1_depth	1
#define fill2_depth	1
#define fill3_depth	1
#define ghosting_depth	1

/************************************************************************/

#define DEF_SPRITE(Path,Name) {#Path,#Name,Name##_bits,Name##_depth,Name##_width,Name##_height,Name##_noswap}

static const struct Sprite Sprites[]=
{
  DEF_SPRITE(bitmaps,oblong),
  DEF_SPRITE(bitmaps,rect),
  DEF_SPRITE(bitmaps,edge),
  DEF_SPRITE(bitmaps,fill0),
  DEF_SPRITE(bitmaps,fill1),
  DEF_SPRITE(bitmaps,fill2),
  DEF_SPRITE(bitmaps,fill3),
  DEF_SPRITE(bitmaps,ghosting),
  DEF_SPRITE(icon,solidm),
  DEF_SPRITE(icon,solidr),
  DEF_SPRITE(icon,solidi),
  DEF_SPRITE(icon,solids),
  DEF_SPRITE(icon,solidt),
  DEF_SPRITE(icon,shellm),
  DEF_SPRITE(icon,shellr),
  DEF_SPRITE(icon,shelli),
  DEF_SPRITE(icon,shells),
  DEF_SPRITE(icon,shellt),
  DEF_SPRITE(board,cherry),
  DEF_SPRITE(board,ball),
  DEF_SPRITE(board,digits),
  DEF_SPRITE(board,seat),
  DEF_SPRITE(apple,aplnorm),
  DEF_SPRITE(apple,aplrock),
  DEF_SPRITE(apple,aplspl),
  DEF_SPRITE(apple,apldcy),
  DEF_SPRITE(apple,aplrot),
  DEF_SPRITE(apple,gstnorm),
  DEF_SPRITE(apple,gstrock),
  DEF_SPRITE(apple,aplsmall),
  DEF_SPRITE(player,hplyrw1),
  DEF_SPRITE(player,splyrw1),
  DEF_SPRITE(player,hplyrw2),
  DEF_SPRITE(player,hplyrs1),
  DEF_SPRITE(player,hplyrs2),
  DEF_SPRITE(player,hplyrf),
  DEF_SPRITE(player,hplyrp1),
  DEF_SPRITE(player,hplyrp2),
  DEF_SPRITE(player,hplyrh1),
  DEF_SPRITE(player,hplyrh2),
  DEF_SPRITE(player,splyrw2),
  DEF_SPRITE(player,splyrs1),
  DEF_SPRITE(player,splyrs2),
  DEF_SPRITE(player,splyrf),
  DEF_SPRITE(player,splyrp1),
  DEF_SPRITE(player,splyrp2),
  DEF_SPRITE(player,splyrd1),
  DEF_SPRITE(player,splyrd2),
  DEF_SPRITE(player,splyrh1),
  DEF_SPRITE(player,splyrh2),
  DEF_SPRITE(normal,hden),
  DEF_SPRITE(normal,sden),
  DEF_SPRITE(normal,hnormw1),
  DEF_SPRITE(normal,hnormw2),
  DEF_SPRITE(normal,hnormf),
  DEF_SPRITE(normal,snormw1),
  DEF_SPRITE(normal,snormw2),
  DEF_SPRITE(normal,snormf),
  DEF_SPRITE(munch,hmnchw1),
  DEF_SPRITE(munch,hmnchw2),
  DEF_SPRITE(munch,hmnchf),
  DEF_SPRITE(munch,smnchw1),
  DEF_SPRITE(munch,smnchw2),
  DEF_SPRITE(munch,smnchf),
  DEF_SPRITE(xtra,hxtraw1),
  DEF_SPRITE(xtra,hxtraw2),
  DEF_SPRITE(xtra,hxtraf),
  DEF_SPRITE(xtra,sxtraw1),
  DEF_SPRITE(xtra,sxtraw2),
  DEF_SPRITE(xtra,sxtraf),
  DEF_SPRITE(xtra,xtrfaint),
  DEF_SPRITE(xtra,xtrbold),
  DEF_SPRITE(drone,hdronw1),
  DEF_SPRITE(drone,hdronw2),
  DEF_SPRITE(drone,hdronf),
  DEF_SPRITE(drone,sdronw1),
  DEF_SPRITE(drone,sdronw2),
  DEF_SPRITE(drone,sdronf),
  DEF_SPRITE(chomp,hchmpo),
  DEF_SPRITE(chomp,hchmpc),
  DEF_SPRITE(chomp,schmpo),
  DEF_SPRITE(chomp,schmpc),
  DEF_SPRITE(prize,cake),
  DEF_SPRITE(prize,spanner),
  DEF_SPRITE(prize,brolly),
  DEF_SPRITE(prize,mushrm),
  DEF_SPRITE(prize,clock),
  DEF_SPRITE(prize,gem1),
  DEF_SPRITE(prize,gem2),
  DEF_SPRITE(prize,gem3),
  DEF_SPRITE(edit,path),
  DEF_SPRITE(edit,red),
  DEF_SPRITE(edit,green),
  DEF_SPRITE(edit,blue),
  DEF_SPRITE(bitmaps,special),
  DEF_SPRITE(bitmaps,mredspecial),
  DEF_SPRITE(apple,noapple)
};

/************************************************************************/

struct SpriteTable
{
  const char *Name;
  ULONG BorderHalo;
};

#define MRIS_SPRITES 0
struct SpriteTable mris[]=
{
  {"oblong",FALSE},
  {"rect",FALSE},
  {"edge",FALSE},
  {"digits",FALSE},
  {"hden",TRUE},
  {"ball",FALSE},
  {"cherry",TRUE},
  {"aplnorm",FALSE},
  {"aplrock",FALSE},
  {"aplspl",FALSE},
  {"apldcy",FALSE},
  {"aplrot",FALSE},
  {"gstnorm",FALSE},
  {"gstrock",FALSE},
  {"gem1",TRUE},
  {"gem2",TRUE},
  {"gem3",TRUE},
  {"xtrbold",FALSE},
  {"xtrfaint",FALSE},
  {"hxtraw1",TRUE},
  {"hxtraw2",TRUE},
  {"hnormw1",TRUE},
  {"hnormw2",TRUE},
  {"hmnchw1",TRUE},
  {"hmnchw2",TRUE},
  {"hdronw1",TRUE},
  {"hdronw2",TRUE},
  {"hplyrw1",TRUE},
  {"hplyrw2",TRUE},
  {"hplyrs1",TRUE},
  {"hplyrs2",TRUE},
  {"hplyrp1",TRUE},
  {"hplyrp2",TRUE},
  {"hplyrh1",TRUE},
  {"hplyrh2",TRUE},
  {"hnormf",TRUE},
  {"hmnchf",TRUE},
  {"hxtraf",TRUE},
  {"hdronf",TRUE},
  {"hplyrf",TRUE},
  {"hchmpo",TRUE},
  {"hchmpc",TRUE},
  {"solidm",TRUE},
  {"solidr",TRUE},
  {"solidi",TRUE},
  {"solids",TRUE},
  {"shellm",TRUE},
  {"shellr",TRUE},
  {"shelli",TRUE},
  {"shells",TRUE},
  {"seat",TRUE},
  {"ghosting",FALSE},
  {"cake",TRUE},
  {"spanner",TRUE},
  {"brolly",TRUE},
  {"mushrm",TRUE},
  {"clock",TRUE},
  {"special",FALSE},
  {"fill0",FALSE},
  {"fill1",FALSE},
  {"fill2",FALSE},
  {"fill3",FALSE}
};

#define MSIT_SPRITES 1
struct SpriteTable msit[]=
{
  {"oblong",FALSE},
  {"rect",FALSE},
  {"edge",FALSE},
  {"digits",FALSE},
  {"sden",TRUE},
  {"ball",FALSE},
  {"cherry",TRUE},
  {"aplnorm",FALSE},
  {"aplrock",FALSE},
  {"aplspl",FALSE},
  {"apldcy",FALSE},
  {"aplrot",FALSE},
  {"gstnorm",FALSE},
  {"gstrock",FALSE},
  {"gem1",TRUE},
  {"gem2",TRUE},
  {"gem3",TRUE},
  {"xtrbold",FALSE},
  {"xtrfaint",FALSE},
  {"sxtraw1",TRUE},
  {"sxtraw2",TRUE},
  {"snormw1",TRUE},
  {"snormw2",TRUE},
  {"smnchw1",TRUE},
  {"smnchw2",TRUE},
  {"sdronw1",TRUE},
  {"sdronw2",TRUE},
  {"splyrw1",TRUE},
  {"splyrw2",TRUE},
  {"splyrs1",TRUE},
  {"splyrs2",TRUE},
  {"splyrp1",TRUE},
  {"splyrp2",TRUE},
  {"splyrh1",TRUE},
  {"splyrh2",TRUE},
  {"snormf",TRUE},
  {"smnchf",TRUE},
  {"sxtraf",TRUE},
  {"sdronf",TRUE},
  {"splyrf",TRUE},
  {"schmpo",TRUE},
  {"schmpc",TRUE},
  {"solidm",TRUE},
  {"solids",TRUE},
  {"solidi",TRUE},
  {"solidt",TRUE},
  {"shellm",TRUE},
  {"shells",TRUE},
  {"shelli",TRUE},
  {"shellt",TRUE},
  {"seat",TRUE},
  {"ghosting",FALSE},
  {"cake",TRUE},
  {"spanner",TRUE},
  {"brolly",TRUE},
  {"mushrm",TRUE},
  {"clock",TRUE},
#if 0
  /* Christine: I'm not quite sure about these. I noticed that these aren't mentioned */
  /* in the SpriteList.#?.msit files; then I checked defcom.c and got the impression */
  /* that Xmris uses the male SPRITE_XTRA sprites for msit? Anyway, I left it the way */
  /* it is now for msit */
  {"hxtraw1",TRUE},
  {"hxtraw2",TRUE},
#endif
  {"splyrd1",TRUE},
  {"splyrd2",TRUE},
  {"special",FALSE},
  {"fill0",FALSE},
  {"fill1",FALSE},
  {"fill2",FALSE},
  {"fill3",FALSE}
};

#define MRED_SPRITES 2
struct SpriteTable mred[]=
{
  {"oblong",FALSE},
  {"rect",FALSE},
  {"path",FALSE},
  {"hden",TRUE},
  {"cherry",TRUE},
  {"aplnorm",FALSE},
  {"gstnorm",FALSE},
  {"hplyrw1",TRUE},
  {"mredspecial",FALSE},
  {"fill0",FALSE},
  {"fill1",FALSE},
  {"fill2",FALSE},
  {"fill3",FALSE},
  {"red",TRUE},
  {"green",TRUE},
  {"blue",TRUE},
  {"noapple",FALSE},
  {"aplsmall",FALSE}
};

/************************************************************************/

struct
{
  const struct SpriteTable * const Table;
  const ULONG Count;
} const TheSprites[3]=
{
  {mris,ARRAYSIZE(mris)},
  {msit,ARRAYSIZE(msit)},
  {mred,ARRAYSIZE(mred)}
};

/************************************************************************/
/*									*/
/* Free a bitmap							*/
/*									*/
/************************************************************************/

static void FreeBitmap(struct BitMap *Bitmap)

{
  while (Bitmap->Depth)
    {
      FreeRaster(Bitmap->Planes[--Bitmap->Depth],Bitmap->BytesPerRow*8,Bitmap->Rows);
    }
  FreeVec(Bitmap);
}

/************************************************************************/
/*									*/
/* Create the image of a sprite						*/
/*									*/
/************************************************************************/

static INLINE struct MyBitmap *CreateImage(const struct Sprite *Sprite, ULONG Monochrome, ULONG Type)

{
  struct MyBitmap *Bitmap;

  if ((Bitmap=AllocVec(sizeof(*Bitmap)+(1<<Sprite->Depth)*sizeof(ULONG),0L)))
    {
      UBYTE *SpriteBitmap;
      ULONG Plane;

      if (Sprite->Colors)
	{
	  ULONG ColorCount;

	  Bitmap->ColorCount=1<<Sprite->Depth;
	  ColorCount=Bitmap->ColorCount;
	  while (--ColorCount)
	    {
	      if (Monochrome)
		{
		  Bitmap->ColorTable[ColorCount]=Colors[(Sprite->Colors[0] & (1<<ColorCount)) ?
							COLOR_BLACK : COLOR_WHITE][Type==MSIT_SPRITES];
		}
	      else
		{
		  if (Sprite->Colors[ColorCount]!=~0)
		    {
		      Bitmap->ColorTable[ColorCount]=Colors[Sprite->Colors[ColorCount]][Type==MSIT_SPRITES];
		    }
		  else
		    {
		      Bitmap->ColorTable[ColorCount]=0;
		    }
		}
	    }
	}
      else
	{
	  Bitmap->ColorCount=0;
	}
      InitBitMap(&Bitmap->Bitmap,Sprite->Depth,Sprite->Width,Sprite->Height/Sprite->Depth);
      SpriteBitmap=Sprite->Bitmap;
      for (Plane=0; Bitmap && Plane<Sprite->Depth; Plane++)
	{
	  UBYTE *CurrentPlane;

	  if ((CurrentPlane=Bitmap->Bitmap.Planes[Plane]=AllocRaster(Bitmap->Bitmap.BytesPerRow*8,Bitmap->Bitmap.Rows)))
	    {
	      WORD Row;

	      for (Row=0; Row<Bitmap->Bitmap.Rows; Row++)
		{
		  WORD Byte;

		  for (Byte=0; Byte<(Sprite->Width+7)/8; Byte++)
		    {
		      UBYTE Value;
		      UBYTE Bit;

		      Value=0;
		      for (Bit=0; Bit<8; Bit++)
			{
			  if (*SpriteBitmap & (1<<Bit))
			    {
			      Value|=(128>>Bit);
			    }
			}
		      *CurrentPlane=Value;
		      SpriteBitmap++;
		      CurrentPlane++;
		    }
		  while (Byte<Bitmap->Bitmap.BytesPerRow)
		    {
		      *(CurrentPlane++)=0;
		      Byte++;
		    }
		}
	    }
	  else
	    {
	      Bitmap->Bitmap.Depth=Plane+1;
	      FreeBitmap(&Bitmap->Bitmap);
	      Bitmap=NULL;
	    }
	}
    }
  return Bitmap;
}

/************************************************************************/
/*									*/
/* Create the mask for the sprite					*/
/*									*/
/************************************************************************/

static INLINE struct BitMap *CreateMask(struct MyBitmap *SpriteBitmap)

{
  struct BitMap *Bitmap;

  if ((Bitmap=AllocVec(sizeof(*Bitmap),0)))
    {
      InitBitMap(Bitmap,1,SpriteBitmap->Bitmap.BytesPerRow*8,SpriteBitmap->Bitmap.Rows);
      if ((Bitmap->Planes[0]=AllocRaster(SpriteBitmap->Bitmap.BytesPerRow*8,SpriteBitmap->Bitmap.Rows)))
	{
	  PLANEPTR Plane0;
	  ULONG Plane;

	  Plane0=SpriteBitmap->Bitmap.Planes[0];
	  BltClear(Bitmap->Planes[0],(Bitmap->Rows<<16)|(Bitmap->BytesPerRow),(1<<1));
	  for (Plane=0; Plane<SpriteBitmap->Bitmap.Depth; Plane++)
	    {
	      SpriteBitmap->Bitmap.Planes[0]=SpriteBitmap->Bitmap.Planes[Plane];
	      BltBitMap(&SpriteBitmap->Bitmap,0,0,Bitmap,0,0,Bitmap->BytesPerRow*8,Bitmap->Rows,0xe0,0x1,NULL);
	    }
	  SpriteBitmap->Bitmap.Planes[0]=Plane0;
	}
      else
	{
	  FreeVec(Bitmap);
	  Bitmap=NULL;
	}
    }
  return Bitmap;
}

/************************************************************************/
/*									*/
/* Make the halo							*/
/*									*/
/************************************************************************/

static INLINE int CreateHalo(struct MyBitmap *Image, ULONG Type)

{
  int RC;
  struct BitMap *Mask;

  RC=FALSE;
  if ((Mask=CreateMask(Image)))
    {
      struct BitMap *Bitmap;

      if ((Bitmap=AllocVec(sizeof(*Bitmap),0)))
	{
	  WORD Width, Height;

	  Width=Mask->BytesPerRow*8;
	  Height=Mask->Rows;
	  InitBitMap(Bitmap,1,Width,Height);
	  if ((Bitmap->Planes[0]=AllocRaster(Width,Height)))
	    {
	      if (Image->ColorCount==1<<Image->Bitmap.Depth)
		{
		  if (Image->Bitmap.Planes[Image->Bitmap.Depth]=AllocRaster(Width,Height))
		    {
		      BltClear(Image->Bitmap.Planes[Image->Bitmap.Depth++],
			       (Image->Bitmap.Rows<<16)|(Image->Bitmap.BytesPerRow),(1<<1));
		    }
		}
	      if (Image->ColorCount<1<<Image->Bitmap.Depth)
		{
		  struct RastPort RastPort;

		  BltBitMap(Mask,0,0,Bitmap,0,0,Width,Height,0xc0,0x1,NULL);

		  BltBitMap(Mask,0,0,Bitmap,1,0,Width-1,Height,0xe0,0x1,NULL);
		  BltBitMap(Mask,1,0,Bitmap,0,0,Width-1,Height,0xe0,0x1,NULL);
		  BltBitMap(Mask,0,0,Bitmap,0,1,Width,Height-1,0xe0,0x1,NULL);
		  BltBitMap(Mask,0,1,Bitmap,0,0,Width,Height-1,0xe0,0x1,NULL);

		  BltBitMap(Mask,0,0,Bitmap,0,0,Width,Height,0x20,0x1,NULL);

		  InitRastPort(&RastPort);
		  RastPort.BitMap=&Image->Bitmap;
		  SetABPenDrMd(&RastPort,Image->ColorCount,Image->ColorCount,JAM1);
		  BltTemplate(Bitmap->Planes[0],0,Bitmap->BytesPerRow,&RastPort,0,0,Width,Height);

		  Image->ColorTable[Image->ColorCount++]=Colors[COLOR_WHITE][Type==MSIT_SPRITES];
		  RC=TRUE;
		}
	      FreeRaster(Bitmap->Planes[0],Width,Height);
	    }
	  FreeVec(Bitmap);
	}
      FreeBitmap(Mask);
    }
  return RC;
}

/************************************************************************/
/*									*/
/* Write out the IFF-ILBM file						*/
/*									*/
/************************************************************************/

static INLINE int WriteIFF(struct Sprite *Sprite, struct MyBitmap *Image, ULONG Monochrome, ULONG Type)

{
  BPTR DirLock;
  struct IFFHandle *IFFHandle;
  int RC;

  if (!(DirLock=Lock(Sprite->Path,SHARED_LOCK)))
    {
      if (!(DirLock=CreateDir(Sprite->Path)))
	{
	  PError(0,Sprite->Path);
	  return FALSE;
	}
      ChangeMode(CHANGE_LOCK,DirLock,SHARED_LOCK);
    }
  RC=FALSE;
  DirLock=CurrentDir(DirLock);
  if ((IFFHandle=AllocIFF()))
    {
      static const char SpriteTypes[3*4]=
	{
	  'm','r','i','s',
	  'm','s','i','t',
	  'm','r','e','d'
	};
      char Filename[100];

      SPrintf(Filename,"%s.%s.%.4s",Sprite->Name,(Monochrome ? "mono" : "color"),SpriteTypes+4*Type);
      if ((IFFHandle->iff_Stream=Open(Filename,MODE_NEWFILE)))
	{
	  LONG ErrorCode;
	  ULONG i;

	  InitIFFasDOS(IFFHandle);
	  if (!(ErrorCode=OpenIFF(IFFHandle,IFFF_WRITE)))
	    {
	      if (!ErrorCode)
		ErrorCode=PushChunk(IFFHandle,MAKE_ID('I','L','B','M'),MAKE_ID('F','O','R','M'),IFFSIZE_UNKNOWN);

	      /* write CMAP */
	      if (Image->ColorCount)
		{
		  if (!ErrorCode)
		    ErrorCode=PushChunk(IFFHandle,MAKE_ID('I','L','B','M'),MAKE_ID('C','M','A','P'),Image->ColorCount*3);
		  for (i=0; !ErrorCode && i<Image->ColorCount; i++)
		    if (WriteChunkBytes(IFFHandle,(i ? ((UBYTE *)&Image->ColorTable[i])+1 : (UBYTE *)&i),3)!=3)
		      {
			PError(0,Filename);
			ErrorCode=IFFERR_WRITE;
		      }
		  if (!ErrorCode)
		    ErrorCode=PopChunk(IFFHandle);
		}

	      /* write BMHD */
	      {
		struct
		  {
		    UWORD Width, Height;
		    WORD Left, Top;
		    UBYTE Depth;
		    UBYTE Masking;
		    UBYTE Compression;
		    UBYTE Pad1;
		    UWORD TransparentColor;
		    UBYTE XAspect, YAspect;
		    WORD PageWidth, PageHeight;
		  } BMHD;

		BMHD.Width=Sprite->Width;
		BMHD.Height=Image->Bitmap.Rows;
		BMHD.Left=0;
		BMHD.Top=0;
		BMHD.Depth=Image->Bitmap.Depth;
		BMHD.Masking=2;
		BMHD.Compression=0;
		BMHD.Pad1=0;
		BMHD.TransparentColor=0;
		BMHD.XAspect=1;
		BMHD.YAspect=1;
		BMHD.PageWidth=Image->Bitmap.BytesPerRow*8;
		BMHD.PageHeight=Image->Bitmap.Rows;
		if (!ErrorCode)
		  ErrorCode=PushChunk(IFFHandle,MAKE_ID('I','L','B','M'),MAKE_ID('B','M','H','D'),sizeof(BMHD));
		if (!ErrorCode)
		  if (WriteChunkBytes(IFFHandle,&BMHD,sizeof(BMHD))!=sizeof(BMHD))
		    {
		      PError(0,Filename);
		      ErrorCode=IFFERR_WRITE;
		    }
		if (!ErrorCode)
		  ErrorCode=PopChunk(IFFHandle);
	      }

	      /* write BODY */
	      {
		UWORD Row;
		if (!ErrorCode)
		  ErrorCode=PushChunk(IFFHandle,MAKE_ID('I','L','B','M'),MAKE_ID('B','O','D','Y'),
				      Image->Bitmap.BytesPerRow*Image->Bitmap.Rows*Image->Bitmap.Depth);
		for (Row=0; !ErrorCode && Row<Image->Bitmap.Rows; Row++)
		  {
		    UWORD Plane;

		    for (Plane=0; !ErrorCode && Plane<Image->Bitmap.Depth; Plane++)
		      {
			if (WriteChunkBytes(IFFHandle,
					    ((UBYTE *)Image->Bitmap.Planes[Plane])+Row*Image->Bitmap.BytesPerRow,
					    Image->Bitmap.BytesPerRow)!=Image->Bitmap.BytesPerRow)
			  {
			    PError(0,Filename);
			    ErrorCode=IFFERR_WRITE;
			  }
		      }
		  }
		if (!ErrorCode)
		  ErrorCode=PopChunk(IFFHandle);
	      }

	      if (!ErrorCode)
		ErrorCode=PopChunk(IFFHandle);
	      if (!ErrorCode)
		RC=TRUE;
	      CloseIFF(IFFHandle);
	      if (ErrorCode)
		{
		  VFPrintf(StdErr,"IFF error: %ld\n",&ErrorCode);
		}
	    }
	  if (!Close(IFFHandle->iff_Stream))
	    {
	      PError(0,Filename);
	      RC=FALSE;
	    }
	  else
	    {
	      SetProtection(Filename,FIBF_EXECUTE);
	    }
	  if (!RC)
	    {
	      DeleteFile(Filename);
	    }
	}
      FreeIFF(IFFHandle);
    }
  UnLock(CurrentDir(DirLock));
  return RC;
}

/************************************************************************/
/*									*/
/* Cross out a sprite							*/
/* This is used to create the "noapple" sprite from the "aplnorm"	*/
/* sprite								*/
/*									*/
/************************************************************************/

#define CrossWritePixel(RastPort,x,y) WritePixel(RastPort,x,y); WritePixel(RastPort,x,31-(y))

static INLINE void CrossSprite(struct MyBitmap *Image, ULONG Monochrome, ULONG Type)

{
  struct RastPort RastPort;
  ULONG Color;
  WORD i;

  InitRastPort(&RastPort);
  RastPort.BitMap=&Image->Bitmap;
  Color=(1<<noapple_depth)-1;
  SetAPen(&RastPort,Color);

  if (Monochrome)
    {
      Image->ColorTable[Color]=Colors[COLOR_BLACK][Type==MSIT_SPRITES];
    }
  else
    {
      Image->ColorTable[Color]=Colors[COLOR_RED][Type==MSIT_SPRITES];
    }

  for (i=1; i<31; i++)
    {
      CrossWritePixel(&RastPort,i,i);
      CrossWritePixel(&RastPort,i+1,i-1);
      CrossWritePixel(&RastPort,i-1,i+1);
      if (i>1)
	{
	  CrossWritePixel(&RastPort,i,i-1);
	  CrossWritePixel(&RastPort,i-1,i);
	}
    }
}

/************************************************************************/
/*									*/
/* Create an IFF-ILBM file						*/
/*									*/
/************************************************************************/

static int MakeIFF(const struct SpriteTable *SpriteTable, ULONG Monochrome, ULONG Type)

{
  ULONG i;
  int RC;

  RC=FALSE;
  for (i=0; !RC && i<sizeof(Sprites)/sizeof(Sprites[0]); i++)
    {
      if (!strcmp(Sprites[i].Name,SpriteTable->Name))
	{
	  struct MyBitmap *Image;

	  if ((Image=CreateImage(&Sprites[i],Monochrome,Type)))
	    {
	      if (!SpriteTable->BorderHalo || CreateHalo(Image,Type))
		{
		  if (!strcmp(SpriteTable->Name,"noapple"))
		    {
		      CrossSprite(Image,Monochrome,Type);
		    }
		  if (WriteIFF(&Sprites[i],Image,Monochrome,Type))
		    {
		      RC=TRUE;
		    }
		}
	      FreeBitmap(&Image->Bitmap);
	    }
	  if (!RC)
	    {
	      break;
	    }
	}
    }
  return RC;
}

/************************************************************************/
/*									*/
/* Create the destination directory					*/
/*									*/
/************************************************************************/

static int CreateDestDir(const char *Dest)

{
  char *Dir;

  if ((Dir=AllocVec(strlen(Dest)+1,0)))
    {
      ULONG Count;

      strcpy(Dir,Dest);
      Count=0;
      while (TRUE)
	{
	  char *t;

	  t=PathPart(Dir);
	  if (*t)
	    {
	      Count++;
	      *t='\0';
	    }
	  else
	    {
	      break;
	    }
	}

      do
	{
	  BPTR DirLock;
	  ULONG Index;

	  if (!(DirLock=Lock(Dir,SHARED_LOCK)))
	    {
	      DirLock=CreateDir(Dir);
	    }
	  if (DirLock)
	    {
	      UnLock(DirLock);
	    }
	  else
	    {
	      PError(0,Dir);
	      break;
	    }
	  Index=strlen(Dir);
	  Dir[Index]=Dest[Index];
	}
      while (Count--);
      FreeVec(Dir);
      if (Count!=~0)
	{
	  Dir=NULL;
	}
    }
  return Dir!=NULL;
}

/************************************************************************/

int AmigaMain(void)

{
  int RC;

  RC=RETURN_CATASTROPHY;
  if (!WorkbenchMessage)
    {
      if ((DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",ROM_VERSION)))
	{
	  if ((UtilityBase=OpenLibrary("utility.library",ROM_VERSION)))
	    {
	      if ((GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",ROM_VERSION)))
		{
		  ErrorHandle();
		  RC=RETURN_FAIL;
		  if ((IFFParseBase=OpenLibrary("iffparse.library",36)))
		    {
		      struct
			{
			  char *Dest;
			  LONG Mono;
			  LONG Types[3];
			} Arguments;
		      struct RDArgs *RDArgs;

		      Arguments.Mono=FALSE;
		      Arguments.Types[MRIS_SPRITES]=FALSE;
		      Arguments.Types[MSIT_SPRITES]=FALSE;
		      Arguments.Types[MRED_SPRITES]=FALSE;
		      Arguments.Dest="";
		      if ((RDArgs=ReadArgs("DEST,MONO/S,MRIS/S,MSIT/S,MRED/S",(long *)&Arguments,NULL)))
			{
			  ULONG Type;

			  for (Type=0; Type<ARRAYSIZE(Arguments.Types); Type++)
			    {
			      if (Arguments.Types[Type])
				{
				  if (CreateDestDir(Arguments.Dest))
				    {
				      BPTR DirLock;

				      if ((DirLock=Lock(Arguments.Dest,SHARED_LOCK)))
					{
					  ULONG i;

					  RC=RETURN_OK;
					  DirLock=CurrentDir(DirLock);
					  for (i=0; RC==RETURN_OK && i<TheSprites[Type].Count; i++)
					    {
					      if (!MakeIFF(&TheSprites[Type].Table[i],!!Arguments.Mono,Type))
						{
						  RC=RETURN_ERROR;
						}
					      if (CheckSignal(SIGBREAKF_CTRL_C))
						{
						  PError(ERROR_BREAK,NULL);
						  RC=RETURN_ERROR;
						}
					    }
					  UnLock(CurrentDir(DirLock));
					}
				      else
					{
					  PError(0,Arguments.Dest);
					}
				    }
				}
			    }
			  FreeArgs(RDArgs);
			}
		      else
			{
			  PError(0,NULL);
			}
		      CloseLibrary(IFFParseBase);
		    }
		  else
		    {
		      VFPrintf(StdErr,"Unable to open iffparse.library V36 or newer\n",NULL);
		    }
		  CloseLibrary(&GfxBase->LibNode);
		  CloseStdErr();
		}
	      CloseLibrary(UtilityBase);
	    }
	  CloseLibrary(&DOSBase->dl_lib);
	}
    }
  return RC;
}
