{$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,P-,Q-,R-,S-,T-,V-,X+}
{$M 16384,0,0}
program vtg2;
{ $define arabic}
{$define Fiedel}
Uses Objects,Drivers,Dos,NewCRT,Strings;
var
TextAttr:Byte;
sstr,filename:PathStr;
Timer: word absolute $40:$6c;
type
tPage=array[0..$3ff] of byte; {40*24+10+14 = 1 KByte}
int=integer;
void=int;
numstr=array[0..3] of char; {von wegen Hexzahlen}
const
OldButtons:word=0;
INDIZES=2048;
{$ifdef Fiedel}
MAGIC=$e6e8d4d6;
INDEXPP=249; {Indexeinträge pro führender Index-Seite}
{$else}
MAGIC=$f3e8d4d6;
INDEXPP=255;
{$endif}
{MAGIC=Longint('fhTV') or $80808080; Intelnotation}
type
tView=object (tRect)
procedure MouseHide;
procedure WriteBuf(x,y,br,h:Integer; Buf:Pointer);
end;
procedure tView.MouseHide; assembler;
asm
les bx,[self]
mov al,es:[bx]
dec al
mov ah,8
mul ah
mov cx,ax
mov al,es:[bx+2]
dec al
mov ah,FONTH
mul ah
mov dx,ax
mov al,es:[bx+4]
inc al
mov ah,8
mul ah
mov si,ax
mov al,es:[bx+6]
inc al
mov ah,FONTH
mul ah
mov di,ax
mov ax,10h
int 33h
end;
procedure tView.WriteBuf;
var Zeile,Spalte:Int;
ch:Char; attr:Byte;
begin
for Zeile:=y to y+h-1 do
for Spalte:=x to x+br-1 do begin
ch:=Char(Buf^); Inc(Word(Buf));
attr:=Byte(Buf^); Inc(Word(Buf));
WriteChar(ch,attr,Spalte,Zeile);
end;
end;
type
tVPage=object (tView)
procedure DisplayPage(var Page:tPage;FlagPar:Byte);
function videotreffer(var Page:tPage; var i:int; var event:tevent):boolean;
end;
tButton=object (tView)
Schrift: String;
hot:Char;
constructor Init(s:String;x,y:Byte;hotkey:char);
function Treffer(Event:tEvent):Boolean;
destructor done;
end;
var
i,j,k: int;
p: pointer;
posx,posy,farb: byte;
Event:tEvent;
ch:char;
constructor tButton.Init;
var
i,j:byte;
buf:array[0..39] of word;
begin
Assign(x,y,x+1+CStrLen(s),y+2);
MouseHide;
WriteChar('┌',$f0,a.x,a.y);
WriteChar('┐',$f0,b.x,a.y);
WriteChar('└',$f0,a.x,b.y);
WriteChar('┘',$f0,b.x,b.y);
WriteChar('│',$f0,a.x,a.y+1);
WriteChar('│',$f0,b.x,a.y+1);
for i:=a.x+1 to b.x-1 do begin
WriteChar('─',$f0,i,a.y);
WriteChar('─',$f0,i,b.y);
end;
MoveCStr(buf,s,$f4f0);
WriteBuf(a.x+1,a.y+1,CStrLen(s),1,@buf);
{ WrStr(s,$f0,a.x+1,a.y+1);
WriteChar(hotkey,$f4,xa+pos(hotkey,s),ya+1);}
hot:=hotkey;
showmouse;
end;
destructor tButton.Done;
var
i,j:byte;
s:string;
begin
MouseHide;
s:='';
for i:=a.x to b.x do s:=s+' ';
for i:=a.y to b.y do
WrStr(s,$71,a.x,i);
ShowMouse;
end;
var
button1,button2,button3,button4,buttonU,buttonS:tButton;
buttonplus,buttonminus,buttonnext,ButtonRight,ButtonDouble:tButton;
subpagelist:string[80];
VPage:tVPage;
const
maxhist=9;
historystack: array[0..maxhist] of word=
($100,$100,$100,$100,$100,$100,$100,$100,$100,$100);
procedure puthistory(w:word);
var
i:integer;
begin
for i:=0 to maxhist-1 do historystack[i]:=historystack[i+1];
historystack[maxhist]:=w;
end;
function gethistory:word;
var
i:integer;
begin
gethistory:=historystack[MAXHIST];
for i:=maxhist-1 downto 0 do historystack[i+1]:=historystack[i];
historystack[0]:=$100;
end;
function BCD2Hex(B:Byte):Byte;
begin
BCD2Hex:=(B shr 4)*10 + (B and $f);
end;
function Hex2BCD(B:Byte):Byte;
begin
Hex2BCD:=(B div 10) shl 4 + (B mod 10);
end;
function tButton.Treffer;
var
i,j:Byte;
begin
case Event.What of
evKeyDown:
if UpCase(Event.CharCode)=UpCase(Hot) then begin
Event.What:=0; Treffer:=true; exit;
end;
evMouseDown:
if Contains(Event.Where) then begin
Event.What:=0; Treffer:=true; exit;
end;
end;
treffer:=false;
end;
const
pfad:pathstr='';
Type
pLine=^tLine;
tLine=array[0..39] of byte;
pPage=^tPage;
tIdx=record
pag,sub:word;
end;
var
vtf: TDosStream;
Index: array[0..INDIZES] of tIdx;
IndexCnt: word;
var
Page:tPage;
function CctChr(grafikflag:boolean; code:byte):char;
begin
CctChr:= Chr(Code);
if Code<$20 then cctchr:=' ' else
if grafikflag then begin
case code of
$20..$3f:cctchr:=Chr(code-$20);
$60..$7f:cctchr:=Chr(code+$40);
end {case}
end {grafikflag}
end;{cctchr}
procedure DisplayLine(p:pointer;x,y:Byte;var FlagPar:byte); {FlagPar-Rückgabe}
const
flashtime:boolean=true;
colormap:array[0..7]of byte=(0,$c,$a,$e,9,$d,$b,$f);
var
spalte,byteein,byteold:byte;
FlagReg:Byte;
{0:blinkflag,1:dblheigth (Flag Doppelte Höhe),
2:inbox (Flag für innerhalb einer Box), 3:shift (z.Z. nicht benutzt),
4:secret (Textfreigabe durch Quiztaste), 5:separated (gebrochene Grafik),
6:holdgrafix (bei Farbwechsel Wdh. letzte Grafik), 7:grafikflag (Grafikmode)}
{FlagPar:
0:blinkbit, 1:Zeilen ohne Blinken ignorieren,
2:Mix-Betrieb, 3:??,
4:Quiz-Bit, 5:Zeilen ohne Quiz ignorieren,
6:Doppelte Höhe vorhanden (intern), 7:Doppelte Höhe verboten (=ignorieren)}
procedure PutCctChr(ByteEin:byte);
begin
PutMode:=0;
if (FlagPar and $4 >0) and (FlagReg and $4 =0) then begin
PutMode:= $10; {transparent}
end;
PutMode:= PutMode or FlagReg and 2;
if (PutMode and 2 =0) then Inc(PutMode);
if (FlagReg and $80 >0) then
case (ByteEin and not $40) of
$20..$3f: PutMode:=PutMode or (FlagReg and $20);
end;
{$ifdef arabic}
WriteChar(Char(ByteEin),7,spalte+x,y);
{$else}
if ((FlagReg and 1 =0) or (FlagPar and 1 >0)) {Blinkbit}
and ((FlagReg and $10 =0) or (FlagPar and $10 >0)) then begin {Secret-Bit}
if (FlagReg and $80 >0) then
case ByteEin of
$20..$3f:ByteEin:=ByteEin-$20;
$60..$7f:ByteEin:=ByteEin+$40;
end {case}
end else ByteEin:=$20;
WriteChar(Char(ByteEin),TextAttr,spalte+x,y);
{$endif}
if (FlagPar and $40 >0) and (FlagReg and 2 =0) then {Doppelte Höhe}
WriteChar(' ',TextAttr,spalte+x,y+1); {Zeile darunter auch}
end; {PutCCTChr}
function SContains(p:pointer;b:byte):boolean; assembler;
asm
cld
les di,p
mov al,b
mov cx,40
repne scasb
mov al,false
jnz @@e
mov al,true
@@e:
end;
begin
{Notwendigkeit des Redraws feststellen}
if (FlagPar and $22 =0) or
((FlagPar and 2 >0) and Scontains(p,8)) or
((FlagPar and $20 >0) and Scontains(p,24)) then begin
CurFont:=@norm8x10;
PutMode:=1;
if (FlagPar and 4 >0) then
Wrstr('▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒',$71,x,y);
if (FlagPar and $80 =0) and (Scontains(p,13)) then begin
FlagPar:=FlagPar or $40; {Doppelte Höhe vorhanden}
if (FlagPar and 4 >0) then
Wrstr('▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒',$71,x,y+1);
end;
CurFont:=@tele8x10;
TextAttr:=$f; {Weiß auf Schwarz}
FlagReg:=0; {alle Flags aus}
for Spalte:=0 to 39 do begin
byteein:=byte(p^); Inc(Word(p));
case ByteEin of
28:TextAttr:=TextAttr and $f; {Hintergrund schwarz}
29:TextAttr:=TextAttr and $f or ((TextAttr shl 4) and $f0);
{Nibble doppeln}
end;
if (ByteEin<$20) then begin
if (FlagReg and $c0 =$c0) and {HoldGrafix und GrafikFlag}
((ByteOld and not $40 >=$20) and (ByteOld and not $40 <$40))
then PutCCTChr(ByteOld)
else PutCCTChr({$ifdef arabic} ByteEin {$else}$20{$endif});
end else begin
PutCCTChr(ByteEin);
ByteOld:=ByteEin;
end;
case ByteEin of
0..7,16..23: TextAttr:=TextAttr and $f0 or ColorMap[ByteEin and 7];
end;
if (ByteEin<$20) then
FlagReg:= FlagReg and not $10; {Secret aus}
case ByteEin of
0..7:FlagReg:= FlagReg and not $80;{Grafikflag aus}
{$ifndef arabic}
8: FlagReg:= FlagReg or 1; {Blinken ein}
9: FlagReg:= FlagReg and not 1; {Blinken aus}
10: FlagReg:= FlagReg and not 4; {InBox aus}
11: FlagReg:= FlagReg or 4; {InBox ein}
12: FlagReg:= FlagReg and not 2; {DoubleHeigth aus}
13: if (FlagPar and $80 =0) then {wenn nicht verboten}
FlagReg:= FlagReg or 2; {DoubleHeigth ein}
14: FlagReg:= FlagReg and not 8; {Shift aus (später verwendet)}
15: FlagReg:= FlagReg or 8; {Shift ein (später verwendet)}
16..23: FlagReg:= FlagReg or $80; {Grafikflag ein}
24: FlagReg:= FlagReg or $10; {Secret ein}
25: FlagReg:= FlagReg and not $20;{separated aus}
26: FlagReg:= FlagReg or $20; {separated ein}
30: FlagReg:= FlagReg or $40; {holdgrafix ein}
31: FlagReg:= FlagReg and not $40;{holdgrafix aus}
{$endif}
end; {case}
end; {1 Zeile}
if (FlagPar and 4 =0) then begin
writechar(' ',0,x+40,y);
if (FlagPar and $40 >0) then
writechar(' ',0,x+40,y+1);
end;
end; {if}
end;
const FlagPar:Byte=$01;
type
tHeader=record
Pag,Sub,C:Word;
HamErrs:Byte
end;
function FormatS(const fs:string;p4,p3,p2,p1:LongInt): string; assembler;
asm
les si,@result; push es; push si
les si,fs; push es; push si
lea si,p1; push ss; push si
call FormatStr
end;
function PagStr(I:tHeader):String;
var
s: string[5]; {Vorgabe-String}
begin
s:='%x'; if I.Sub<>0 then s:='%x/%x';
if I.Pag<$100 then I.Pag:=I.Pag+$800;
PagStr:=FormatS(s,0,0,I.Sub,I.Pag);
end;
procedure tVPage.DisplayPage(var Page:tPage;FlagPar:byte);
{ Gibt eine Teletextseite (seitenr) aus dem PC-RAM am Bildschirm aus }
var
Zeile: Byte;
Header: tHeader;
SaveHeader: tHeader absolute Page;
FlagSave: Byte;
NewHeader: String[7];
begin
FlagSave:=FlagPar and $80;
Header:=SaveHeader;
NewHeader:=FormatS('%c%03x/%02x',
0,Header.Sub and $ff,Header.Pag,Page[25*40+11]+Ord('P'));
if NewHeader[1]='0' then NewHeader[2]:='8';
System.Move(NewHeader[1],SaveHeader,7);
MouseHide;
FlagPar:=FlagPar and not $c0;
if (Header.C and $60)<>0 then
FlagPar:=FlagPar or 4; {Untertitel oder Schlagzeile}
for Zeile:=0 to {$ifdef arabic} 25 {$else} 24 {$endif} do begin
if FlagSave=0 then FlagPar:=FlagPar and not $80;
if (Zeile=0) or (Zeile=24) then
FlagPar:=FlagPar or $80;
if (FlagPar and $40 =0) then
DisplayLine(@Page[Zeile*40],a.x,a.y+Zeile,FlagPar)
else
FlagPar:=FlagPar and not $40;
end;
ShowMouse;
PutMode:=1;
SaveHeader:=Header;
end; {DisplayPage}
function tVPage.videotreffer(var Page:tPage; var i:int; var event:tevent):boolean;
var
Envir:array[0..4] of byte; {5 Zeichen}
j,k:int;
begin
if (Event.What=evMouseDown) and
Contains(Event.Where) then begin
System.Move(Page[(Event.Where.y-a.y)*40+(Event.Where.x-a.x)-2],Envir,sizeof(Envir));
for j:=0 to 2 do if (Envir[j]>=$30) and (Envir[j]<$3a) then break;
i:=0;
for k:=j to j+2 do begin
i:= i shl 4;
if (Envir[k]<$30) or (Envir[k]>=$3a) then begin
videotreffer:=false; exit; end;
i:=i + Envir[k] and $f;
end;
Event.What:=0; VideoTreffer:=true;
end else
Videotreffer:=false; {nicht mal Rechteck getroffen}
end;
const
flashcount:word=0;
lookingfor:boolean=false;
procedure Idle;
var
c:char;
var Idx:tIdx;
found:boolean;
{ var Page:tPage;}
begin
if Timer-FlashCount > (FlagPar and 1)*24+8 then begin
FlashCount:=Timer;
FlagPar:=FlagPar xor 1; {Toggeln Blinkzustand}
VPage.DisplayPage(Page,FlagPar or 2);
end;
end;
procedure readall;
var
{ Page: tPage;}
idx: tIdx;
found: boolean;
i: int;
begin
IndexCnt:=LongDiv(vtf.GetSize,sizeof(TPage));
if IndexCnt>INDIZES then RunError;
if (IndexCnt >0) then
for i:=0 to IndexCnt-1 do begin
vtf.Seek(LongMul(i,sizeof(TPage)));
vtf.Read(Index[i],sizeof(TIdx));
Write(i:5,#13);
end;
writeln;
end;
procedure ReadNewIndex; {Routine zum Einlesen eines New-Format-VT-Files}
{Die Kennung sei bereits vorher gecheckt!}
var
i,i1: int;
ph: int absolute page;
begin
IndexCnt:=LongDiv(vtf.GetSize,sizeof(TPage));
{Dateilänge:=Seitenzahl + (Seitenzahl+248) div INDEXPP, oder andersherum:}
{Seitenzahl:=Dateilänge - (Dateilänge+249) div (INDEXPP+1)}
if IndexCnt>INDIZES then RunError; {Zuviele Indizes}
i:=(IndexCnt+INDEXPP) div (INDEXPP+1); {Reservierte Seiten am Beginn}
for i1:=0 to i-1 do
Longint(Index[i1]):=MAGIC;
while i<IndexCnt do begin
vtf.Read(Page,sizeof(TPage)); {Eine Seite mit Indizes lesen}
if ph>=0 then RunError; {Bit15 muß gesetzt sein, auch bei künftigen Änderungen!}
i1:=IndexCnt-i; if i1>INDEXPP then i1:=INDEXPP; {Differenz, aber höchstens 255}
Move(Page[4],Index[i],sizeof(tIdx)*i1); {Indizes kopieren}
Inc(i,i1); {gleich ein Ruck weiter}
end {while};
end;
procedure ReadIn; {Videotext-Index einlesen, alte und neue Form}
var
ph: Longint absolute page;
begin
vtf.Read(Page,sizeof(TPage)); {Erste Seite einlesen}
vtf.Seek(0); {Dateizeiger zurücksetzen}
if ph=MAGIC then ReadNewIndex
else begin
writeln('Bitte warten, Datei ',filename,' wird eingelesen...');
readall;
end;
end;
{----------------------------------------------------}
procedure printtele(const FName:PathStr; const Page:tPage);
var
s1:array[0..40] of char;
f:text;
spalte,zeile,
byteein :byte;
grafikflag :boolean; { Flag ob Grafik ein/aus }
function cctchr(b:byte):char;
begin
case b of
$00..$1f: b:=$20; {Alle Steuerzeichen zu Space machen}
end;
if grafikflag then
case b of
$20..$3f,$60..$7f: b:=byte('░'); {Alle Grafikzeichen zu Füllern machen}
end;
case b of
$40: b:=byte(''); {gültig für deutsche Seite (4) und Codepage 437}
$5b: b:=byte('Ä');
$5c: b:=byte('Ö');
$5d: b:=byte('Ü');
$60: b:=byte('°');
$7b: b:=byte('ä');
$7c: b:=byte('ö');
$7d: b:=byte('ü');
$7e: b:=byte('ß');
end;
if (Zeile=0) and (Spalte<7) then
CctChr:=' ' else
cctchr:=Chr(b);
end;
begin
assign(f,FName); {$i-}Append(f);{$i+}
if IOResult<>0 then Rewrite(f);
s1[40]:=#0;
for Zeile:=0 to 24 do begin
grafikflag:=FALSE;
for spalte:=0 to 39 do begin
byteein:=Page[Zeile*40+Spalte];
case byteein of
0..7: grafikflag:=FALSE;
16..23: grafikflag:=TRUE;
end;
s1[Spalte]:=cctchr(byteein);
end;
writeln(f,s1);
end;
writeln(f); {Leerzeile}
close(f);
end; { printtele }
procedure GetEvent(var E:tEvent);
begin
repeat
GetKeyEvent(E);
if E.What=0 then GetMouseEvent(E);
if E.What=0 then Idle
else asm
mov ax,3
int 33h
mov ax,dx
mov bl,FONTH
div bl
mov ah,0
les di,E
mov [di+6],ax
end;
until E.What<>0;
end;
var speicher,pagenr,seitenr :word;
weiter :boolean;
attralt :byte;
sel,ok :integer;
procedure main;
(*
Function Ja_Nein(x,y:integer):Boolean;
var
ch:char;
BEGIN
{gotoxy(x,y);} write('<J>a oder <N>ein');
runerror;
repeat
ch:=readkey;
if ch in ['j','J'] then begin Ja_Nein:=true;EXIT;end;
if ch in ['n','N'] then begin Ja_Nein:=false;EXIT;end;
until false;
END;{ ja,nein }
*)
Procedure zahl_aus(hilfstr:String);
Begin
WrStr(copy('###',1,3-Length(HilfStr)),$f2,57,4);
WrStr(Hilfstr,$f2,57+3-Length(HilfStr),4);
End;
var pagelast,z: integer;
ch:Char;
MiniStr: String[3]; {3 Zeichen für Seite}
NextFlag: boolean;
Function NeueSeite:integer; {liefert 0 bei Extra-Funktionen}
var
xy :integer;
okay,z :integer;
hilfstring :string;
BEGIN
hilfstring:='';
repeat
GetEvent(Event);
ch:=Upcase(Event.charcode);
if ((Event.What=evKeyDown) and (Ch='Z')) or
((Event.What=evMouseDown) and
(Event.Buttons=mbRightButton)) then begin
NeueSeite:=GetHistory; exit;
end;
if buttonPlus.treffer(Event) then begin
{Such Minimum größer als pagelast}
xy:=MAXINT;
for j:=0 to IndexCnt-1 do
if Index[j].Pag<$800 then begin
z:=Index[j].Pag; if z<=PageLast then z:=z+$800; {Zyklisch machen!}
if xy>z then xy:=z;
end;
puthistory(pagelast);
NeueSeite:=xy; exit;
end;
if buttonMinus.treffer(Event) then begin
{Such Maximum kleiner als pagelast}
xy:=-MAXINT;
for j:=0 to IndexCnt-1 do
if Index[j].Pag<$800 then begin
z:=Index[j].Pag; if z>=PageLast then z:=z-$800;
{Zyklisch machen! Negative Zahlen stören nicht!}
if xy<z then xy:=z;
end;
PutHistory(PageLast);
NeueSeite:=xy; exit;
end;
if buttonNext.treffer(Event) then begin
{Such Maximum größer als pagelast}
NeueSeite:=pagelast; exit;
end;
if ButtonRight.Treffer(Event) then begin
NextFlag:=true;
NeueSeite:=pagelast; exit;
end;
if button3.treffer(Event) then begin
FlagPar:= FlagPar xor $10;
Ch:=' '; if FlagPar and $10 <>0 then Ch:='√';
CurFont:=@Norm8x10;
WriteChar(Ch,$f2,68,21);
VPage.DisplayPage(Page,FlagPar or $20);
end;
if button2.treffer(Event) then begin
FlagPar:= FlagPar xor $4;
Ch:=' '; if FlagPar and $4 <>0 then Ch:='√';
CurFont:=@Norm8x10;
WriteChar(Ch,$f2,60,18);
VPage.DisplayPage(Page,FlagPar);
end;
if buttonDouble.treffer(Event) then begin
FlagPar:= FlagPar xor $80;
Ch:=' '; if FlagPar and $80 =0 then Ch:='√';
CurFont:=@Norm8x10;
WriteChar(Ch,$f2,65,24);
VPage.DisplayPage(Page,FlagPar);
end;
if button1.treffer(Event) then begin
WrStr('Dateiname: ',$f2,0,0);
MemW[$40:$50]:=11;
readln(hilfstring);
if hilfstring<>'' then begin
printtele(hilfstring,Page);
WrStr(hilfstring+' geschrieben.',$f2,44,32);
end else
WrStr('NICHT geschrieben! ',$f4,44,32);
end;{drucken}
if button4.treffer(Event) then ch:=#27;
if buttonS.treffer(Event) then begin
hilfstring:=''; zahl_aus(hilfstring); end;
if VPage.VideoTreffer(Page,xy,Event) then ch:=#12;
case ch of
'0'..'9','A'..'F':
begin
if length(hilfstring) < 3 then begin
hilfstring:=hilfstring+ch;
zahl_aus(hilfstring);
end;
if length(hilfstring)=3 then begin
val('$'+hilfstring,xy,okay);
If (okay=0) then begin
puthistory(pagelast);
neueseite:=xy; exit;
end;
end;
End;{ Ziffern }
#13: begin
if length(hilfstring)=0 then begin
neueseite:=pagelast; exit;
end;
val('$'+hilfstring,xy,okay);
If (okay=0) then begin
puthistory(pagelast);
neueseite:=xy; exit;
end;
End;{ ENTER }
#12: If (xy>=$100) and (xy<$900) then begin
puthistory(pagelast);
neueseite:=xy; exit;
end;
#8: begin
If (length(hilfstring)>0) then begin
delete(hilfstring,length(hilfstring),1);
zahl_aus(hilfstring);
End;
end;{ Backspace }
#27: begin
neueseite:=0; weiter:=true; exit;
end;{ ESC }
end;{ case }
until false;
end;{ neueseite }
var
found: boolean;
Header: tHeader absolute Page;
function inctomax(k,m:int):int;
begin
inc(k); if k>=m then k:=0;
inctomax:=k;
end;
procedure seektonext;
begin
for j:=1 to 80 do begin
inc(k); if k>80 then k:=1;
if subpagelist[k]='X' then break;
end;
end;
BEGIN
VPage.Assign(2,4,42,28);
pagenr:=$100;
pagelast:=0;
repeat
{ GetEvent(Event);}
found:=true;
if pagenr=pagelast then seektonext;
if (Nextflag and (k<3)) then begin
pagenr:=MAXINT;
for j:=0 to IndexCnt-1 do
if Index[j].Pag<$800 then begin
z:=Index[j].Pag; if z<=PageLast then z:=z+$800; {Zyklisch machen!}
if pagenr>z then pagenr:=z;
end;
puthistory(pagelast);
pagenr:=pagenr and $7ff;
end;
if (pagenr<>pagelast) then begin
found:=false;
subpagelist:=' ';
{leermachen!}
for j:=0 to IndexCnt-1 do begin
if Index[j].pag=pagenr then
if Index[j].sub<$80 then begin
found:=true;
subpagelist[BCD2Hex(Index[j].sub)+1]:='X'; {Kreuzchen setzen}
end;
end;
if found then begin
WrStr(SubPageList,$71,0,0);
k:=0;
SeekToNext;
end else begin
write(#7);
WrStr('Seite nicht vorhanden!',$f4,44,32);
end;
end;
if found then begin
for j:=0 to IndexCnt-1 do begin
if (Index[j].pag=pagenr) and (Index[j].sub=Hex2BCD(k-1)) then break;
end;
vtf.Seek(LongMul(j,sizeof(TPage)));
vtf.Read(Page,sizeof(TPage));
WrStr(PagStr(Header)+' ',$f1,44,32);
Zahl_Aus(FormatS('%03x',0,0,0,Header.Pag));
WrStr(FormatS('%04x',0,0,0,Header.Sub),$f2,62,9);
VPage.DisplayPage(Page,FlagPar);
end;
pagelast:=pagenr;
NextFlag:=FALSE;
pagenr:=neueseite and $7ff; {Hohe Zahlen weg!}
until weiter;
end {main};
procedure checkintegrity;
var
i,j:word;
p,s:word;
begin
writeln('Teste Integrität...');
for j:=0 to IndexCnt-1 do begin
p:=Index[j].pag;
s:=Index[j].sub;
if p and $8000 =0 then begin
for i:=j+1 to IndexCnt-1 do begin
if (p=Index[i].pag) and (s=Index[i].sub) then
writeln(FormatS('Inkonsistent: Index %d zu Index %d, Videoseite %x/%x',s,p,i,j));
end; {for}
end; {if}
end; {for}
end; {proc}
var
stat:byte;
n:NameStr;
e:ExtStr;
fi:file;
bytesread:word;
const
DeleteOnExit: boolean=false;
begin
FileMode:=0;
sstr:=ParamStr(1); {$V-}
FSplit(FExpand(sstr),FileName,n,e);
if n='' then begin
writeln('Dateiname angeben!');
exit;
end;
FileName:=FileName+n;
if e='.VTZ' then begin
SwapVectors;
WriteLn('Packe aus mit PKUNZIP...');
Exec(FSearch('pkunzip.exe',GetEnv('PATH')),
' -o '+FileName+'.vtz '+GetEnv('TEMP')+'\');
SwapVectors;
if DosError<>0 then begin
WriteLn('Fehler ',DosError,' beim Ausführen von PKUNZIP.EXE (nicht im Pfad?)');
exit;
end;
if DosExitCode<>0 then begin
WriteLn('Fehler ',DosExitCode,' beim Auspacken (Rückgabewert von PKUNZIP)');
exit;
end;
FileName:=GetEnv('TEMP')+'\'+n; {Name zusammensetzen}
e:=''; {Eine VT-Datei müßte nun vorhanden sein}
DeleteOnExit:=true; {.VT-Datei löschen bei Programmende}
end;
IndexCnt:=0;
Assign(fi,FileName+'.VTI'); {$i-}Reset(fi,4);{$i+}
if IOResult=0 then begin
blockread(fi,Index,INDIZES,IndexCnt);
end;
if e='' then e:='.VT';
FileName:=FileName+e;
vtf.Init(FileName,stOpenRead);
case vtf.ErrorInfo of
0: if IndexCnt=0 then ReadIn;
2: begin
writeln('Datei ',fileName,' nicht gefunden!');
exit;
end;
3: begin
writeln('Pfad zu ',fileName,' nicht gefunden!');
exit;
end;
5: begin
writeln('Zugriff zu ',fileName,' verweigert!');
exit;
end;
else begin
writeln('DOS-Fehler beim Öffnen der Datei ',fileName,'!');
exit;
end;
end;
if IndexCnt=0 then ReadIn; {Index so oder so einlesen}
if ParamCount >=2 then checkintegrity;
asm xor bx,bx; mov ax,$168B; int $2F end; {DOS-Box in Vollbild schalten}
InitVideo;
SetM10;
ScreenMode:=$10; {damit das Rückschalten klappt}
WrStr (' ■ Wenn SAA programmieren so leicht wäre... ',$70,0,0);
for k:=1 to maxy-1 do
Wrstr('▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒',$71,0,k);
WrStr (' Rechte Maustaste=Zurück! ■ Neue Version - unterstützt gepackte .VTZ-Dateien ',$70,0,maxy);
WriteChar('Z',$74,18,maxy);
buttonS.init('~S~eite xxx',50,3,'S');
buttonU.init('~U~nterseite yyyy',50,8,'U');
button1.init('~P~: ASCII-Ausgabe',50,13,'P');
button2.init('~M~ix-Bild ',50,17,'M');
button3.init('~V~erborgener Text ',50,20,'V');
buttonDouble.init('~D~oppelte Höhe ~√~',50,23,'D');
button4.init('E~x~it',50,28,'x');
buttonplus.init(' ~+~ ',25,30,'+');
buttonminus.init(' ~-~ ',5,30,'-');
buttonnext.init(' ~N~ ',15,30,'N');
buttonRight.init(' ~>~ ',35,30,' ');
WrStr('Datenbasis: '+FileName,$70,44,33);
curfont:=@tele8x10;
InitEvents;
main;
DoneEvents;
DoneVideo;
if DeleteOnExit then asm
mov bl,byte [filename]
xor bh,bh
mov byte [filename+1+bx],0
lea dx,filename[1]
mov ah,$41
int 21h {Nun Datei wieder aufräumen}
end;
WriteLn('Ich hoffe, das Programm war nicht GANZ so schlimm...');
end.
Vorgefundene Kodierung: OEM (CP437) | 1
|
|