/* $Id: AmigaMesa.c 1.16 1997/06/25 19:16:56 StefanZ Exp StefanZ $ */

/*
 * Mesa 3-D graphics library
 * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/* This file has been extended (related to previous versions and related
   to the history above) for this current Amiga MESA application.
   Refer to the external history files for further changes  */


/*
$Log: AmigaMesa.c $
 * Revision 1.16  1997/06/25  19:16:56  StefanZ
 * New drawing rutines:
 * - Now in separate files
 * - cyberGfx added.
 *
 * Revision 1.15  1996/10/13  20:54:59  StefanZ
 * A few nasty bugfixes.
 *
 * Revision 1.14  1996/10/07  00:11:07  StefanZ
 * Mesa 2.0 Fixed
 *
 * Revision 1.13  1996/10/06  20:31:50  StefanZ
 * Source Bump before Mesa 2.0
 *
 * Revision 1.12  1996/08/14  22:17:32  StefanZ
 * New API to amigacalls (uses taglist)
 * Made it more flexible to add gfx-card support.
 * Fast doublebuff rutines
 * minor bugfixes
 *
 * Revision 1.10    1996/06/12  13:06:00  StefanZ
 * BugFix and encatments by Jorge Acereda (JAM)
 *
 * Revision 1.9  1996/06/11  15:53:02   StefanZ
 * Little speedup, VerryFast colorallocation by Stefan Burstöm
 *
 * Revision 1.8  1996/06/01  23:57:47   StefanZ
 * Started to use RCS to keep track of code.
 *
 * Revision 1.7  1996/05/21  23:08:42   StefanZ
 * A few bug and enforcer fixes
 *
 * Revision 1.6  1996/04/29  22:14:31   StefanZ
 * BugFixes reported by by Daniel Jönsson
 *
 * Revision 1.5  1996/03/14  23:54:33   StefanZ
 * Doublebuffer & Tmprastport seams to work (big speed improvment)
 * a fastpolydraw is also implemented
 *
 * Revision 1.4  1996/03/07  16:55:04   StefanZ
 * Much of the code works now (RGB mode is simulated) Doublebuffers... (didn't work)
 *
 * Revision 1.3  1996/02/29  02:12:45   StefanZ
 * First sight of colors (even the right ones) maglight.c works
 *
 * Revision 1.2  1996/02/25  13:11:16   StefanZ
 * First working version. Draws everything with the same color
 * (Colormaping is now urgent needed)
 *
 * Revision 1.1  1996/02/23  22:01:15   StefanZ
 * Made changes to match latest version of ddsample 1.5
 *
 * Revision 1.0  1996/02/21  11:01:15   StefanZ
 * File created from ddsample.c ver 1.3 and amesa.c ver 1.5
 * in a brave atempt to rebuild the amiga version
 *
 */


/*
TODO:
Dynamic allocate the vectorbuffer for polydrawing. (memory improvment)
implement shared list.
fix resizing bug.
some native asm rutine
fast asm line drawin in db mode
fast asm clear       in db mode
read buffer rutines  in db-mode

IDEAS:
 Make the gl a sharedlibrary. (Have ben started look in /amiga)
*/


/*
 * Note that you'll usually have to flip Y coordinates since Mesa's
 * window coordinates start at the bottom and increase upward.  Most
 * window system's Y-axis increases downward
 *
 * See dd.h for more device driver info.
 * See the other device driver implementations for ideas.
 *
 */


#include <exec/memory.h>
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/execbase.h>
#include <cybergraphics/cybergraphics.h>
#ifdef __GNUC__
#include <inline/exec.h>
#include <inline/intuition.h>
#include <inline/graphics.h>
#include <inline/utility.h>
#else
#ifndef __STORM__
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/utility.h>
#else
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/utility_protos.h>
#ifndef __PPC__
#include <pragma/exec_lib.h>
#include <pragma/dos_lib.h>
#include <pragma/intuition_lib.h>
#include <pragma/graphics_lib.h>
#include <pragma/utility_lib.h>
#else
#include <clib/powerpc_protos.h>
#endif
#endif
#endif

#ifdef __GNUC__
#include <proto/cybergraphics.h>
#else
#ifndef __STORM__
#include <inline/cybergraphics.h>
#else
#include <clib/cybergraphics_protos.h>
#ifndef __PPC__
#include <pragma/cybergraphics_lib.h>
#endif
#endif
#endif

