/*
**	$VER: draw_test.c 1.1 (12.03.1998)
**
**	This is an example program for CyberGL
**
**      Written by Frank Gerberding
**
**	Copyright © 1996-1998 by phase5 digital products
**      All Rights reserved.
**
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include <clib/exec_protos.h>

#define CYBERGLNAME             "cybergl.library"
#define CYBERGLVERSION          39L


#define SHARED                  /* we use the cybergl shared library */
#define GL_APICOMPATIBLE        /* we use stubs from cybergl.lib */


#include <cybergl/cybergl.h>
#include <proto/cybergl.h>

#ifdef SHARED
LONG __oslibversion   = 39L;
LONG __CGLlibversion = CYBERGLVERSION;
#endif





#define TABLE_SIZE 256


GLushort rMap [256] = {
  0x0000, 0x0000, 0x0CCC, 0x0CCC, 0x1444, 0x1000, 0x1000, 0x1888,
  0x2444, 0x2444, 0x2444, 0x2000, 0x2444, 0x2000, 0x3111, 0x3111,
  0x2000, 0x3111, 0x2888, 0x3555, 0x3111, 0x3111, 0x2888, 0x3999,
  0x3111, 0x4111, 0x3999, 0x3555, 0x3111, 0x4555, 0x4555, 0x4555,
  0x3999, 0x4111, 0x4DDD, 0x3999, 0x5111, 0x4999, 0x4DDD, 0x4555,
  0x4555, 0x5555, 0x3999, 0x5555, 0x5111, 0x4111, 0x5111, 0x4999,
  0x5555, 0x5555, 0x5555, 0x4999, 0x4999, 0x5111, 0x6555, 0x5999,
  0x6555, 0x4111, 0x5999, 0x6111, 0x5555, 0x4DDD, 0x6999, 0x6111,
  0x6999, 0x5111, 0x6111, 0x6999, 0x6111, 0x6555, 0x7555, 0x5111,
  0x6555, 0x4DDD, 0x6555, 0x6111, 0x7555, 0x5DDD, 0x6999, 0x7999,
  0x4DDD, 0x6555, 0x6555, 0x5999, 0x7555, 0x7999, 0x7111, 0x5DDD,
  0x6999, 0x7555, 0x6999, 0x7111, 0x7111, 0x8666, 0x7DDD, 0x6555,
  0x5111, 0x7555, 0x7111, 0x5999, 0x8666, 0x6111, 0x8AAA, 0x7111,
  0x7999, 0x7555, 0x7111, 0x6999, 0x8666, 0x6DDD, 0x5DDD, 0x8222,
  0x6999, 0x8EEE, 0x7999, 0x8666, 0x8222, 0x9222, 0x7111, 0x7999,
  0x9666, 0x6DDD, 0x6111, 0x8666, 0x8666, 0x6111, 0x6999, 0x8222,
  0x7111, 0x9AAA, 0x8666, 0x8222, 0x6DDD, 0x9EEE, 0x7111, 0x8EEE,
  0x7DDD, 0x7111, 0x8EEE, 0x9EEE, 0x6999, 0xA666, 0x8EEE, 0x8AAA,
  0x8AAA, 0x8AAA, 0x7999, 0xA666, 0x7111, 0x8AAA, 0x9EEE, 0x8666,
  0x9666, 0x6DDD, 0x8AAA, 0x9222, 0x7999, 0x9666, 0x8666, 0x9AAA,
  0x9666, 0x8666, 0x9AAA, 0x9666, 0x9AAA, 0x8AAA, 0x8666, 0x9666,
  0x7999, 0x8AAA, 0x9EEE, 0x9AAA, 0x8AAA, 0x8666, 0x9666, 0xA666,
  0x9AAA, 0xA666, 0x9AAA, 0xA222, 0xA666, 0xAEEE, 0x9666, 0x9666,
  0x9EEE, 0x9222, 0xAEEE, 0x9EEE, 0x9EEE, 0x9AAA, 0xAEEE, 0xAEEE,
  0x9EEE, 0xBAAA, 0xA666, 0x8EEE, 0xB666, 0xAEEE, 0xB666, 0xA666,
  0xA222, 0xAEEE, 0xB666, 0xB222, 0xAAAA, 0xAEEE, 0xAEEE, 0xBEEE,
  0xB222, 0xC222, 0xAAAA, 0xB222, 0xB666, 0xBAAA, 0xBAAA, 0xB666,
  0xCAAA, 0xB666, 0xC666, 0xC666, 0xC666, 0xBEEE, 0xC666, 0xB666,
  0xC666, 0xCEEE, 0xCEEE, 0xCEEE, 0xD666, 0xCEEE, 0xD666, 0xD666,
  0xB666, 0xDFFF, 0xDFFF, 0xDBBB, 0xE333, 0xDFFF, 0xE333, 0xE777,
  0xE777, 0xEFFF, 0xEFFF, 0xEFFF, 0xF777, 0xF777, 0xF777, 0xFBBB,
  0xFBBB, 0xFBBB, 0xF777, 0xF333, 0xFBBB, 0xF333, 0xF777, 0xF333
};





