Logo Search packages:      
Sourcecode: hermes1 version File versions  Download package

Blit.c

/*
   Format conversion handle routines for the HERMES library
   Copyright (c) 1998 Christian Nentwich (c.nentwich@cs.ucl.ac.uk)
   This source code is licensed under the GNU LGPL
  
   Please refer to the file COPYING.LIB contained in the distribution for
   licensing conditions
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "H_Conv.h"
#include "H_Format.h"
#include "H_Pal.h"
#include "H_Blit.h"
#include "Palette.h"
#include "Factory.h"
#include "Convert.h"
#include "HermConf.h"
#include "HeadC.h"
#include "HeadX86.h"
#include "HeadMMX.h"
#include "Debug.h"

/* ConverterList is a list of HermesConverter* */

static HermesConverter **ConverterList;
static int lastConverter=0;                  /* Array size, one beyond end */

static int refcount=0;
static HermesHandle currenthandle;



HermesHandle HERMES_API Hermes_BlitterInstance(unsigned long flags)
{

  int i;
  HermesConverter *newinstance;
  HermesConverter **newlist;

  DEBUG_PRINT("Hermes_BlitterInstance called\n","");
  /* Initialising, allocate initial size array of converters */

  if (!refcount) {

    ConverterList=(HermesConverter **)malloc(sizeof(HermesConverter*)*
                                   HERMES_INITIAL);
    if (!ConverterList) return 0;
    
    lastConverter=HERMES_INITIAL;
    currenthandle=1;

    for (i=0;i<lastConverter;i++)
    ConverterList[i]=0;

    DEBUG_PRINT("Creating dynamic array(Blit.c:58), size %d\n",HERMES_INITIAL)
  } 


  /* Uh oh, arrary too small, time for growth */

  if (currenthandle==lastConverter) {

    /* I'm told realloc isn't completely portable !? Let's do it by hand */

    newlist=(HermesConverter **)malloc(sizeof(HermesConverter*)*
                              (lastConverter+HERMES_GROWTH));
    if (!newlist) return 0;

    /* Copy converter pointers */

    for (i=0;i<lastConverter;i++)
    newlist[i]=ConverterList[i];

    free(ConverterList);

    /* Assign new list to old one */

    ConverterList=newlist;

    lastConverter+=HERMES_GROWTH;

    DEBUG_PRINT("Growing dynamic array, new size %d\n",lastConverter)
  }

  /* Create a HermesConverter */

  newinstance=(HermesConverter *)malloc(sizeof(HermesConverter));
  if (!newinstance) return 0;

  /* Zero it out */

  newinstance->loopnormal=0;
  newinstance->loopstretch=0;
  newinstance->normal=0;
  newinstance->stretch=0;
  newinstance->dither=0;
  newinstance->ditherstretch=0;
  newinstance->flags=flags;
  memset(&newinstance->source, 0, sizeof(HermesFormat));
  memset(&newinstance->dest, 0, sizeof(HermesFormat));

  ConverterList[currenthandle]=newinstance;

  refcount++;
  
  currenthandle++;

  return currenthandle-1;
}



void HERMES_API Hermes_BlitterReturn(HermesHandle handle)
{ if (handle<0 || handle>=lastConverter) return;

  /* Adjust reference count */
  refcount--;

  if (ConverterList[handle]!=0) {
    free(ConverterList[handle]);
    ConverterList[handle]=0;
  }

  /* No more references, deinitialise */

  if (!refcount) {

    if (ConverterList) {
      free(ConverterList);
      ConverterList=0;
    }

    currenthandle=0;
    lastConverter=0;
  }
}




