/**************************************************/
/***                                            ***/
/*** Test2.c  -- test interface to inpout32.dll ***/
/***  ( http://www.logix4u.net/inpout32.htm )   ***/
/***                                            ***/
/*** Copyright (C) 2005, Douglas Beattie Jr.    ***/
/***                                            ***/
/***    <beattidp@ieee.org>                     ***/
/***    http://www.hytherion.com/beattidp/      ***/
/***                                            ***/
/**************************************************/
/*	Last Update: 2006.05.14
 */

/*******************************************************/
/*                                                     */
/*  Builds with Borland's Command-line C Compiler      */
/*    (free for public download from Borland.com, at   */
/*  http://www.borland.com/bcppbuilder/freecompiler )  */
/*                                                     */
/*   Compile with:                                     */
/*                                                     */
/*   BCC32 -IC:\BORLAND\BCC55\INCLUDE  TEST2.C         */
/*                                                     */
/*                                                     */
/*  Be sure to change PPORT_BASE (Port Base address)   */
/*  accordingly if your LPT port is addressed          */
/*  elsewhere.                                         */
/*                                                     */
/*******************************************************/


#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <memory.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
/* Definitions in the build of inpout32.dll are:            */
/*   short _stdcall Inp32(short PortAddress);               */
/*   void _stdcall Out32(short PortAddress, short data);    */

/* prototype (function typedef) for DLL function Inp32: */

     typedef short (_stdcall *inpfuncPtr)(short portaddr);
     typedef void (_stdcall *oupfuncPtr)(short portaddr, char datum);

#define PPORT_BASE 0x378


// Prototypes for Test functions
void test_read8(void);
void test_write(void);
void test_write_datum(short datum);

#define BYTES_PER_LINE 32

typedef struct TGA_HEADER
{
   char  idlength;                // 0
   char  colourmaptype;           // 1
   char  datatypecode;            // 2
   char  pad[5];                  // 3
   short x_origin;                // 8
   short y_origin;                // 10
   short width;                   // 12
   short height;                  // 14
   char  bitsperpixel;            // 16
   char  imagedescriptor;         // 17
} TGA_HEADER;

TGA_HEADER header;

int LoadWidth()
{
	return header.width;
}

int LoadHeight()
{
	return header.height;
}

unsigned char *LoadTGA(char *name)
{
	FILE *f;
	unsigned char *data, *p;

	f = fopen(name, "rb");
	printf("here\n");
	if (!f)
		return 0;
	fread(&header, sizeof(TGA_HEADER), 1, f);
	printf("tga %d %d %d\n", header.width, header.height, header.bitsperpixel);
	printf("here2\n");

	p = data = (unsigned char *)malloc(header.width * header.height * header.bitsperpixel);
	if (!data)
		return 0;

	for (int y=header.height-1; y>=0; y--)
  {
    p = data + (y * (int)header.width * 4);

		for (int x=0; x<header.width; x++)
		{
			if (header.bitsperpixel == 32)
			{
				fread(p, 1, 1, f);
				p++;
				fread(p, 1, 1, f);
				p++;
				fread(p, 1, 1, f);
				p++;
				fread(p, 1, 1, f);
				p++;
			}
			else if (header.bitsperpixel == 24)
			{
				fread(p, 1, 1, f);
				p++;
				fread(p, 1, 1, f);
				p++;
				fread(p, 1, 1, f);
				p++;
				*p++ = 0xff;
			}
		}
  }
	printf("here3\n");

	return data;
}


/* After successful initialization, these 2 variables
   will contain function pointers.
 */
     inpfuncPtr inp32fp;
     oupfuncPtr oup32fp;


/* Wrapper functions for the function pointers
    - call these functions to perform I/O.
 */
     short  Inp32 (short portaddr)
     {
          return (inp32fp)(portaddr);
     }

     void  Out32 (short portaddr, char datum)
     {
          (oup32fp)(portaddr,datum);
     }


