{$ifndef unix}
{$A+,B-,D+,E+,F-,G+,I+,L+,N+,O-,P+,Q-,R-,S+,T-,V-,X+,Y+}
{$else}
{$B-,I+,S-,T-,X+}
{$endif}
unit xcrt;

interface

var
	wherex,
	wherey,
	textattr:byte;
	windmin,
	windmax:word(16);
	directvideo:boolean;
const
	co80=3;
	bw80=2;
	co40=1;
	bw40=0;
	maxlongint=$7fffffff;

procedure gotoxy(x,y:byte);
procedure clreol;
procedure Clearscreen(color:byte);

procedure textmode(m:byte);
procedure SetVideoMode(Mode:Word);

procedure sound(hz:word);
procedure nosound;
procedure delay(ms:word);

function keypressed:boolean;
function readkey:char;

(* --- X-functions --- *)
type
	Font_t =record
		d:^byte;
		size:integer(32);
	end;

	rect=record
		x1,y1,x2,y2:longint;
	end;
	
	ainteger=array[0..0] of word(32);
	aword=array[0..0] of word(16);
	abyte=array[0..0] of byte;
	
	XImage_t=record
		width,
		height,
		xoffset,
		format			:word(32);
		data			:^abyte;
		byte_order,
		bitmap_unit,
		bitmap_bit_order,
		bitmap_pad,
		depth,
		bytes_per_line,
		bits_per_pixel,
		red_mask,
		green_mask,
		blue_mask		:word(32);
	end;

	XData_t=record
		image			:^XImage_t;
		font			:Font_t;
		bg: record case byte of
			0:(x32		:^ainteger);
			1:(x16		:^aword);
			2:(x8		:^abyte);
		end;
		bg_size,
		bytes_per_line,
		depth,
		kbscan,
		kbstate,
		kbkeycode,
		kbscancode,
		mx,
		my,
		mb				:word(32);
		update			:rect;
		active			:byte;
	end;
	
	pchar=^char;

var
	X:XData_t;external;
	mousemode:integer;external;
	XFont_8x8:pointer;external;
	XFont_8x14:pointer;external;
	XFont_8x16:pointer;external;

	gwriteca:procedure(c:char; a:byte; x, y:integer);
	gwritecan:procedure(c:char; a:byte; n, x, y:integer);
	gwritesa:procedure(l:integer;s:pchar; a:byte; x, y:integer);
	plot:procedure(x,y:integer;a:byte);
	hline:procedure(x1,x2,y: Word; Color: Byte);
	vline:procedure(x,y1,y2: Word; Color, page: Byte);
	Xplotline8:procedure(ox,xx,oy:word; b:pointer);
	Xplotline2_8:procedure(ox,xx,oy:word; b:pointer);
	Xfrect8:procedure(x1,y1,x2,y2:integer; a:byte);

function Xinit(xx,y:integer):boolean;

procedure Xdone;
asmname 'Xdone';

function Xsetmouse(mouse:integer):integer;
asmname 'Xsetmouse';

procedure Xupdate(x, y:integer);
asmname 'Xupdate';

procedure Xupdate2(x, y, x2, y2:integer);
asmname 'Xupdate2';

procedure XSetColorBlock(firstreg,anz:word;var Colortable);
asmname 'XSetColorBlock';

procedure writeca(c:char;attr,n,page:byte);
PROCEDURE  WriteChar(c: Char; x,y: Word; ForeColor, BackColor: Byte);

implementation

{$L xgraphic.c}

uses
	vbios,
	rom8x8,
	rom8x14,
	rom8x16;

function XinitC(x,y:integer):boolean;
asmname 'XinitC';

procedure Xwriteca4_32(c:char; a:byte; x, y:integer);
asmname 'Xwriteca4_32';

procedure Xwritecan7_32(c:char; a:byte; n, x, y:integer);
asmname 'Xwritecan7_32';

procedure Xwritesa4_32(l:integer;s:pchar; a:byte; x, y:integer);
asmname 'Xwritesa4_32';