int HERMES_API Hermes_BlitterRequest(HermesHandle handle,
                               HermesFormat *source,
                               HermesFormat *dest)
{
  int searchlist=0;
  int i;
  char found=0;
  HermesConverter *cnv;
  
  DEBUG_PRINT("Blitter Request\n","");
  /* Check array ranges */

  if (handle<0 || handle>=lastConverter) return 0;
  if (!ConverterList[handle]) return 0;

  cnv=ConverterList[handle];

  /* Cache repeated requests of the same conversion */

  if (Hermes_FormatEquals(source,&ConverterList[handle]->source) &&
      Hermes_FormatEquals(dest,&ConverterList[handle]->dest))
  {
      DEBUG_PRINT("Cached converter, from bpp %n", source->bits);
      DEBUG_PRINT("To bpp: %n\n", dest->bits);
      DEBUG_PRINT("\tColorkey source: %d,\n", source->has_colorkey);
      DEBUG_PRINT("\tColorkey dest: %d,\n", dest->has_colorkey);
      return 1;
  }



  /* Clear the generic converter flag */

  cnv->flags&=~HERMES_CONVERT_GENERIC;



  /* If the source and destination are equal and src no alph, use copy routines */
  
  if (Hermes_FormatEquals(source,dest) && !source->a) {
      DEBUG_PRINT("Source, dest equal! bpp %d\n", source->bits);  
      if ((source->bits&0x7)!=0 || source->bits > 32 || !source->bits) return 0;

      i=(source->bits>>3)-1;
      
      if (!equalConverters[i]) return 0;
   
    Hermes_FormatCopy(source,&cnv->source);
    Hermes_FormatCopy(dest,&cnv->dest);

    cnv->loopnormal=equalConverters[i]->loopnormal;
    cnv->loopstretch=equalConverters[i]->loopstretch;
    cnv->normal=equalConverters[i]->normal;
    cnv->stretch=equalConverters[i]->stretch;

    return 1;
  }

//*/

  /* Start looking for specialised converters */
  
  searchlist=0xff;

  switch (source->bits) {
    case 32: if (source->r==0xff0000 && source->g==0xff00 && source->b==0xff)
             searchlist=0;
             else
           if (source->r==0xff<<20 && source->g==0xff<<10 && source->b==0xff)
             searchlist=3;
             break;

    case 24: if (source->r==0xff0000 && source->g==0xff00 && source->b==0xff)
             searchlist=1; break;

    case 16: if (source->r==0xf800 && source->g==0x7e0 && source->b==0x1f)
             searchlist=2; 
             break;

     case 8: if (source->indexed)
             searchlist=4; 
             break;
  }
  
  
  /* We can use a quicker loop for 8 bit */
/*
  if (searchlist!=0xff)
  if (source->bits==8) {
    for (i=0;i<numConverters[searchlist];i++) {
      if (standardConverters[searchlist][i])
      if (dest->bits==standardConverters[searchlist][i]->dest.bits)
      {
      Hermes_FormatCopy(source,&cnv->source);
        Hermes_FormatCopy(dest,&cnv->dest);

        cnv->loopnormal=standardConverters[searchlist][i]->loopnormal;
        cnv->loopstretch=standardConverters[searchlist][i]->loopstretch;

        cnv->normal=standardConverters[searchlist][i]->normal;
        cnv->stretch=standardConverters[searchlist][i]->stretch;

      cnv->dither=standardConverters[searchlist][i]->dither;
      cnv->ditherstretch=standardConverters[searchlist][i]->ditherstretch;

        return 1;
      }
    }
  }
  else
  for (i=0;i<numConverters[searchlist];i++) {
    if (standardConverters[searchlist][i])
    if (Hermes_FormatEquals(&standardConverters[searchlist][i]->source,source)&&
      Hermes_FormatEquals(&standardConverters[searchlist][i]->dest,dest))
    { Hermes_FormatCopy(source,&cnv->source);
      Hermes_FormatCopy(dest,&cnv->dest);

      cnv->loopnormal=standardConverters[searchlist][i]->loopnormal;
      cnv->loopstretch=standardConverters[searchlist][i]->loopstretch;

      cnv->normal=standardConverters[searchlist][i]->normal;
      cnv->stretch=standardConverters[searchlist][i]->stretch;

      cnv->dither=standardConverters[searchlist][i]->dither;
      cnv->ditherstretch=standardConverters[searchlist][i]->ditherstretch;

      return 1;
    }
  }
*/

  /* Otherwise find a generic converter */

  cnv->loopnormal=0;
  cnv->loopstretch=0;
  cnv->dither=0;
  cnv->ditherstretch=0;
  cnv->flags|=HERMES_CONVERT_GENERIC;


  /* Generic routines implement whole converters not scanline converters, 
     assign placeholders */

  cnv->normal=NotApplicable;
  cnv->stretch=NotApplicable;
 
  found=0;
  
/*
      Converting rules:

      C -> C
      C -> A

      A -> O, A -> A
      A -> C 

      O -> O , A, C are the same
*/
  if ((source->has_colorkey==1) && (dest->has_colorkey==1)) // Ck -> Ck
  {
      DEBUG_PRINT("CKCK\n","");
    switch (source->bits) {
      case 32: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic32_C_Generic32_C_Blit;
                  cnv->loopstretch=ConvertC_Generic32_C_Generic32_C_S_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_C_Generic32_C_Blit", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic32_C_Generic24_C_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_C_Generic24_C_Blit", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic32_C_Generic16_C_Blit;
                        cnv->loopstretch=ConvertC_Generic32_C_Generic16_C_S_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_C_Generic16_C_Blit", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic32_C_Generic8_C_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_C_Generic8_C_Blit", NULL);
                    found=1; break;
               }
               break;
  
      case 24: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic24_C_Generic32_C_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_C_Generic32_C_Blit", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic24_C_Generic24_C_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_C_Generic24_C_Blit", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic24_C_Generic16_C_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_C_Generic16_C_Blit", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic24_C_Generic8_C_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_C_Generic8_C_Blit", NULL);
                    found=1; break;
               }
               break;
         
      case 16: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic16_C_Generic32_C_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_C_Generic32_C_Blit", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic16_C_Generic24_C_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_C_Generic24_C_Blit", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic16_C_Generic16_C_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_C_Generic16_C_Blit", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic16_C_Generic8_C_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_C_Generic8_C_Blit", NULL);
                    found=1; break;
               }
               break;    
    }
  }
