program COE2LCD;

(* GLCD Font Converter für COE-Coregenerator Files  *)
(* für Borland Pascal 7, von C. Meyer 6/2010 (!)    *)

{$R-} (* Array-Bereichs-Check ausschalten! *)

uses  dos;


var   COEfilename,LCDfilename,filext : string;
	bitarray:array[0..63,0..31] of boolean; {line,col}
	pixelarray3,pixelarray2,pixelarray1,pixelarray0:array[0..63] of byte;
	pixelarray:array[0..63] of LongInt;
  radix:Integer;
(* Untersuchen eines Dateinamens auf Angabe einer extension,   *)
(* gefundene extension wird (Upcase) in FILEXT gespeichert.    *)

function hasextension(s:string):boolean;
var i,j : integer;
begin
  hasextension:=false;
  filext:='';
  for i:=length(s) downto 2 do begin
    if s[i]='.' then begin
      hasextension:=true;
      filext:=copy(s,succ(i),255);
      for j:=1 to length(filext) do
        filext[j]:=upcase(filext[j]);
      exit;
      end;
    end;
  end;

function extractfilename(s:string):string;
var j : integer;
begin
  j:=pos('.',s);
  extractfilename:=copy(s,0,j-1);
end;

function int2hex(intval:LongInt):string;
var HexStr:String;
  digit:byte;
begin
  HexStr:='';
  repeat
    digit:=intval mod 16;
    intval:=intval div 16;
    If digit<10 then HexStr:=Chr(Digit+ord('0'))+HexStr;
    If digit>=10 then HexStr:=Chr(Digit-10+ord('A'))+HexStr;
  until intval=0;
  int2Hex:=HexStr;
end;

function hex2int(HexStr:String):LongInt;
var
  digit:byte;
  tempStr:String;
  x : longint;
  converr: Integer;
begin
	if HexStr[1]<>'$' then
  	tempStr:='$'+HexStr
  else tempStr:=HexStr;
  val(tempStr,x,converr);
  hex2int:=x;
  if converr <> 0 then
  begin
    writeln('Error at value ',tempStr);
    halt;
  end;
end;

(*---------------------- CONVERSION --------------------------*)

procedure gettxtfile;
var COEfil,LCDfil,tempfil    : text;
	count,value:LongInt;
	line,col, charcode:Integer;
	instr, outstr:string;
	inchar,lastchar:char;
	i,n,width,height,start,numchars:Integer;
begin
  assign(COEfil,COEfilename);
  lastchar:=char(13);
  {$I-}
  reset(COEfil);
  {$I+}
  if ioresult<>0 then begin
    writeln('Error opening ',COEfilename);
    halt;
  end;
{ test anlegen }
  assign(tempfil,'~temp.txt');
  rewrite(tempfil);
  writeln('Converting ',COEfilename, ' to ', LCDfilename);
  while not eof(COEfil) do begin
    read(COEfil,inchar);
    if (inchar<>' ') and (inchar<>char(10)) then begin
    	if inchar='=' then inchar:=char(13);
    	if inchar=';' then { ### Kommentare überspringen ### }
    	repeat
        read(COEfil,inchar);
    	until (inchar<' ') or eof(COEfil);
			if not((lastchar<' ') and (inchar<' ')) then
    	  write(tempfil,inchar);
    end;
    lastchar:=inchar;
  end;
  close(COEfil);

	reset(tempfil);
	repeat
		readln(tempfil,instr);
	until instr='memory_initialization_vector';
	count:=0;
	repeat
		readln(tempfil,instr);
		inc(count);
	until (instr='') or eof(tempfil);
	writeln(count,' entries found');
	write('Enter pixel width: ');
	readln(width);
	write('Enter pixel heigth: ');
	readln(height);
	write('Enter range start char number: ');
	readln(start);
	numchars:=count div height;
	writeln('Number of chars is: ',numchars);

	assign(LCDfil,LCDfilename);
	rewrite(LCDfil);
	reset(tempfil);

{### Header suchen ###}
	repeat
    readln(tempfil,instr);
  until instr='memory_initialization_radix';
	readln(tempfil,radix);
	writeln('Char width: ',width);
	repeat
		readln(tempfil,instr);
	until instr='memory_initialization_vector';

	writeln(LCDfil,'<?xml version="1.0" encoding="iso-8859-1"?>');
	writeln(LCDfil,'<FONT>');
	writeln(LCDfil,'     <FONTNAME>Converted_',width,'x',height,'</FONTNAME>');
	writeln(LCDfil,'     <FONTSIZE WIDTH="',width,'" HEIGHT="',height,'" PROPORTIONAL="0" FONTKIND="0"/>');
	writeln(LCDfil,'     <RANGE FROM="',start,'" TO="',start+numchars-1,'"/>');
	writeln(LCDfil,'     <CHARS>');

{### einzelne Bits lesen und zu Zeichen zusammenfügen ###}
	count:=0;
	for n:=0 to numchars-1 do begin
		for i:=0 to height-1 do begin
			value:=0;
			if (radix=10) and not eof(tempfil) then readln(tempfil,value)
			else begin
				instr:='';
				if not eof(tempfil) then readln(tempfil,instr);
				value:=hex2int(instr);
			end;
			pixelarray[i]:=value;
		end;
		{Bit-Arrays füllen}
		for line:=0 to height-1 do begin
		  value:=pixelarray[line];
			for col:=0 to width-1 do begin
		 		if value and 1 = 1 then	bitarray[line,col]:=true
		 		else bitarray[line,col]:=false;
		 		value:=value shr 1;
			end;
		end;
		write(LCDfil, '          <CHAR CODE="', start+n,'" PIXELS="');
		for col:=0 to width-1 do begin
			for line:=0 to height-1 do begin
		 		if bitarray[line,col] then value:=0 else value:=16777215;
		 		write(LCDfil,value);
		 		inc(count);
				if (line=height-1) and (col=width-1) then writeln(LCDfil,'"/>') else write(LCDfil,',')
			end;
		end;
	end;
  writeln(LCDfil,'     </CHARS>');
	writeln(LCDfil,'</FONT>');
	writeln; writeln('Total of ',count,' pixels processed');
	writeln('Use "batch/mirror all chars" in GLCD if wrong alignment');
	close(tempfil);
	close(LCDfil);
	erase(tempfil);
end;


(*---------------------------- MAIN ---------------------------*)

begin
  writeln('COE to LCD Converter, cm@ct.de 06/2010');
  writeln('produces GLCD Font Creator XML file (.LCD) from Xilinx CoreGen (.COE) file');
  writeln('with LSBit left, horizontal aligned, max. 32 pixel width, 63 pixel height');
  if paramcount>0 then COEfilename:=paramstr(1) else begin
    write('COE file (Default: *.COE): ');
    readln(COEfilename);
    if COEfilename='' then begin
		writeln('Usage: COE2LCD <fontrom.COE>');
    	halt;
    	end;
    end;
  if hasextension(COEfilename) then
    begin
      LCDfilename:=extractfilename(COEfilename)+'.LCD';
      gettxtfile;
    end
  else
  begin
    LCDfilename:=COEfilename+'.LCD';
    COEfilename:=COEfilename+'.COE';
    gettxtfile;
  end;
  halt;
end.