int LoadImagetoPP(AnsiString fn,int numberofadres)
{
     HINSTANCE hLib;


	unsigned char *image;
	//unsigned int addr=0x300;

    unsigned int addr= 0x75300/2 * numberofadres;


// load image
	image = LoadTGA(fn.c_str());
	if (!image)
	{
		printf("couldn't load TGA %s\n", fn.c_str());
		exit(1);
	}

	if (LoadWidth() % BYTES_PER_LINE != 0)
	{
		printf("TGA width not multiple of %d\n", BYTES_PER_LINE);
		exit(1);
	}


     /* Load the library */
     hLib = LoadLibrary("inpout32.dll");

     if (hLib == NULL) {
          cout<<"LoadLibrary Failed."<<endl;
          return -1;
     }

     /* get the address of the function */

     inp32fp = (inpfuncPtr) GetProcAddress(hLib, "Inp32");

     if (inp32fp == NULL) {
          cout<<"GetProcAddress for Inp32 Failed."<<endl;
          return -1;
     }


     oup32fp = (oupfuncPtr) GetProcAddress(hLib, "Out32");

     if (oup32fp == NULL) {
          cout<<"GetProcAddress for Oup32 Failed"<<endl;
          return -1;
     }


/*******************************************************/
/** IF WE REACHED HERE, INITIALIZED SUCCESSFUL    ******/
/*******************************************************/


	unsigned int color;
	int	bcount=0;

short aa=1;
//FILE * fp=fopen("d.txt","r");
for (int y=0; y<600; y++)
		for (int x=0; x<800; x++)
		{
			
           unsigned char r, g, b, a;
			b = *image++;
			g = *image++;
			r = *image++;
			a = *image++;
#ifdef GRAYSCALE
      r = g = b = ((int)r + g + b) / 3;     // make image grayscale
#endif
			color = (((r >> 5) & 0x7) << 5) | (((g >> 6) & 0x3) << 3) | (((b >> 5) & 0x7) << 0);
		
	if ((bcount % BYTES_PER_LINE) == 0)
				{
                 short addr1;
                 addr1 = addr>>20;
                 addr1 = addr1<<2;
                 addr1= addr1|0xc3;
                 
                 short addr2;
                 addr2 = addr>>16;
                 addr2 = addr2 & 0xF;
                 addr2 = addr2<<2;
                 addr2= addr2|0xc3;
                 
                 short addr3;
                 addr3 = addr>>12;
                 addr3 = addr3 & 0xF;
                 addr3 = addr3<<2;
                 addr3= addr3|0xc3;
                 
                 short addr4;
                 addr4 = addr>>8;
                 addr4 = addr4 & 0xF;
                 addr4 = addr4<<2;
                 addr4= addr4|0xc3;
                 
                 short addr5;
                 addr5 = addr>>4;
                 addr5 = addr5 & 0xF;
                 addr5 = addr5<<2;
                 addr5= addr5|0xc3;
                 
                 short addr6;
                 addr6 = addr & 0xF;
                 addr6 = addr6<<2;
                 addr6= addr6|0xc3;
                 
                 Out32(PPORT_BASE,0xC2);
                 Out32(PPORT_BASE,0xc3);
                 Out32(PPORT_BASE,0xc3);
                 
                 Out32(PPORT_BASE,addr1);
                 addr1^=0x2;
                 Out32(PPORT_BASE,addr1);
                  
                 Out32(PPORT_BASE,0xc3);
                 Out32(PPORT_BASE,addr2);
                 addr2 ^= 0x2;                
                 Out32(PPORT_BASE,addr2);
                  
                 Out32(PPORT_BASE,0xc3);
                 Out32(PPORT_BASE,addr3);
                 addr3 ^= 0x2;                
                 Out32(PPORT_BASE,addr3);
 
                
                 
                 Out32(PPORT_BASE,0xc3);
                 Out32(PPORT_BASE,addr4);
                 addr4 ^= 0x2;                
                 Out32(PPORT_BASE,addr4);

                 
                 Out32(PPORT_BASE,0xc3);
                 Out32(PPORT_BASE,addr5);
                 addr5 ^= 0x2;                
                 Out32(PPORT_BASE,addr5);


                
                 Out32(PPORT_BASE,0xc3);
                 Out32(PPORT_BASE,addr6);
                 addr6 ^= 0x2;                
                 Out32(PPORT_BASE,addr6);
                 
                }
             
			short clr1 = color>>4;
			clr1 &=0xf;
			clr1 = clr1<<2;
			clr1 |= 0xc3;

		/*	short clr2= color>>8;
			clr2=clr2&0xF;
			clr2 = clr2<<2;
			clr2 |=0xc3;
            
            short clr3= color>>4;
			clr3=clr3&0xF;
			clr3 = clr3<<2;
			clr3 |=0xc3;
			
			*/
			short clr4=color&0xF;
			clr4 = clr4<<2;
			clr4 |=0xc3;
                //fscanf(fp,"%02x\n%02x\n%02x\n%02x\n",&clr1,&clr2,&clr3,&clr4);

            Out32(PPORT_BASE,0xc3);
			Out32(PPORT_BASE,0xcf);
			Out32(PPORT_BASE, clr1);
			Out32(PPORT_BASE,clr1^0x2);
/*
			Out32(PPORT_BASE,0xcf);
			Out32(PPORT_BASE, clr2);
			Out32(PPORT_BASE,clr2^0x2);
			
			Out32(PPORT_BASE,0xc3);
			Out32(PPORT_BASE,0xcf);
			Out32(PPORT_BASE, clr3);
			Out32(PPORT_BASE,clr3^0x2);*/
            
            Out32(PPORT_BASE,0xc3);
			Out32(PPORT_BASE,0xcf);
			Out32(PPORT_BASE, clr4);
			Out32(PPORT_BASE,clr4^0x2);
			/*Out32(PPORT_BASE,0xc3);
			Out32(PPORT_BASE,0xcf);
			Out32(PPORT_BASE, 0xfd);*/
			
            if ((bcount % BYTES_PER_LINE) == (BYTES_PER_LINE-1) )
			{
				
				addr += BYTES_PER_LINE/2;
				a=1;
			}
		    if(aa%2==0){
                        bcount++;
                        aa=1;
            }
            aa++;
			

			
		}
     /* finished - unload library and exit */
     FreeLibrary(hLib);
    
     //fclose(fp);
     return 0;
}


 