GLushort gMap [256] = {
  0x0000, 0x0000, 0x0888, 0x1000, 0x0444, 0x1000, 0x1000, 0x1888,
  0x0000, 0x0444, 0x0CCC, 0x1444, 0x1888, 0x2000, 0x0CCC, 0x0000,
  0x2000, 0x1888, 0x2444, 0x0CCC, 0x2000, 0x2000, 0x2444, 0x2000,
  0x2888, 0x0CCC, 0x2888, 0x2DDD, 0x3111, 0x1000, 0x1CCC, 0x2888,
  0x3555, 0x3111, 0x2888, 0x3999, 0x1000, 0x3111, 0x2888, 0x2DDD,
  0x3555, 0x1888, 0x3999, 0x1000, 0x1CCC, 0x3999, 0x3111, 0x3999,
  0x3555, 0x2DDD, 0x3999, 0x4111, 0x4111, 0x3999, 0x1444, 0x3999,
  0x1444, 0x3DDD, 0x4111, 0x3555, 0x4555, 0x4999, 0x1888, 0x3999,
  0x2444, 0x4DDD, 0x4111, 0x2888, 0x4111, 0x3555, 0x1888, 0x5111,
  0x4111, 0x4DDD, 0x4999, 0x4999, 0x1888, 0x4DDD, 0x4555, 0x2444,
  0x4DDD, 0x4999, 0x4111, 0x5111, 0x1CCC, 0x2444, 0x4555, 0x5555,
  0x4999, 0x3111, 0x5111, 0x4DDD, 0x4999, 0x1444, 0x2DDD, 0x5555,
  0x5111, 0x3DDD, 0x5111, 0x5111, 0x2000, 0x5999, 0x1CCC, 0x5555,
  0x5111, 0x5555, 0x5999, 0x6111, 0x3555, 0x5999, 0x5999, 0x4555,
  0x6111, 0x2888, 0x5999, 0x5555, 0x4999, 0x2000, 0x6555, 0x5999,
  0x2DDD, 0x6555, 0x6111, 0x5999, 0x5999, 0x5999, 0x6111, 0x6111,
  0x6999, 0x2444, 0x5555, 0x6111, 0x6555, 0x2888, 0x6999, 0x6111,
  0x6999, 0x6DDD, 0x6111, 0x3DDD, 0x6111, 0x2888, 0x6111, 0x6111,
  0x6999, 0x6999, 0x7111, 0x2888, 0x7111, 0x6999, 0x5111, 0x7111,
  0x6999, 0x6DDD, 0x7555, 0x6111, 0x7555, 0x6999, 0x7999, 0x6DDD,
  0x7111, 0x7999, 0x6111, 0x7111, 0x7555, 0x7999, 0x7DDD, 0x7555,
  0x7999, 0x8666, 0x7999, 0x7999, 0x8666, 0x8222, 0x8222, 0x7999,
  0x8666, 0x7999, 0x8AAA, 0x7999, 0x8666, 0x7555, 0x8EEE, 0x7DDD,
  0x8EEE, 0x8AAA, 0x8666, 0x8AAA, 0x9666, 0x8EEE, 0x8AAA, 0x8AAA,
  0x9222, 0x7999, 0x9666, 0x8EEE, 0x8AAA, 0x9222, 0x9222, 0x9AAA,
  0x9666, 0x9AAA, 0x9666, 0x9AAA, 0x9AAA, 0xA666, 0xA666, 0x9AAA,
  0xAAAA, 0x9AAA, 0xA666, 0xAAAA, 0xAAAA, 0xAEEE, 0xAEEE, 0xAEEE,
  0xA222, 0xAAAA, 0xB222, 0xB222, 0xBAAA, 0xB666, 0xBAAA, 0xAEEE,
  0xBAAA, 0xBEEE, 0xBEEE, 0xC666, 0xC222, 0xC666, 0xC666, 0xC666,
  0xB666, 0xCEEE, 0xC666, 0xCEEE, 0xD666, 0xD666, 0xCEEE, 0xD666,
  0xDBBB, 0xDFFF, 0xD666, 0xDFFF, 0xE777, 0xE777, 0xEFFF, 0xF333,
  0xF777, 0xF777, 0xFFFF, 0xF333, 0xFBBB, 0xF333, 0xFBBB, 0xF333
};





