{$N+,A+,G+,F+,D-,E-,L-,R-,S-,Q-,Y-}
unit text1;

interface

procedure scene_endscroll;

implementation

uses global, screen, resource, memory, palette, text;

const
max_length_string=38;
max_count_string=300;
line_height=15;

procedure gradDrawChar_6x6(ch:char; x,y:integer; seg_font,ofs_font, where:word);
var vsi,height:word;
begin
if (y<=-6) or (y>199) then exit;
vsi:=(ord(ch)-32)*36 + ofs_font;

if y<0 then begin height:=6+y; vsi:=vsi-6*y; y:=0; end
else if y>200-6 then height:=6-(y-(200-6))
else height:=6;
asm
mov es, where
mov si, vsi

{call x+y*320}
mov ax, y
xchg ah, al
mov  di, ax
shr  di, 2
add  di, ax
add  di, x

mov al, byte ptr y
mov ah, al
mov dx, ax
db $66; shl dx, 16
mov dx, ax

mov cx, height

push ds
mov ds, seg_font
@y:
   db $66; mov ax, ds:[si]
           mov bx, ds:[si+4]

   db $66; add dx, 0101h;dw 0101h;

   db $66; and ax, dx  {set color}
           and bx, dx
   db $66; mov es:[di], ax
           mov es:[di+4], bx
   add di, 320
   add si, 6
dec cx
jnz @y
pop ds
end;
end;


procedure gradDrawChar_12x12(ch:char; x,y:integer; seg_font,ofs_font, where:word);
var vsi,height:word;
begin
if (y<=-12) or (y>199) then exit;
vsi:=(ord(ch)-32)*144 + ofs_font;

if y<0 then begin height:=12+y; vsi:=vsi-12*y; y:=0; end
else if y>200-12 then height:=12-(y-(200-12))
else height:=12;
asm
mov es, where
mov si, vsi

{call x+y*320}
mov ax, y
xchg ah, al
mov  di, ax
shr  di, 2
add  di, ax
add  di, x

mov al, byte ptr y
mov ah, al
mov dx, ax
db $66; shl dx, 16
mov dx, ax


push bp
push ds
mov cx, height
mov ds, seg_font
@y:
   db $66; mov ax, ds:[si]
   db $66; mov bx, ds:[si+4]
   db $66; mov bp, ds:[si+8]

   db $66; add dx, 0101h;dw 0101h;
   db $66; and ax, dx  {set color}
   db $66; and bx, dx
   db $66; and bp, dx

   db $66; mov es:[di], ax
   db $66; mov es:[di+4], bx
   db $66; mov es:[di+8], bp

   add di, 320
   add si, 12
dec cx
jnz @y
pop ds
pop bp
end;
end;

procedure gradDrawString_6x6(s:string; x,y:integer; seg_font6x6,ofs_font6x6,where:word);
var h,n:word;
begin
h:=0;
   for n:=1 to Length(s) do begin
      gradDrawChar_6x6(s[n], x+h,y, seg_font6x6,ofs_font6x6, where);
      h:=h+6;
   end;
end;


procedure gradDrawString_12x12(s:string; x,y:integer; seg_font12x12,ofs_font12x12, where:word);
var h,n:word;
begin
h:=0;
   for n:=1 to Length(s) do begin
      gradDrawChar_12x12(s[n], x+h,y, seg_font12x12,ofs_font12x12, where);
      h:=h+12;
   end;
end;


var
 Aantal, T1, start_time, old_time,elapsed_time:word;

 seg_text:word;
 seg_offset_index:word;
 seg_len_index:word;
 seg_height_index:word;
 seg_font_index:word;

 s:string;
 sizetext, n, offset, stroka:word;
 Hscroll, x,y,y1:integer;
 test,b, m:byte;
 font, num_string, c:byte;
 xx,yy, count_string:word;
 Hscroll_s, step: single;
seg_font6x6, ofs_font6x6, seg_font12x12, ofs_font12x12: word;


procedure Scene_Endscroll;
begin
seg_font6x6:=vaddr2;       ofs_font6x6:=0;
seg_font12x12:=vaddr2+256; ofs_font12x12:=0;
seg_text:=vaddr3;
seg_len_index:=vaddr3   +512;
seg_height_index:=vaddr3+512*2;
seg_offset_index:=vaddr3+512*3;
seg_font_index  :=vaddr3+512*4;

LoadBin('font6.bin',  seg_font6x6,   0);
LoadBinUnpack('font12.bin',  {load->}vaddr,{-unpack->}seg_font12x12,  0);