/*
  else if ((source->has_colorkey==1) && dest->a) // Ck -> A
  {
    switch (source->bits) {
      case 32: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic32_C_Generic32_A_Blit;
                  cnv->loopstretch=ConvertC_Generic32_C_Generic32_A_S_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_C_Generic32_A_Blit", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic32_C_Generic24_A_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_C_Generic24_A_Blit", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic32_C_Generic16_A_Blit;
                        cnv->loopstretch=ConvertC_Generic32_C_Generic16_A_S_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_C_Generic16_A_Blit", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic32_C_Generic8_A_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_C_Generic8_A_Blit", NULL);
                    found=1; break;
               }
               break;
  
      case 24: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic24_C_Generic32_A_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_C_Generic32_A_Blit", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic24_C_Generic24_A_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_C_Generic24_A_Blit", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic24_C_Generic16_A_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_C_Generic16_A_Blit", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic24_C_Generic8_A_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_C_Generic8_A_Blit", NULL);
                    found=1; break;
               }
               break;
         
      case 16: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic16_C_Generic32_A_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_C_Generic32_A_Blit", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic16_C_Generic24_A_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_C_Generic24_A_Blit", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic16_C_Generic16_A_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_C_Generic16_A_Blit", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic16_C_Generic8_A_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_C_Generic8_A_Blit", NULL);
                    found=1; break;
               }
               break;    
    }
  }
  else if (source->a && (dest->has_colorkey==1)) // A -> Ck
  {

    switch (source->bits) {
      case 32: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic32_A_Generic32_C_Blit;
                  cnv->loopstretch=ConvertC_Generic32_A_Generic32_C_S_Blit;
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic32_A_Generic24_C_Blit;
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic32_A_Generic16_C_Blit;
                        cnv->loopstretch=ConvertC_Generic32_A_Generic16_C_S_Blit;
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic32_A_Generic8_C_Blit;
                    found=1; break;
               }
               break;
  
      case 24: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic24_A_Generic32_C_Blit;
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic24_A_Generic24_C_Blit;
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic24_A_Generic16_C_Blit;
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic24_A_Generic8_C_Blit;
                    found=1; break;
               }
               break;
         
      case 16: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic16_A_Generic32_C_Blit;
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic16_A_Generic24_C_Blit;
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic16_A_Generic16_C_Blit;
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic16_A_Generic8_C_Blit;
                    found=1; break;
               }
               break;    
    }

  }
*/
  else if (source->a && dest->a) // A -> A
  {
      DEBUG_PRINT("AA\n","");
    switch (source->bits) {
      case 32: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic32_A_Generic32_O_Blit;
                  cnv->loopstretch=ConvertC_Generic32_A_Generic32_O_S_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_A_Generic32_A_Blit", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic32_A_Generic24_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_A_Generic24_A_Blit", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic32_A_Generic16_O_Blit;
                        cnv->loopstretch=ConvertC_Generic32_A_Generic16_O_S_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_A_Generic16_A_Blit", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic32_A_Generic8_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_A_Generic8_A_Blit", NULL);
                    found=1; break;
               }
               break;
  
      case 24: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic24_A_Generic32_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_A_Generic32_A_Blit", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic24_A_Generic24_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_A_Generic24_A_Blit", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic24_A_Generic16_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_A_Generic16_A_Blit", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic24_A_Generic8_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_A_Generic8_A_Blit", NULL);
                    found=1; break;
               }
               break;
         
      case 16: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic16_A_Generic32_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_A_Generic32_A_Blit", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic16_A_Generic24_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_A_Generic24_A_Blit", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic16_A_Generic16_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_A_Generic16_A_Blit", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic16_A_Generic8_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_A_Generic8_A_Blit", NULL);
                    found=1; break;
               }
               break;    
    }
  }

  
    // not working yet
    // Yes it is, I fixed it.
  else if (source->a) // A -> O
  {
    switch (source->bits) {
      case 32: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic32_A_Generic32_O_Blit;
                  cnv->loopstretch=ConvertC_Generic32_A_Generic32_O_S_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_A_Generic32_O_Blit", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic32_A_Generic24_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_A_Generic24_O_Blit", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic32_A_Generic16_O_Blit;
                        cnv->loopstretch=ConvertC_Generic32_A_Generic16_O_S_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_A_Generic16_O_Blit", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic32_A_Generic8_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_A_Generic8_O_Blit", NULL);
                    found=1; break;
               }
               break;
  
      case 24: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic24_A_Generic32_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_A_Generic32_O_Blit", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic24_A_Generic24_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_A_Generic24_O_Blit", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic24_A_Generic16_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_A_Generic16_O_Blit", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic24_A_Generic8_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_A_Generic8_O_Blit", NULL);
                    found=1; break;
               }
               break;
         
      case 16: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic16_A_Generic32_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_A_Generic32_O_Blit", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic16_A_Generic24_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_A_Generic24_O_Blit", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic16_A_Generic16_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_A_Generic16_O_Blit", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic16_A_Generic8_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_A_Generic8_O_Blit", NULL);
                    found=1; break;
               }
               break;    
    }
  }
  
  else if (source->has_colorkey==1) // C -> O
  {
  switch (source->bits) {
      case 32: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic32_C_Generic32_O_Blit;
                  cnv->loopstretch=ConvertC_Generic32_C_Generic32_O_S_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_C_Generic32_O_Blit", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic32_C_Generic24_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_C_Generic24_O_Blit", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic32_C_Generic16_O_Blit;
                        cnv->loopstretch=ConvertC_Generic32_C_Generic16_O_S_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_C_Generic16_O_Blit", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic32_C_Generic8_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_C_Generic8_O_Blit", NULL);
                    found=1; break;
               }
               break;
  
      case 24: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic24_C_Generic32_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_C_Generic32_O_Blit", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic24_C_Generic24_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_C_Generic24_O_Blit", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic24_C_Generic16_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_C_Generic16_O_Blit", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic24_C_Generic8_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_C_Generic8_O_Blit", NULL);
                    found=1; break;
               }
               break;
         
      case 16: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic16_C_Generic32_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_C_Generic32_O_Blit", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic16_C_Generic24_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_C_Generic24_O_Blit", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic16_C_Generic16_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_C_Generic16_O_Blit", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic16_C_Generic8_O_Blit;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_C_Generic8_O_Blit", NULL);
                    found=1; break;
               }
               break;    
    }
  }
  else // O->O, O->A, A->O, O->Ck
  {
      DEBUG_PRINT("Generic\n","");
    switch (source->bits) {
      case 32: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic32_Generic32;
                  cnv->loopstretch=ConvertC_Generic32_Generic32_S;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_Generic32", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic32_Generic24;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_Generic24", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic32_Generic16;
                        cnv->loopstretch=ConvertC_Generic32_Generic16_S;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_Generic16", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic32_Generic8;
                        DEBUG_PRINT("Using converter: ConvertC_Generic32_Generic8", NULL);
                    found=1; break;
               }
               break;
  
      case 24: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic24_Generic32;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_Generic32", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic24_Generic24;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_Generic24", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic24_Generic16;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_Generic16", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic24_Generic8;
                        DEBUG_PRINT("Using converter: ConvertC_Generic24_Generic8", NULL);
                    found=1; break;
               }
               break;
         
      case 16: switch(dest->bits) {
                 case 32: cnv->loopnormal=ConvertC_Generic16_Generic32;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_Generic32", NULL);
                    found=1; break;
             case 24: cnv->loopnormal=ConvertC_Generic16_Generic24;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_Generic24", NULL);
                    found=1; break;
             case 16: cnv->loopnormal=ConvertC_Generic16_Generic16;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_Generic16", NULL);
                    found=1; break;
              case 8: cnv->loopnormal=ConvertC_Generic16_Generic8;
                        DEBUG_PRINT("Using converter: ConvertC_Generic16_Generic8", NULL);
                    found=1; break;
               }
               break;    
    }
  }


  if (found) {
    Hermes_FormatCopy(source,&cnv->source);
    Hermes_FormatCopy(dest,&cnv->dest);

    return 1;
  }


  /* No converter found, fail */

  return 0;
}