GLushort bMap [256] = {
  0x0000, 0x0888, 0x0444, 0x0000, 0x0444, 0x0888, 0x1000, 0x0CCC,
  0x0888, 0x0000, 0x0444, 0x0444, 0x0888, 0x0CCC, 0x0888, 0x0888,
  0x1888, 0x0000, 0x0CCC, 0x1000, 0x0444, 0x1888, 0x2444, 0x0444,
  0x1888, 0x1000, 0x0444, 0x1000, 0x1888, 0x1444, 0x0888, 0x0444,
  0x1888, 0x0CCC, 0x0444, 0x2000, 0x1888, 0x0888, 0x1444, 0x2000,
  0x1888, 0x1444, 0x2DDD, 0x2000, 0x2000, 0x2000, 0x0888, 0x1444,
  0x0444, 0x2000, 0x1000, 0x2888, 0x2444, 0x2444, 0x1CCC, 0x0888,
  0x2000, 0x4111, 0x1444, 0x0000, 0x2000, 0x2888, 0x2000, 0x0CCC,
  0x2000, 0x2888, 0x0888, 0x2444, 0x1444, 0x2888, 0x2000, 0x3555,
  0x2444, 0x3DDD, 0x0CCC, 0x1888, 0x2888, 0x2888, 0x1000, 0x1CCC,
  0x4999, 0x1CCC, 0x3111, 0x3111, 0x3111, 0x2888, 0x0CCC, 0x2DDD,
  0x2DDD, 0x3111, 0x2000, 0x1000, 0x1888, 0x2888, 0x2888, 0x2DDD,
  0x5555, 0x3555, 0x1888, 0x4DDD, 0x2888, 0x3DDD, 0x3111, 0x2888,
  0x1444, 0x2000, 0x3111, 0x3111, 0x3111, 0x3DDD, 0x5111, 0x2DDD,
  0x3999, 0x3111, 0x2888, 0x1444, 0x3999, 0x3555, 0x3111, 0x3555,
  0x2888, 0x3DDD, 0x5111, 0x2000, 0x2888, 0x6111, 0x4DDD, 0x2000,
  0x3DDD, 0x3555, 0x3999, 0x2DDD, 0x5111, 0x3999, 0x4DDD, 0x2000,
  0x3DDD, 0x4999, 0x2888, 0x3555, 0x6555, 0x3555, 0x2DDD, 0x3DDD,
  0x2888, 0x3555, 0x4555, 0x3999, 0x5555, 0x3999, 0x3DDD, 0x4111,
  0x2DDD, 0x6555, 0x3999, 0x4DDD, 0x5555, 0x3999, 0x4111, 0x2888,
  0x3111, 0x4DDD, 0x4DDD, 0x3999, 0x3111, 0x4999, 0x5555, 0x4555,
  0x6DDD, 0x4999, 0x3999, 0x4555, 0x5555, 0x6111, 0x4DDD, 0x3555,
  0x4111, 0x4555, 0x4999, 0x5555, 0x4111, 0x4555, 0x5111, 0x6999,
  0x4999, 0x6555, 0x3DDD, 0x5999, 0x5555, 0x6555, 0x4555, 0x4DDD,
  0x6555, 0x5555, 0x5555, 0x8666, 0x4DDD, 0x5111, 0x4555, 0x5999,
  0x6DDD, 0x5999, 0x5555, 0x5555, 0x6555, 0x5999, 0x6555, 0x5DDD,
  0x6111, 0x6555, 0x7999, 0x6999, 0x6DDD, 0x6111, 0x6999, 0x7999,
  0x6DDD, 0x8666, 0x6555, 0x6DDD, 0x6111, 0x7999, 0x6DDD, 0x9AAA,
  0x7DDD, 0x6DDD, 0x7DDD, 0x7111, 0x6DDD, 0x7DDD, 0x7111, 0x7DDD,
  0xB666, 0x7111, 0x7DDD, 0x7999, 0x7111, 0x7DDD, 0x8222, 0x7DDD,
  0x8EEE, 0x8222, 0x8EEE, 0x8EEE, 0x8222, 0x8EEE, 0x9222, 0x9AAA,
  0x9EEE, 0xAEEE, 0xAAAA, 0xCAAA, 0xB666, 0xD666, 0xCEEE, 0xEFFF
};





