
#include <stdio.h>
#include "ack3d.h"
#include "ackext.h"

extern unsigned char *ScreenBuffer;
extern int VidRow[];

#define SCREEN_HEIGHT 200
#define SCREEN_WIDTH  320

long read_clock()
{
	return 0;
}

void port_out( int value, int port )
{
	__asm__ volatile ("outb %0,%1"
	: : "a" ((unsigned char)value), "d" ((unsigned short)port));
}

void port_outw( int value, int port ) {
	__asm__ volatile("outw %0,%1"
	: : "a" ((unsigned short)value), "d" ((unsigned short)port));
}

int port_in( int port )
{
	unsigned char value;
	__asm__ volatile ("inb %1,%0"
		: "=a" (value)
		: "d" ((unsigned short)port));
	return value;
}

/*============================================================================
 void graphinit(int width,int psize,int mask)
   width - width of the screen in bytes/plane (defaults to 320/4 if 0)
   psize - size of each page in bytes/plane (defaults to 320*200/4 if 0)
============================================================================*/

void graphinit(int mode)
{
	if (mode == 0)
		vga_setmode(G320x200x256);
	else
		vga_setmode(G320x240x256);
}

/*==============================================================================
 void SetVGAmode(void);
==============================================================================*/

void SetVGAmode(void)
{
	graphinit(0);
}

/*==============================================================================
 void SetPalette(unsigned char *PalBuf);
==============================================================================*/
void SetPalette(unsigned char *PalBuf)
{
int i;
unsigned char *p;

	for (i = 0, p = PalBuf; i < 256; i++, p += 3)
		vga_setpalette(i, *p, *(p+1), *(p+2));
}

/* bangs ScreenBuffer to the screen
 * (nothing to do with page flipping at all!)
 */
void flippage()
{

	memcpy(graph_mem, ScreenBuffer, 64000);
}

/*==============================================================================
 void DrawWalls(void);
==============================================================================*/

void DrawWalls(void)
{
int vcol;
int av,boff,av_low,av_high;
int y1,y2;
WALLARRAY *walls_array_ptr;
unsigned char *bitmap_ptr,*scrnbuf_ptr;
int height,halfscrnsiz;


	halfscrnsiz=(SCREEN_HEIGHT>>1)*SCREEN_WIDTH;

	/* fill top half of 'ScreenBuffer' (top 100 lines) with TopColor here */
	memset(ScreenBuffer,TopColor,halfscrnsiz);

	/* and fill bottom half with BottomColor here */
	memset(ScreenBuffer+halfscrnsiz,BottomColor,halfscrnsiz);


	walls_array_ptr=Walls;

	for (vcol = 0; vcol < SCREEN_WIDTH; vcol++) {
  		bitmap_ptr = bMaps[walls_array_ptr->Number]+((walls_array_ptr->Column)<<6);
  		height = DistanceTable[walls_array_ptr->Distance];
  		y1 = CenterRow - (height>>1);
  		y2 = y1+height;
  		if (y2 > SCREEN_HEIGHT-1) y2 = SCREEN_HEIGHT-1;

  		av = AdjustTable[walls_array_ptr->Distance];
  		scrnbuf_ptr = ScreenBuffer + vcol;
  		boff = 0;
 
  		/* they claimed this was y1>y2, the code actually did a '>='...
  		 * the sense of the '>=' is reversed below to '<' as it's an 'if' not
  		 * an 'if not'.
  		 */
  		if (y1 < y2) {
    			av_low = av & 0xFFFF;
    			av_high = (av>>16);

    			if (y1>0)
    			  	scrnbuf_ptr += VidRow[y1];

    			do {
      				if (y1 >= 0) {
        				*scrnbuf_ptr=*bitmap_ptr; /* sbptr = di, bmptr = si */
        				scrnbuf_ptr+=SCREEN_WIDTH;	/* next screen row */
        			}

      				boff += av_low;
      				bitmap_ptr += av_high;
      				if (boff > 0xFFFF) {
        				boff &= 0xFFFF;
        				bitmap_ptr++;
        			}
      			} while(++y1<y2);
    		}
    
  		walls_array_ptr++;
  	}
}	/* the end! */



void DrawOneObject(int ObjNum,int ObjCol,int ObjDist,int VidCol,int PageNum)
{
int height,av,y1,y2,boff;
int av_low,av_high;
unsigned char *bitmap_ptr,*scrnbuf_ptr;

	height = DistanceTable[ObjDist];
	y1 = CenterRow - (height>>1);
	y2 = y1 + height;
	if (y2 > SCREEN_HEIGHT-1) 
		y2 = SCREEN_HEIGHT-1;

	av = AdjustTable[ObjDist];

	bitmap_ptr = oMaps[ObjNum]+(ObjCol<<6);
	scrnbuf_ptr = ScreenBuffer+VidCol;
	boff = 0;

	if(y1>0)
	  	scrnbuf_ptr+=VidRow[y1]; /* XXX if VidRow[] is an array that goes 0,
  				 	  * 320, 640, etc. change to:
                                 	  * 'scrnbuf_ptr+=VidRow[y1];'
  				 	  */

	if(y1<y2) {
  		av_low=av&0xFFFF;
  		av_high=(av>>16);

  		do {
    			if(y1>=0) {
      				if(*bitmap_ptr!=0)
        				*scrnbuf_ptr=*bitmap_ptr;
      				scrnbuf_ptr+=SCREEN_WIDTH;
      			}
	
    			boff+=av_low;
    			bitmap_ptr+=av_high;
    			if(boff>0xFFFF) {
      				boff&=0xFFFF;
      				bitmap_ptr++;
      			}
    		} while(++y1<y2);
  	}
}