#include <gl/AmigaMesa.h>

#include "ADisp_Cyb.h"
#include "ADisp_SW.h"
#include "ADisp_SWFS.h"
#include "ht_colors.h"



#include <stdlib.h>
#include <stdio.h>
#include <gl/gl.h>
#include "context.h"
#include "dd.h"
#include "xform.h"
#include "macros.h"
#include "vb.h"
#include "misc.h"

//#define DEBUGPRINT

#ifdef DEBUGPRINT
#define DEBUGOUT(x) printf(x);
#else
#define DEBUGOUT(x) /*printf(x);*/
#endif

#define TC_RGBA(r,g,b,a) ((((((a<<8)|r)<<8)|g)<<8)|b)

/**********************************************************************/
/*****                Internal Data                                         *****/
/**********************************************************************/
//struct amigamesa_context * amesa = NULL;
GLenum LastError;                /* The last error generated*/
struct Library *CyberGfxBase = NULL; /* optional base address for cybergfx */
extern struct Library *SysBase;

/**********************************************************************/
/*****                Some Usefull code                                     *****/
/**********************************************************************/

/*
	The Drawing area is defined by:

	CC.Viewport.X = x;
	CC.Viewport.Width = width;
	CC.Viewport.Y = y;
	CC.Viewport.Height = height;
*/



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

//extern void cyb_Faster_DD_pointers( GLcontext *ctx);
//extern void cyb_standard_DD_pointers( GLcontext *ctx);


/*
long _STI_200_InitMesaLibrary(void)
	{
	if(!GfxBase)
		{
//  printf("Opening graphics.library\n");
		if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",39)))
			{
			printf("MesaOpenGL Error\nCouldent open graphics.library v39\n");
			return(FALSE);
			}
		}
// printf("GfxBase=0x%x\n",GfxBase);
	return(TRUE);
	}

void _STD_200_DisposeMesaLibrary(void)
	{
	if (GfxBase)    // @@@ TODO Open and close gfxlibrary when open and flush lib.
		CloseLibrary((struct Library *)GfxBase);
	GfxBase=NULL;
	}
*/

/**********************************************************************/
/*****                  Amiga/Mesa API Functions                  *****/
/**********************************************************************/
/*
 * Implement the client-visible Amiga/Mesa interface functions defined
 * in Mesa/include/GL/Amigamesa.h
 *
 **********************************************************************/
/*
 * Implement the public Amiga/Mesa interface functions defined
 * in Mesa/include/GL/AmigaMesa.h
 */
 
struct amigamesa_visual *
AmigaMesaCreateVisualTags(long Tag1, ...)
{
	return AmigaMesaCreateVisual((struct TagItem *)&Tag1);
}

#ifdef __GNUC__
struct amigamesa_visual *
AmigaMesaCreateVisual(register struct TagItem *tagList)
#else
#ifndef __STORM__
__asm __saveds struct amigamesa_visual *
AmigaMesaCreateVisual(register __a0 struct TagItem *tagList)
#else
#ifndef __PPC__
struct amigamesa_visual * __saveds
AmigaMesaCreateVisual(register __a0 struct TagItem *tagList)
#else
struct amigamesa_visual * __saveds
AmigaMesaCreateVisual(struct TagItem *tagList)
#endif
#endif
#endif
{
   struct amigamesa_visual *v;
   int  index_bits;
   GLfloat redscale, greenscale, bluescale, alphascale;
   GLint redbits, greenbits, bluebits, alphabits;

#ifndef __PPC__
   v = (struct amigamesa_visual *)AllocVec(sizeof(struct amigamesa_visual),MEMF_PUBLIC|MEMF_CLEAR);
#else
   v = (struct amigamesa_visual *)AllocVecPPC(sizeof(struct amigamesa_visual),MEMF_PUBLIC|MEMF_CLEAR,0);
#endif
   if (!v) {
	  return NULL;
   }

	v->rgb_flag=GetTagData(AMA_RGBMode,GL_TRUE,tagList);
	v->db_flag=GetTagData(AMA_DoubleBuf,GL_FALSE,tagList);
	v->alpha_flag=GetTagData(AMA_AlphaFlag,GL_FALSE,tagList);


   if (v->rgb_flag) {
	  /* RGB(A) mode */
	  redscale =   greenscale = bluescale = alphascale = 255;
	  index_bits = 0;
	  redbits = greenbits = bluebits = 8;
	  alphabits = 8;
   }
   else {
	  /* color index mode */
	  redscale = 0.0;
	  greenscale = 0.0;
	  bluescale = 0.0;
	  alphascale = 0.0;
	  index_bits = 8;           /* @@@ TODO */
	  redbits = greenbits = bluebits = alphabits = 0;
   }
   v->depth = 16;
   /* Create core visual */
   v->gl_visual = gl_create_visual( v->rgb_flag, 
				    v->alpha_flag,
				    v->db_flag,
				    16,        /* depth_size */
				    8,         /* stencil_size */
				    16,        /* accum_size */
				    index_bits,
				    redscale, greenscale,
				    bluescale, alphascale,
				    redbits, greenbits,
				    bluebits, alphabits);

   return v;
}