GLushort rPal [2] = {0x3333, 0x9999};
GLushort gPal [2] = {0x2222, 0x8888};
GLushort bPal [2] = {0x1111, 0x5555};





GLubyte charT [32] =
{
  0x00,0x00,
  0x00,0x00,
  0x03,0xC0,
  0x01,0x80,
  0x01,0x80,
  0x01,0x80,
  0x01,0x80,
  0x01,0x80,
  0x01,0x80,
  0x01,0x80,
  0x01,0x80,
  0x01,0x80,
  0x11,0x88,
  0x19,0x98,
  0x1F,0xF8,
  0x00,0x00
};





GLubyte *loadImage (void)
{
  FILE    *file;
  GLubyte *image = NULL;

  if (file = fopen ("PROGDIR:image.raw", "r"))
  {
    if (image = malloc (196608))
    {
      fread (image, 196608, 1, file);
    }
    fclose (file);
  }
  return image;
}





GLubyte *loadBitmap (void)
{
  FILE    *file;
  GLubyte *bitmap = NULL;

  if (file = fopen ("PROGDIR:bitmap.raw", "r"))
  {
    if (bitmap = malloc (10240))
    {
      fread (bitmap, 10240, 1, file);
    }
    fclose (file);
  }
  return bitmap;
}





GLubyte *loadIndices (void)
{
  FILE    *file;
  GLubyte *indices = NULL;

  if (file = fopen ("PROGDIR:indices.raw", "r"))
  {
    if (indices = malloc (81920))
    {
      fread (indices, 81920, 1, file);
    }
    fclose (file);
  }
  return indices;
}





void handle_window_events (struct Window *window)
{
  struct IntuiMessage *msg;
  int                  done = 0;

  while (!done)
  {
    Wait (1L << window->UserPort->mp_SigBit);
    while ((!done) && (msg = (struct IntuiMessage *) GetMsg (window->UserPort)))
    {
      switch (msg->Class)
      {
        case IDCMP_CLOSEWINDOW:
          done = 1;
          break;
      }
      ReplyMsg ((struct Message *) msg);
    }
  }
}





