program LCD2COE;

(* 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   lcdfilename,coefilename,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;

(* 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 lcdfil,coefil,tempfil    : text;
	val,valtemp:LongInt;
	line,col, count,charcode:Integer;
	instr, outstr:string;
	inchar:char;
	width,height:Integer;
begin
  assign(lcdfil,lcdfilename);
  {$I-} reset(lcdfil); {$I+}
  if ioresult<>0 then begin
    writeln('Error opening ',lcdfilename);
    halt;
  end;
  assign(tempfil,'~temp.txt');
  rewrite(tempfil);
  writeln('Converting ',lcdfilename, ' to ', coefilename);
  while not eof(lcdfil) do begin
    read(lcdfil,inchar);
    if (inchar='"') or (inchar=',') then inchar:=char(13);
    if (inchar<>' ') and (inchar<>char(10)) and (inchar<>'<')
    	and (inchar<>'>') and (inchar<>'/') and (inchar<>'=')
    	then write(tempfil,inchar);
  end;
  close(lcdfil);

	reset(tempfil);
	assign(coefil,coefilename);
	rewrite(coefil);

{### Header suchen ###}
	repeat
    	readln(tempfil,instr);
    until instr='FONTSIZEWIDTH';
	readln(tempfil,width);
	writeln('Char width: ',width);
	repeat
		readln(tempfil,instr);
	until instr='HEIGHT';
	readln(tempfil,height);
	writeln('Char height: ', height);
	writeln('Processing charcode:');

	writeln(coefil,'; Created by LCD2COE (c) cm@ct.de, LSBit first');
	writeln(coefil,'; CharHeight:',height:4,'  CharWidth:',width:4);
	writeln(coefil,'  memory_initialization_radix  = 16;');
	writeln(coefil,'  memory_initialization_vector =');

{### einzelne Bits lesen und zu Zeichen zusammenfügen ###}
	count:=0;
	repeat
		repeat
			readln(tempfil,instr);
			if (instr='FONT') or eof(tempfil) then
			{ Ende erreicht, Dateien schließen }
			begin
				writeln(coefil,'; end -- ',count,' chars processed');
				writeln; writeln('Total of ',count,' chars processed');
				close(tempfil);
				close(coefil);
				erase(tempfil);
				halt;
			end;
		until (instr='CHARCODE') or eof(tempfil);
		readln(tempfil,charcode);
		write(charcode:4);
		{Bit- und Byte-Arrays nullen}
		for col:=0 to 31 do begin
			for line:=0 to 63 do begin
		 		bitarray[line,col]:=false;
			end;
		end;
		repeat
			readln(tempfil,instr);
		until (instr='PIXELS') or eof(tempfil);
		for col:=0 to width-1 do begin
			for line:=0 to height-1 do begin
		 		readln(tempfil,val);
		 		if val=0 then bitarray[line,col]:=true
		 			else bitarray[line,col]:=false;
			end;
		end;
		{Array umstellen}
		for line:=0 to height-1 do begin
			val:=0;
			valtemp:=1;
			for col:=0 to width-1 do begin
				if bitarray[line,col]=true then begin
					val:=val or (valtemp shl col);
				end;
			end;
			writeln(coefil,int2Hex(val));
		end;
		inc(count);
		writeln(coefil);
	until (instr='FONT') or eof(tempfil);
	writeln(coefil,'; end -- ',count,' chars processed');
	writeln; writeln('Total of ',count,' chars processed');
	close(tempfil);
	close(coefil);
	erase(tempfil);
end;


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

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