#ifdef __GNUC__
void AmigaMesaDestroyVisual(register struct amigamesa_visual *v )
#else
#ifndef __STORM__
__asm __saveds void AmigaMesaDestroyVisual(register __a0 struct amigamesa_visual *v )
#else
#ifndef __PPC__
void __saveds AmigaMesaDestroyVisual(register __a0 struct amigamesa_visual *v )
#else
void __saveds AmigaMesaDestroyVisual(struct amigamesa_visual *v )
#endif
#endif
#endif
{
   gl_destroy_visual( v->gl_visual );
#ifndef __PPC__
   FreeVec( v );
#else
   FreeVecPPC( v );
#endif
}




struct amigamesa_buffer *AmigaMesaCreateBuffer( struct amigamesa_visual *visual,int windowid)
{
   struct amigamesa_buffer *b;

#ifndef __PPC__
   b = (struct amigamesa_buffer *) AllocVec(sizeof(struct amigamesa_buffer),MEMF_PUBLIC|MEMF_CLEAR);
#else
   b = (struct amigamesa_buffer *) AllocVecPPC(sizeof(struct amigamesa_buffer),MEMF_PUBLIC|MEMF_CLEAR,0);
#endif
   if (!b) {
	  return NULL;
   }

   b->gl_buffer = gl_create_framebuffer( visual->gl_visual);

   /* other stuff */

   return b;
}



void AmigaMesaDestroyBuffer( struct amigamesa_buffer *b )
{
	gl_destroy_framebuffer( b->gl_buffer );
#ifndef __PPC__
   FreeVec( b );
#else
   FreeVecPPC( b );
#endif
}




/* this small function checks if P96 is running */

/* currently not used

int DetectP96(void)
{
	struct Node *current;

	Forbid();
	current = ((struct ExecBase *)SysBase)->LibList.lh_Head;
	while (current->ln_Succ != 0)
	{
		if (!(strcmp("rtg.library",current->ln_Name)))
		{
			Permit();
			return(TRUE);
		}
		current = current->ln_Succ;
	}
	Permit();
	return(FALSE);
}

*/


#ifndef __PPC__
void SetFPU(void);
#endif

struct amigamesa_context *AmigaMesaCreateContextTags(long Tag1, ...)
{
	return AmigaMesaCreateContext((struct TagItem *)&Tag1);
}