Sizetext:=word(LoadBin('text.txt',   seg_text,      0));

{decrypt}
for n:=0 to Sizetext-1 do mem[seg_text:n]:=mem[seg_text:n] xor 13;{}

Clear(0, 64000, vga);
Midas_WaitVR;
SetOneColor(0, 0, 0, 0);
set_border_color(0);

for n:=1 to 200 do begin
   c:=round(sin(n/40-0.9)*25+35);
   setOneColor(n, c, c, c);
end;

{---------- creat indexes ---------}
count_string:=0;
offset:=0;
y:=0;
yy:=0;
repeat
   s:='';
   n:=0;
   memw[seg_offset_index:count_string shl 1]:=offset;
   repeat
       b:=mem[seg_text:offset+n];
       if b=61 then mem[seg_text:offset+n]:=byte(32); {заменяем "=" на пробел}
       s[0]:=char(n); {length of string}
       inc(n);
       s[n]:=char(b);
   until (b=13) or (s='{end}') or (n>Max_length_string);

   offset:=offset+n+1;
   mem[seg_len_index:count_string]:=n-1;
   memw[seg_height_index:count_string shl 1]:=yy;

   {распознаем символ < в конце строки, включающий для строки маленький шрифт}
   if (byte(s[n-2])=32) and (byte(s[n-1])=60) and (byte(s[n])=13) then begin
        {уменьшаем длину строки, чтобы не рисовать служебные символы}
        dec(mem[seg_len_index:count_string], 2);
        {отмечаем вид шрифта для данной строки}
        mem[seg_font_index:count_string]:=6;
        yy:=yy+line_height div 2 +1;
   end
   else begin
        mem[seg_font_index:count_string]:=12;
        yy:=yy+line_height;
   end;

   inc(count_string);
until (s='{end}') or (count_string>max_count_string);
{-------------------------------------------------------------}



Hscroll_s:=-210;

y1:=0;

{Найдем стартовую видимую строку}
Hscroll:=trunc(HScroll_s);
y:=0;
if (Hscroll_s>0) then begin
   repeat
      yy:=memw[seg_height_index:y shl 1];
      inc(y);
   until integer(yy)-Hscroll >= -line_height;
y1:=y-1;
end;



{--------------------------POEHALI---------------------------------}
Aantal:=0; T1:=mTimer;
old_time:=mtimer;
start_time:=mtimer;

repeat
elapsed_time:=(mtimer-old_time);
old_time:=mtimer;

Clear(0, 64000, vaddr);


MP^.GetInformation(@info);


test:=0;

Hscroll:=trunc(HScroll_s);

{продвигаемся по массиву вперед, когда текущая верхняя строка уходит за верхний край}
if integer(memw[seg_height_index:y1 shl 1]-Hscroll)<-line_height then y1:=y1+1;

y:=y1;

if y<count_string-1 then
repeat

   xx:=0;
   s:='';
   offset:=memw[seg_offset_index:y shl 1];
   s[0]:=char(mem[seg_len_index:y]);
   m:=mem[seg_len_index:y];
   yy:=memw[seg_height_index:y shl 1];
   font:=mem[seg_font_index:y];

   if m>0 then {formiruem stroku}
      for n:=0 to m-1 do
        begin
           b:=mem[vaddr3:offset+n];
           s[n+1]:=char(b);
        end;
   s[0]:=char(m);


   if font=12 then begin
       xx:=(320-(m*12)) div 2;
       gradDrawString_12x12(s, xx, yy-Hscroll, seg_font12x12,ofs_font12x12,  vaddr)
   end
   else begin
       xx:=(320-(m*6)) div 2;
       gradDrawString_6x6(s, xx, yy-Hscroll, seg_font6x6,ofs_font6x6, vaddr);
   end;

   inc(test);

inc(y);
until (yy-Hscroll>200) or (y>=count_string-1);

step:=0.5*elapsed_time;
if step>line_height-1 then step:=line_height-1;
Hscroll_s:=Hscroll_s+step;{}


{str(test, s);
DrawString_6x6(s, 2, 15, 2, seg_font6x6,ofs_font6x6, vaddr);{}


Midas_WaitVR;{}
FlipScreen(vaddr,VGA);{}

Inc(Aantal);
if FPS_Mode=1 then WriteFps(3, mtimer, T1, Aantal, vga);

until (esc_test) or (music_pos(84,30));
end;

end.