int HERMES_API Hermes_BlitterPalette(HermesHandle handle,
                               HermesHandle sourcepal,
                               HermesHandle destpal)
{
  if (handle<0 || handle>=lastConverter) return 0;
  if (!ConverterList[handle]) return 0;

  /* Fail silently if not indexed colour format */

  if (!ConverterList[handle]->source.indexed) { 
    ConverterList[handle]->lookup=0;
    return 1;
  }
  
  ConverterList[handle]->lookup=
    Hermes_PaletteGetTable(sourcepal,&ConverterList[handle]->dest);
  
  if (!ConverterList[handle]->lookup) return 0;

  return 1;
}





int HERMES_API Hermes_BlitterBlit(HermesHandle handle,void *s_pixels,int s_x,
                            int s_y,int s_width,int s_height,
                            int s_pitch,void *d_pixels,int d_x,int d_y,
                            int d_width,int d_height,int d_pitch)
{ HermesConverter *cnv;
  HermesConverterInterface iface;

  if (handle<0 || handle>=lastConverter) return 0;
  cnv=ConverterList[handle];
  if (!cnv) return 0;


  /* Returns success if height or width is zero. This is debatable.. ! */

  if (s_width<=0 || s_height<=0 || d_width<=0 || d_height<=0) return 1;
  
  iface.s_pixels=(char8 *)s_pixels;
  iface.s_width=s_width;
  iface.s_height=s_height;
  iface.s_add=s_pitch-s_width*(cnv->source.bits>>3);
  iface.s_pitch=s_pitch;

  iface.d_pixels=(char8 *)d_pixels;
  iface.d_width=d_width;
  iface.d_height=d_height;
  iface.d_add=d_pitch-d_width*(cnv->dest.bits>>3);
  iface.d_pitch=d_pitch;

  iface.s_pixels+=s_y*s_pitch+s_x*(cnv->source.bits>>3);
  iface.d_pixels+=d_y*d_pitch+d_x*(cnv->dest.bits>>3);
  
  iface.s_has_colorkey = cnv->source.has_colorkey;
  iface.d_has_colorkey = cnv->dest.has_colorkey;
  iface.s_colorkey = cnv->source.colorkey;
  iface.d_colorkey = cnv->dest.colorkey;

  iface.lookup=cnv->lookup;


  /* For generic converters, do some extra setup (find shifts, etc.) 
     TODO: Move that out of here and in the request routine ! */

  if (cnv->flags&HERMES_CONVERT_GENERIC) {
    Hermes_Calculate_Generic_Info(Hermes_Topbit(cnv->source.r),
                          Hermes_Topbit(cnv->source.g),
                          Hermes_Topbit(cnv->source.b),
                          Hermes_Topbit(cnv->source.a),
                          Hermes_Topbit(cnv->dest.r),
                          Hermes_Topbit(cnv->dest.g),
                          Hermes_Topbit(cnv->dest.b),
                          Hermes_Topbit(cnv->dest.a),
                          &iface.info);
    iface.mask_r=cnv->dest.r;
    iface.mask_g=cnv->dest.g;
    iface.mask_b=cnv->dest.b;
    iface.s_mask_a = cnv->source.a;
  }


  /* Check for dithering. This should not be in here but in request as well */

  if (cnv->flags&HERMES_CONVERT_DITHER) {

    /* If there is a ditherer, use it else fall back to normal */

    if (cnv->dither) 
    cnv->loopnormal=cnv->dither;
  }


  /* Normal conversion */

  if (s_width==d_width && s_height==d_height) {
    if (!cnv->normal || !cnv->loopnormal) return 0;

    /* Optimization 
    if (iface.s_add==0 && iface.d_add==0) {
      iface.s_width *= s_height;
      iface.d_width *= d_height;
      iface.s_height = 1;    
      iface.d_height = 1;    
    }*/

    iface.func=cnv->normal;
    cnv->loopnormal(&iface);

    return 1;
  }
  /* Stretch conversion */
  else {
    if (!cnv->stretch || !cnv->loopstretch) return 0;
    
    iface.func=cnv->stretch;
    cnv->loopstretch(&iface);
  }

  return 1;
}









Generated by  Doxygen 1.6.0   Back to index