#ifdef __GNUC__
struct amigamesa_context *
AmigaMesaCreateContext(register struct TagItem *tagList)
#else
#ifndef __STORM__
__asm __saveds struct amigamesa_context *
AmigaMesaCreateContext(register __a0 struct TagItem *tagList)
#else
#ifndef __PPC__
struct amigamesa_context * __saveds
AmigaMesaCreateContext(register __a0 struct TagItem *tagList)
#else
struct amigamesa_context * __saveds
AmigaMesaCreateContext(struct TagItem *tagList)
#endif
#endif
#endif
{
	/* Create a new Amiga/Mesa context */
	/* Be sure to initialize the following in the core Mesa context: */
	/* DrawBuffer, ReadBuffer */    /* @@@ IMPLEMENTERA ???*/


//  GLfloat redscale,greenscale,bluescale,alphascale;
//  int         I;
//      int drawMode;
	struct amigamesa_context *c;

#ifndef __PPC__
	SetFPU();       //set rounding mode to 'round to zero'
#endif
	/* try to open cybergraphics.library */
	if (CyberGfxBase==NULL)
		{
			CyberGfxBase = OpenLibrary((UBYTE*)"cybergraphics.library",0);
		}

		/* allocate amigamesa_context struct initialized to zeros */
#ifndef __PPC__
	c = (struct amigamesa_context *) AllocVec(sizeof(struct amigamesa_context),MEMF_PUBLIC|MEMF_CLEAR);
#else
	c = (struct amigamesa_context *) AllocVecPPC(sizeof(struct amigamesa_context),MEMF_PUBLIC|MEMF_CLEAR,0);
#endif
	if (!c)
		{
		LastError=AMESA_OUT_OF_MEM;
		return(NULL);
		}

	c->window=(struct Window *)GetTagData(AMA_Window,0,tagList);

/* this was moved from the driver to this place here */
	if (!c->window)
	    {
	    c->rp=(struct RastPort *)GetTagData(AMA_RastPort,0,tagList);
	    if (!c->rp)
		{
		LastError=AMESA_RASTPORT_TAG_MISSING;
		return(FALSE);
		}
	    c->Screen=(struct Screen *)GetTagData(AMA_Screen,0,tagList);
	    if (!c->Screen)
		{
		LastError=AMESA_SCREEN_TAG_MISSING;
		return(FALSE);
		}
	    }
	else
	{
	    c->rp =c->window->RPort;
	    c->Screen=c->window->WScreen;
	}

	if (GetTagData(AMA_Fullscreen,GL_FALSE,tagList) == GL_TRUE)
		c->flags = c->flags | FLAG_FULLSCREEN;
	if (GetTagData(AMA_DirectRender,GL_FALSE,tagList) == GL_TRUE)
		c->flags = c->flags | FLAG_DIRECTRENDER;


/* looks a bit ugly, I know... this code fragment makes sure, that
   the 'direct render'/'full screen'-mode isn't called for unsupported
   color formats */

	if (CyberGfxBase != 0)
	{
	    int fmt;

	    if (IsCyberModeID(GetVPModeID(&c->Screen->ViewPort)))
	    {
		fmt = GetCyberMapAttr(c->rp->BitMap,CYBRMATTR_PIXFMT);

/* all colorformats currently supported for direct rendering/full screen mode */

		if ((fmt != PIXFMT_LUT8) && (fmt != PIXFMT_RGB16)
		    && (fmt != PIXFMT_ARGB32) && (fmt != PIXFMT_BGRA32)
		    && (fmt != PIXFMT_RGB16PC) && (fmt != PIXFMT_RGB15)
		    && (fmt != PIXFMT_RGB15PC) && (fmt != PIXFMT_BGR15PC)
		    && (fmt != PIXFMT_BGR16PC) )
		{
		    c->flags = c->flags & (~FLAG_DIRECTRENDER);
		    c->flags = c->flags & (~FLAG_FULLSCREEN);
		}
	    }
	}





	c->visual=(struct amigamesa_visual *)GetTagData(AMA_Visual,NULL,tagList);
	c->buffer=(struct amigamesa_buffer *)GetTagData(AMA_Buffer,NULL,tagList);

	if(!c->visual)
		{
		if (!(c->visual=AmigaMesaCreateVisual(tagList)))
			{
			LastError=AMESA_OUT_OF_MEM;
			return NULL;
			}
		c->flags=c->flags|FLAG_OWNVISUAL;
		}

	if(!c->buffer)
		{
		if(!(c->buffer=AmigaMesaCreateBuffer( c->visual,GetTagData(AMA_WindowID,1,tagList))))
			{
			LastError=AMESA_OUT_OF_MEM;
			return NULL;
			}
		c->flags=c->flags|FLAG_OWNBUFFER;
		}

	c->share = NULL;        /* we misuse this field */
	c->gl_ctx = gl_create_context(  c->visual->gl_visual,NULL,(void *) c  );


/*
 *
 *      Launch gfx drivers
 *
 */

/* First check if cybergraphics.library available */

	if (CyberGfxBase)
	{
		if ( ((c->flags & FLAG_DIRECTRENDER) && (IsCyberModeID(GetVPModeID(&c->Screen->ViewPort))))
		    || (c->flags & FLAG_FULLSCREEN) )
		{

/* if direct rendering to gfx RAM or fullscreen mode is enabled,
   always call the full screen SW/HW driver */

			if (SWFSDriver_init(c,tagList))
				return c;
			else
				{
				gl_destroy_context( c->gl_ctx );
#ifndef __PPC__
				FreeVec( c );
#else
				FreeVecPPC( c );
#endif
				return NULL;
				}
		}

		if(c->visual->db_flag==GL_TRUE)
		{
/* if double buffered, than launch the new gfxboard SW driver (or
   HW driver in future */
			if (SWDriver_init(c,tagList))
				return c;
			else
				{
				gl_destroy_context( c->gl_ctx );
#ifndef __PPC__
				FreeVec( c );
#else
				FreeVecPPC( c );
#endif
				return NULL;
				}
		}
		else
		{
/* if not double buffered, launch the old gfx board driver */

			if (Cyb_Standard_init(c,tagList))
				return c;
			else
				{
				gl_destroy_context( c->gl_ctx );
#ifndef __PPC__
				FreeVec( c );
#else
				FreeVecPPC( c );
#endif
				return NULL;
				}
		}
	}

/* if cybergraphics.library not available, check for further drivers
   insert here alternative drivers (for example EGS).

   if no custom driver found, launch standard AGA compatible driver
   (works also for CGFX LUT 8)
*/
	else
	{

		if (c->flags & FLAG_FULLSCREEN)
		{

/* if full screen mode is enabled, call the full screen SW/HW driver */

			if (SWFSDriver_init(c,tagList))
				return c;
			else
				{
				gl_destroy_context( c->gl_ctx );
#ifndef __PPC__
				FreeVec( c );
#else
				FreeVecPPC( c );
#endif
				return NULL;
				}
		}

		if(c->visual->db_flag==GL_TRUE)
		{
/* if double buffered, launch the new AGA compatible SW driver */

			if (SWDriver_init(c,tagList))
				return c;
			else
				{
				gl_destroy_context( c->gl_ctx );
#ifndef __PPC__
				FreeVec( c );
#else
				FreeVecPPC( c );
#endif
				return NULL;
				}
		}
		else
		{
/* if not double-buffered, launch the old AGA driver */

			if (Amiga_Standard_init(c,tagList))
				return c;
			else
				{
				gl_destroy_context( c->gl_ctx );
#ifndef __PPC__
				FreeVec( c );
#else
				FreeVec( c );
#endif
				return NULL;
				}
		}
	}
}