void main (int argc, char *argv [])
{
  void    *window;

  GLubyte *image;
  GLubyte *bitmap;
  GLubyte *indices;

  GLfloat  contrast = 1.0f, brightness = 0.0f;
  GLfloat  tableR [TABLE_SIZE];
  GLfloat  tableG [TABLE_SIZE];
  GLfloat  tableB [TABLE_SIZE];
  GLint    count;

  image   = loadImage ();
  bitmap  = loadBitmap  ();
  indices = loadIndices ();

  if(image && bitmap && indices)
  {
   for (count = 0; count < TABLE_SIZE; count++)
   {
    tableR [count] = ((GLfloat) count / (TABLE_SIZE - 1));
    tableG [count] = ((GLfloat) count / (TABLE_SIZE - 1));
    tableB [count] = ((GLfloat) count / (TABLE_SIZE - 1));
   }

   if (argc > 1)
   {
     sscanf (argv [1], "%f", &contrast);
   }
   if (argc > 2)
   {
     sscanf (argv [2], "%f", &brightness);
   }

   window = openGLWindowTags (512, 512, GLWA_Title, "draw_test",
                                        GLWA_IDCMP, IDCMP_CLOSEWINDOW,
                                        GLWA_CloseGadget, TRUE,
                                        GLWA_DepthGadget, TRUE,
                                        GLWA_DragBar,     TRUE,
                                        GLWA_Activate, TRUE,
                                        GLWA_RGBAMode, GL_TRUE,
                                        TAG_DONE);

   glClearColor     ((GLfloat) 0.0, (GLfloat) 0.0, (GLfloat) 0.0, (GLfloat) 1.0);
   glClearDepth     (1.0);
   glClear          (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   glPixelStorei    (GL_UNPACK_ALIGNMENT,   1);
   glPixelStorei    (GL_UNPACK_SWAP_BYTES,  GL_FALSE);
   glPixelStorei    (GL_UNPACK_SKIP_ROWS,   0);
   glPixelStorei    (GL_UNPACK_SKIP_PIXELS, 0);
   glPixelStorei    (GL_UNPACK_ROW_LENGTH,  0);
   glPixelTransferf (GL_RED_SCALE,   contrast);
   glPixelTransferf (GL_GREEN_SCALE, contrast);
   glPixelTransferf (GL_BLUE_SCALE,  contrast);
   glPixelTransferf (GL_RED_BIAS,    brightness);
   glPixelTransferf (GL_GREEN_BIAS,  brightness);
   glPixelTransferf (GL_BLUE_BIAS,   brightness);
   glPixelMapfv     (GL_PIXEL_MAP_R_TO_R, TABLE_SIZE, tableR);
   glPixelMapfv     (GL_PIXEL_MAP_G_TO_G, TABLE_SIZE, tableG);
   glPixelMapfv     (GL_PIXEL_MAP_B_TO_B, TABLE_SIZE, tableB);
   glPixelTransferi (GL_MAP_COLOR, GL_TRUE);
   glColor3d        (1.0, 0.0, 0.0);
   glRasterPos2d    (-0.5, -0.5);
   glDrawPixels     (256, 256, GL_RGB, GL_UNSIGNED_BYTE, image);

   glPixelStorei    (GL_UNPACK_ROW_LENGTH,  320);
   glPixelTransferi (GL_MAP_COLOR, GL_TRUE);
   glPixelMapusv    (GL_PIXEL_MAP_I_TO_R, 256, rMap);
   glPixelMapusv    (GL_PIXEL_MAP_I_TO_G, 256, gMap);
   glPixelMapusv    (GL_PIXEL_MAP_I_TO_B, 256, bMap);
   glDrawPixels     (256, 256, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, indices);

   glDrawPixels     (256, 256, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, indices);

   glDrawPixels     (256, 256, GL_LUMINANCE, GL_UNSIGNED_BYTE, indices);

   glPixelStorei    (GL_UNPACK_ALIGNMENT,  1);
   glPixelStorei    (GL_UNPACK_ROW_LENGTH, 320);
   glPixelTransferi (GL_MAP_COLOR, GL_TRUE);
   glPixelMapusv    (GL_PIXEL_MAP_I_TO_R, 2, rPal);
   glPixelMapusv    (GL_PIXEL_MAP_I_TO_G, 2, gPal);
   glPixelMapusv    (GL_PIXEL_MAP_I_TO_B, 2, bPal);
   glDrawPixels     (256, 256, GL_COLOR_INDEX, GL_BITMAP, bitmap);

   for (brightness = 0.0001; brightness <= 1.0; brightness *= 1.2)
   {
    glColor3f        (brightness, brightness, brightness);
    glRasterPos2d    (-0.5, 0.0);
    glPixelStorei    (GL_UNPACK_ROW_LENGTH, 0);
    for (count = 0; count < 18; count++)
    {
#ifndef GL_APICOMPATIBLE
      {
       GLbitmap bitmap;

       bitmap.width    = 16;
       bitmap.height    = 16;
       bitmap.xorig    = 1.0f;
       bitmap.yorig = 2.0f;
       bitmap.xmove = 14.2f;
       bitmap.ymove = 0.0f;
       bitmap.bitmap = charT;
       glBitmap (&bitmap);
      }
#else
      glBitmap (16, 16, 1.0f, 2.0f, 14.2f, 0.0f, charT);
#endif
     }
   }

   handle_window_events (getWindow (window));

   closeGLWindow (window);
  }

  if(bitmap)    free (bitmap);
  if(indices)   free (indices);
  if(image)     free (image);
  
}