procedure Xdelay(ms:integer);
asmname 'Xdelay';

function Xreadkey:char;
asmname 'Xreadkey';

function Xkeypressed:boolean;
asmname 'Xkeypressed';

procedure Xplot8_32(x,y:integer;a:byte);
asmname 'Xplot8_32';

procedure Xhline8_32(x1,x2,y: Word; Color: Byte);
asmname 'Xhline8_32';

procedure Xvline8_32(x,y1,y2: Word; Color, logic: Byte);
asmname 'Xvline8_32';

procedure Xplotline8_32(ox,xx,oy:word; b:pointer);
asmname 'Xplotline8_32';

procedure Xplotline2_8_32(ox,xx,oy:word; b:pointer);
asmname 'Xplotline2_8_32';

procedure Xfrect8_32(x1,y1,x2,y2:integer; a:byte);
asmname 'Xfrect8_32';
                
function Xinit(xx,y:integer):boolean;
var
	b:boolean;
begin
	b:=XinitC(xx,y);
	case X.image^.bits_per_pixel of
		32:begin
			gwriteca:=Xwriteca4_32;
			gwritecan:=Xwritecan7_32;
			gwritesa:=Xwritesa4_32;
			plot:=Xplot8_32;
			hline:=Xhline8_32;
			vline:=Xvline8_32;
			Xplotline8:=Xplotline8_32;
			Xplotline2_8:=Xplotline2_8_32;
			Xfrect8:=Xfrect8_32;
		end;
	end;
	Xinit:=b;
end;

procedure gotoxy(x,y:byte);
begin
	wherex:=x;
	wherey:=y;
	setcursorxy(windmin and $ff + x-1, windmin shr 8+y-1,0);
end;

procedure writeca(c:char;attr,n,page:byte);
var
	i:integer;
begin
	gwritecan(c,attr,n,cursorpos[0].x*8,cursorpos[0].y*(CharSize+1));
end;

PROCEDURE  WriteChar(c: Char; x,y: Word; ForeColor, BackColor: Byte);
begin
	gwriteca(c,BackColor shl 4 or ForeColor,x,y);
end;

procedure clreol;
begin
{fixme}
end;

procedure Clearscreen(color:byte);
begin
	Xfrect8(0,0,X.image^.width-1,X.image^.height-1,color);
end;

procedure sound(hz:word);
begin
{fixme}
end;

procedure nosound;
begin
{fixme}
end;

procedure delay(ms:word);
begin
	Xdelay(ms);
end;

function keypressed:boolean;
begin
	keypressed:=Xkeypressed;
end;

function readkey:char;
begin
	readkey:=Xreadkey;
end;

procedure textmode(m:byte);
begin
	setvideomode(m);
end;

procedure SetVideoMode(Mode:Word);
var
 keep:boolean;
begin
	keep:=mode and $80 <> 0;
	case mode of
		0,1:;
		2,3,7:;
		4:;
		5:;
		6:;
		$D:;
		$e:;
		$f:;
		$10:;
		$11:;
		$12:begin
			if (videomode<>$12) or not keep then begin
				if not xinit(640,480) then halt;
			end;
			X.font.d:=@Font_Rom8x16;
			X.font.size:=16;
			Charsize:=15;
		end;
		$13:;
	else
		Xdone;
	end;
	videomode:=mode;
	windmin:=0;
	windmax:=24*256+79;
	gotoxy(1,1);
end;

begin
	windmin:=0;
	windmax:=24*256+79;
	gotoxy(1,1);
	gwriteca:=Xwriteca4_32;
	gwritecan:=Xwritecan7_32;
	gwritesa:=Xwritesa4_32;
	plot:=Xplot8_32;
	hline:=Xhline8_32;
	vline:=Xvline8_32;
	XFont_8x8:=@Font_Rom8x8;
	XFont_8x14:=@Font_Rom8x14;
	XFont_8x16:=@Font_Rom8x16;
	X.font.d:=@Font_Rom8x16;
	X.font.size:=16;
	Charsize:=15;
end.