void RestoreFPU(void);

#ifdef __GNUC__
void AmigaMesaDestroyContext(register struct amigamesa_context *c )
#else
#ifndef __STORM__
__asm __saveds void AmigaMesaDestroyContext(register __a0 struct amigamesa_context *c )
#else
#ifndef __PPC__
void __saveds AmigaMesaDestroyContext(register __a0 struct amigamesa_context *c )
#else
void __saveds AmigaMesaDestroyContext(struct amigamesa_context *c )
#endif
#endif
#endif

{
	/* destroy a Amiga/Mesa context */

/*
	if (c==amesa)
		amesa=NULL;
*/
	(*c->Dispose)( c );
	if(c->flags&FLAG_OWNVISUAL)
		AmigaMesaDestroyVisual(c->visual);
	if(c->flags&FLAG_OWNBUFFER)
		AmigaMesaDestroyBuffer(c->buffer);
	gl_destroy_context( c->gl_ctx );
#ifndef __PPC__
	FreeVec( c );
#else
	FreeVecPPC( c );
#endif
	if (CyberGfxBase)
		CloseLibrary(CyberGfxBase);
#ifndef __PPC__
	RestoreFPU();           //restore FPU rounding mode
#endif
}


#ifdef __GNUC__
void AmigaMesaMakeCurrent(register struct amigamesa_context *amesa,register struct amigamesa_buffer *b )
#else
#ifndef __STORM__
__asm __saveds void AmigaMesaMakeCurrent(register __a0 struct amigamesa_context *amesa,register __a1    struct amigamesa_buffer *b )
#else
#ifndef __PPC__
void __saveds AmigaMesaMakeCurrent(register __a0 struct amigamesa_context *amesa,register __a1    struct amigamesa_buffer *b )
#else
void __saveds AmigaMesaMakeCurrent(struct amigamesa_context *amesa,struct amigamesa_buffer *b )
#endif
#endif
#endif
{
	/* Make the specified context the current one */
	/* the order of operations here is very important! */


   if (amesa && b) {
	    if (amesa->gl_ctx == gl_get_current_context())
		return;
	    if (amesa->share == NULL)
	      if (!(amesa->visual->rgb_flag))
	      {
		AmigaMesaSetOneColor(amesa,0,0.0,0.0,0.0);
		AmigaMesaSetOneColor(amesa,1,1.0,0.0,0.0);
		AmigaMesaSetOneColor(amesa,2,0.0,1.0,0.0);
		AmigaMesaSetOneColor(amesa,3,1.0,1.0,0.0);
		AmigaMesaSetOneColor(amesa,4,0.0,0.0,1.0);
		AmigaMesaSetOneColor(amesa,5,1.0,0.0,1.0);
		AmigaMesaSetOneColor(amesa,6,0.0,1.0,1.0);
		AmigaMesaSetOneColor(amesa,7,1.0,1.0,1.0);
	     }
	   gl_make_current( amesa->gl_ctx,b->gl_buffer );
	   (*amesa->InitDD)(amesa->gl_ctx);                            /* Call Driver_init_rutine */
	   if (amesa->gl_ctx->Viewport.Width==0) {
		glViewport( 0, 0, amesa->width, amesa->height );
	   }
	   if (amesa->share == NULL)
	   {
	     if (!(amesa->visual->rgb_flag))
		glClearIndex(0.0);
	     else
		glClearColor(0.0,0.0,0.0,0.0);
	   }
	   amesa->share = (struct amigamesa_context *)1;  /* misuse */
   }
   else
   {
	gl_make_current( NULL,NULL);
   }
}



