/*
 *  amiga.c
 *
 *  Author: Tomi Ollila <too@cs.hut.fi>
 *
 *  Created: Sun Jul 05 15:30:58 1992 too
 *  Last modified: Mon Sep 14 00:58:34 1992 too
 *
 */

#include <exec/types.h>
#include <intuition/intuition.h>
#include "iff.h"

#include <inline/stubs.h>
#include <inline/exec.h>
#include <inline/intuition.h>
#include <inline/graphics.h>
#include "inline_iff.h"

#include <stdlib.h>
#include <string.h>
#include "amiga.h"

#ifndef NULL
#define NULL 0
#endif

#define WRITERR(msg) write(2, msg, strlen(msg))

struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase	     *GfxBase = NULL;
struct Library	     *IFFBase = NULL;

void am_OpenLibraries(void)
{
  if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",
						   33)) == NULL) {
    WRITERR("Could not open Intuition library\n");
    am_CloseLibraries();
    exit(0);
  }
  if ((GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",
						   33)) == NULL) {
    WRITERR("Could not open Graphics library\n");
    am_CloseLibraries();
    exit(0);
  }
  if ((IFFBase = (struct Library *)OpenLibrary("iff.library",
						   22L)) == NULL) {
    WRITERR("Could not open IFF library\n");
    am_CloseLibraries();
    exit(0);
  }
}

void am_CloseLibraries()
{
  if (IntuitionBase)  CloseLibrary(IntuitionBase);
  if (GfxBase) CloseLibrary(GfxBase);
  if (IFFBase) CloseLibrary(IFFBase);
}

void am_GetScreenSize(w, h)
int * w;
int * h;
{
  struct Screen screen;

  if (GetScreenData((APTR)&screen, sizeof(struct Screen),
		    WBENCHSCREEN, NULL) == NULL) {
    WRITERR("Could not figure out screensize.\n");
    am_CloseLibraries();
    exit(0);
  }
  *w = screen.Width;
  *h = screen.Height;
}

/* Memory for bitmaps is longword aligned so we can use longword copy. */
#define BitmapSize(w,h) (((((w) + 31) / 32) * 4) * (h))

char * am_LoadFullmoon(w, h, filename)
     int  *	w;
     int  *	h;
     char *	filename;
{
  PLANEPTR	plane;
  IFFL_HANDLE	iffhandle;
  struct BitMap bitmap;
  struct IFFL_BMHD *bmhd;
  int size;

  if (filename == NULL)
    filename = "fullmoon.ilbm\0                                              ";

  if ((iffhandle = IFFL_OpenIFF(filename, IFFL_MODE_READ)) == NULL) {
    WRITERR("Error: Could not open ");
    WRITERR(filename);
    WRITERR(" for reading as fullmoon picture\n");
    am_CloseLibraries();
    exit(0);
  }
  if ((bmhd = IFFL_GetBMHD(iffhandle)) == NULL) {
    WRITERR("Error: no BMHD chunk in ");
    WRITERR(filename);
    WRITERR("\n");
    am_CloseLibraries();
    exit(0);
  }
  *w = (int)bmhd->w; *h = (int)bmhd->h;
  size = BitmapSize(*w, *h);

  if ((plane = (PLANEPTR)malloc(size)) == NULL) {
    WRITERR("Out of memory\n");
    am_CloseLibraries();
    exit(0);
  }
  InitBitMap(&bitmap, 1, *w, *h);
  bitmap.Planes[0] = plane;

  if (IFFL_DecodePic(iffhandle, &bitmap) == FALSE) {
    WRITERR("Error: Could not decode IFF picture\n");
    IFFL_CloseIFF(iffhandle);
    am_CloseLibraries();
    exit(0);
  }

  IFFL_CloseIFF(iffhandle);
  return (char *)plane;
}

static UWORD colortable[] = {0xaaa, 0x000, 0xfff, 0x68b};

void am_MakeIFFile(w, h, bits, reverseflag)
int	w;
int	h;
char *	bits;
int	reverseflag;
{
  struct BitMap bitmap;
  LONG		size;
  ULONG 	*plane1, *plane0;
  int		i;

  InitBitMap(&bitmap, 2, w, h);
  size = BitmapSize(w, h);
  plane0 = (ULONG *)bits;

  if ((plane1 = (ULONG *)malloc(size)) == NULL) {
    am_CloseLibraries();
    WRITERR("Out of memory\n");
    exit(0);
  }
  bitmap.Planes[reverseflag] = (PLANEPTR)plane1;
  bitmap.Planes[(reverseflag + 1) & 1] = (PLANEPTR)plane0;

  size >>= 2;
  for (i = 0; i < size; i++)
    plane1[i] = plane0[i] ^ 0xffffffff;

  (void)IFFL_SaveBitMap("RAM:phoon.ilbm", &bitmap, colortable, 0);
  free(plane1);
}
