/*
** RAW_loader.cpp  -  Nikolaj Thygesen  -  21.  1998.
** Loader til fiktivt RAW-format. Bare lis'sem et eksempel
** =======================================================
*/

#include <dos/dos.h>

#include <proto/dos.h>
#include <proto/exec.h>
#include <stdlib.h>
#include <string.h>

struct BitmapLoaderBase {
  struct Library library;
};
#pragma libbase BitmapLoaderBase;

#include "basictype.h"
#include "proto/BitmapLoader.h"
#include "proto/DiamondBox.h"

/*
** Dette er LibBase til DiamondBOX's eget lille lib, der med tiden bliver lidt
** mere ordnet :o) Der er lidt kaos over det PT.
*/
struct Library *DiamondBase;


/*
** Denne struktur hjemmestrikkes til at indeholde de ting og sager man måtte
** behøve under læsningen af den enkelte filtype.
*/
struct PebbleHandle {
  unsigned linenumber, width;
  ULONG stream;
};


/*
** Her læser vi en enkelt scanline og returnerer nummeret på den læste scanline,
** i intervallet: [0, height[, i "*lineno". En pointer til vores PebbleHandle
** ligger i "data", og bitmap data smides i "SLP".
*/
enum RCode ASM LoaderScanline(
  A0 struct PebbleHandle *data,
  A1 PixelARGB *SLP,
  A2 unsigned *lineno
)
{
  *lineno = data->linenumber++;
  FRead(data->stream, SLP, PIXELARGB_SZ * data->width, 1);
  return Success;
}


/*
** Allokerer resourcer til læsning af bitmap.
** ==========================================
*/
struct PebbleHandle *OpenLoader(
  A0 char *filename,
  A1 unsigned *picwidth,
  A2 unsigned *picheight,
  D0 struct Library *diamondlib
)
{
  struct PebbleHandle *RC = NULL;
  char ID[4];

  /*
  ** For nemheds skyld overleveres en pointer til lokalt lib, som også kunne
  ** åbnes. Det giver adgang til en række utility-funktioner. Nogle får er
  ** allerede på nuværende tidspunkt ligegyldige.
  */
  DiamondBase = diamondlib;
  /*
  ** PebbleHandle SKAL allokeres med dertil indrettet funtion, og ligeledes
  ** frigives med FreePebbleHandle(). Returværdi forskellig fra NULL angiver
  ** succesfuld åbning af bitmap-fil.
  */
  if(RC = AllocPebbleHandle(sizeof(struct PebbleHandle))) {
    if(RC->stream = (ULONG)Open(filename, MODE_OLDFILE)) {
      FRead(RC->stream, ID, 4, 1);
      /*
      ** Bemærk at der ikke fejlmeddeles ifm. identifikation da vi elegant videre-
      ** giver kontrollen til næste loader hvis det viser sig ikke at være vores
      ** filtype. Vi forestiller os at de første fire bytes indeholder tegnene:
      ** 'X', 'R', 'A' og 'W' efterfulgt af bredde, højde og selve bitmap.
      */
      if(!memcmp("XRAW", ID, 4)) {
        FRead(RC->stream, picwidth, 4, 1);
        FRead(RC->stream, picheight, 4, 1);
        RC->linenumber = 0;
        RC->width = *picwidth;
        return RC;
      }
      Close(RC->stream);
    }
    else DumpError(RC_UNFOUNDFILE, filename);
    FreePebbleHandle(RC);
  }
  else DumpError(RC_NOMEMORY, "PebbleHandle");
  return NULL;
}


/*
** Denne lille finesse har endnu ikke fundet anvendelse, men den er rar at have
** hvis det nu skulle vise sig... Bemærk at CloseLoader() bliver kaldt efter
** AbortLoader(), så ikke noget med at lukke filer to gange.
*/
void ASM AbortLoader(A0 struct PebbleHandle *data) {}


/*
** Ikke de store overraskelser her :o)
*/
void CloseLoader(A0 struct PebbleHandle *data)
{
  Close(data->stream);
  FreePebbleHandle(data);
}


unsigned long ASM IdentifyLoader(A0 char *name)
{
  /*
  ** Navnet på loaderen skal holdes på højest 30 tegn.
  */
  strcpy(name, "RAW loader");
  return EXTERN_fileloader;
}


/*
** StormC++ linker kan ikke klare sig uden denne her :o(
*/
void exit(int x) {}

/* End Of File.*/