#ifdef __GNUC__
void AmigaMesaSwapBuffers(register struct amigamesa_context *amesa)
#else
#ifndef __STORM__
__asm __saveds void AmigaMesaSwapBuffers(register __a0 struct amigamesa_context *amesa)
#else
#ifndef __PPC__
void __saveds AmigaMesaSwapBuffers(register __a0 struct amigamesa_context *amesa)
#else
void __saveds AmigaMesaSwapBuffers(struct amigamesa_context *amesa)
#endif
#endif
#endif
	{                /* copy/swap back buffer to front if applicable */
	(*amesa->SwapBuffer)( amesa );
	}




/* This is on the drawingboard */
/* Mostly for when future changes the library is still intact*/

#ifdef __GNUC__
BOOL AmigaMesaSetDefs(register struct TagItem *tagList)
#else
#ifndef __STORM__
__asm __saveds BOOL AmigaMesaSetDefs(register __a0 struct TagItem *tagList)
#else
#ifndef __PPC__
BOOL __saveds AmigaMesaSetDefs(register __a0 struct TagItem *tagList)
#else
BOOL __saveds AmigaMesaSetDefs(struct TagItem *tagList)
#endif
#endif
#endif
	{
/*
	struct TagItem *tag;
		
	tagValue=AMA_DrawMode;
	tag = FindTagItem(tagValue,tagList);
	if (tag)
		printf("Tag=0x%x, is 0x%x/n",tagValue,tag->ti_Data);
	else
		printf("Tag=0x%x is not specified/n",tagValue);
*/
	return FALSE;
	}


/*
 Maybe a report error rutine ??? like:
*/

#ifdef __GNUC__
GLenum AmigaMesaReportError(register struct amigamesa_context *c )
#else
#ifndef __STORM__
__asm __saveds GLenum AmigaMesaReportError(register __a0 struct amigamesa_context *c )
#else
#ifndef __PPC__
GLenum __saveds AmigaMesaReportError(register __a0 struct amigamesa_context *c )
#else
GLenum __saveds AmigaMesaReportError(struct amigamesa_context *c )
#endif
#endif
#endif
	{
	GLenum error;
	error=LastError;
	LastError=NULL;
	return(error);
	}


/**********************************************************************/
/***** AmigaMesaSetOneColor                                       *****/
/**********************************************************************/
#ifdef __GNUC__
void AmigaMesaSetOneColor(register struct amigamesa_context *c,register __d0 int index, register __fp0 float r, register __fp1 float g, register __fp2 float b)
#else
#ifndef __STORM__
__asm __saveds void AmigaMesaSetOneColor(register __a0 struct amigamesa_context *c,register __d0 int index, register __fp0 float r, register __fp1 float g, register __fp2 float b)
#else
#ifndef __PPC__
void __saveds AmigaMesaSetOneColor(register __a0 struct amigamesa_context *c,register __d0 int index, register __fp0 float r, register __fp1 float g, register __fp2 float b)
#else
void __saveds AmigaMesaSetOneColor(struct amigamesa_context *c,int index,float r,float g,float b)
#endif
#endif
#endif
{
    unsigned char color;
    unsigned char red = (int)(r*255);
    unsigned char green = (int)(g*255);
    unsigned char blue = (int)(b*255);
    if (c->visual->rgb_flag)
	return;

    if (c->visual->db_flag)
    {
	if (c->depth <= 8)
	{
	    color = (unsigned char)ObtainBestPen(c->Screen->ViewPort.ColorMap,red<<24,green<<24,blue<<24,OBP_Precision,PRECISION_EXACT,TAG_DONE);
	    (c->ColorTable2[color])++;
	    c->penconv[index] = color;
	    c->penconvinv[color] = index;
	}
	else
	{
	    if ((c->flags & FLAG_FULLSCREEN) || (c->flags & FLAG_DIRECTRENDER))
	    {
		if (c->fmt == PIXFMT_ARGB32)
		    c->ColorTable2[index] = (red << 16) | (green << 8) | blue;
		if (c->fmt == PIXFMT_BGRA32)
		    c->ColorTable2[index] = (blue << 24) | (green << 16) | (red << 8);
		if (c->fmt == PIXFMT_RGB16)
		    c->ColorTable2[index] = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
		if (c->fmt == PIXFMT_RGB16PC)
		    c->ColorTable2[index] = ((red >> 3) << 3) | (green >> 5) | ((green >> 2) << 13) | ((blue >> 3) << 8);
		if (c->fmt == PIXFMT_RGB15)
		    c->ColorTable2[index] = ((red >> 3) << 10) | ((green >> 3) << 5) | (blue >> 3);
		if (c->fmt == PIXFMT_RGB15PC)
		    c->ColorTable2[index] = ((red >> 3) << 2) | (green >> 6) | ((green >> 3) << 13) | ((blue >> 3) << 8);
		if (c->fmt == PIXFMT_BGR16PC)
		    c->ColorTable2[index] = ((blue >> 3) << 3) | (green >> 5) | ((green >> 2) << 13) | ((red >> 3) << 8);
		if (c->fmt == PIXFMT_BGR15PC)
		    c->ColorTable2[index] = ((blue >> 3) << 2) | (green >> 6) | ((green >> 3) << 13) | ((red >> 3) << 8);
	    }
	    else
		c->ColorTable2[index] = (red << 16) | (green << 8) | blue;
	}
    }
    else
    {
	if (c->depth>8) {
	    c->ColorTable2[index] = (red << 16) | (green << 8) | blue;
	    ((unsigned long*)c->penconv)[index] = c->ColorTable2[index];
	} else {
#ifndef DITHERING
	    color = EvalPen(c,red,green,blue);
#else
	    color = EvalPen_D(c,red,green,blue,0,0);
#endif
	    c->penconv[index] = color;
	    c->penconvinv[color] = index;
	}
    }
}

void AmigaMesaSetRastTags(struct amigamesa_context *c, long Tag1, ...)
{
	AmigaMesaSetRast(c,(struct TagItem *)&Tag1);
}

/**********************************************************************/
/***** AmigaMesaSetRast                                           *****/
/**********************************************************************/
#ifdef __GNUC__
void AmigaMesaSetRast(register struct amigamesa_context *c, register __a1 struct TagItem* tagList)
#else
#ifndef __STORM__
__asm __saveds void AmigaMesaSetRast(register __a0 struct amigamesa_context *c, register __a1 struct TagItem* tagList)
#else
#ifndef __PPC__
void __saveds AmigaMesaSetRast(register __a0 struct amigamesa_context *c, register __a1 struct TagItem* tagList)
#else
void __saveds AmigaMesaSetRast(struct amigamesa_context *c, struct TagItem* tagList)
#endif
#endif
#endif
{
	struct Window* win;
	struct RastPort* rp;

	if (c->flags & FLAG_FULLSCREEN)
	{
		LastError=AMESA_NOT_IN_FULLSCREEN;
		return;
	}
	win=(struct Window *)GetTagData(AMA_Window,0,tagList);
	rp=(struct RastPort *)GetTagData(AMA_RastPort,0,tagList);

	if (!win)
	{
	    if (!rp)
	    {
		c->rp = NULL;
		c->front_rp = rp;
	    }
	    else
	    {
		c->rp = rp;
		c->front_rp = rp;
	    }
	}
	else
	{
	    c->window = win;
	    c->rp = win->RPort;
	    c->front_rp = c->rp;
	}
}


#undef DEBUGPRINT
