Umiestnenie súboru www.TrSek.com/cover/saloky/maingr.pas{ MAINGR.PAS }
{ Nasledovnik MukoGr, hlavny graficky unit. }
{ VypisPO v MGP som zmenil na Vypis. }
{ }
{ Author: ¥ubo¹ Saloky }
{ Datum: 01.01.1996 http://www.trsek.com }
unit MainGr;
INTERFACE
type FontStruc=record
OfsTab:array[0..255] of word; {tabulka offsetov pismen}
Verzia,Vyska,PPismen,Posun,PMedzier,SMedzer:byte; {hlavicka}
Rezerva:array[1..10] of byte;
Pismo:array[0..63999] of byte; {font}
end;
BMPStruc=record
RozX,RozY:word;
BMP:array[0..63999] of byte;
end;
Bezier3Struc=array[1..4,1..2] of integer; {4 riadiace body}
PBezier3Struc=^Bezier3Struc;
{ ----- globalne premenne unitu ----- }
const DataPath='d:\lubo\pascal\units\';
Cierna=0;Cervena=1;Oranzova=2;Zlta=3;Zelena=4;Svetlomodra=5;Modra=6;
Ruzova=7;Bordova=8;Hneda=9;Hnedocervena=10;
var OknoXMin,OknoXMax,OknoYMin,OknoYMax:word; {okraje okna do ktoreho sa kresli}
VSeg:word; {segment VideoRAM}
Color:byte; {aktualna farba}
VypinajMys:boolean; {ci kazda procedura autom. vypne pri kresleni mys.}
{ ----- zakladne procedury a funkcie ----- }
Procedure InicializujGrafiku;
Procedure ZavriGrafiku;
Procedure ZmazObrazovku;
Procedure PolozBod(px,py:word;pColor:byte); {TURBO (nespracuva MYS)}
Function ZistiBod(px,py:word):byte;
Procedure CiaraVodorovna(px,py,Dlzka:integer); {TURBO, nema vyznam pri STOSW}
Procedure CiaraZvisla(px,py,Dlzka:integer);
Procedure Ciara(x1,y1,x2,y2:integer);
Procedure Bezier3(p:PBezier3Struc;PC:word;ColB:byte);
Procedure VyplnPlochu(px,py,DeltaX,DeltaY:integer); {TURBO, nema vyznam pri STOSW}
{ ----- praca s bitmapami ----- }
Procedure NacitajBMP(var f:file;var p:pointer); {subor musi byt otvoreny a nastaveny na spravnej pozicii}
Procedure NacitajAnimaciu(var f:file;Vstup:pointer); {adresa na pole pointrov - jednotlive snimky animacie}
Procedure PrilepBMP(px,py:integer;p:pointer); {TURBO}
Procedure PrilepBMPP(px,py:word;Zdroj:pointer); {TURBO priehladne}
Procedure PrilepBMPPO(px,py:integer;Zdroj:pointer); {TURBO priehladne, okno}
Procedure PrilepBMPPF(px,py:integer;p:pointer;Odtien:byte);{priehladne, odtien}
Procedure PrilepBMPPOF(px,py:integer;Zdroj:pointer;Odtien:byte);
Procedure StiahniBMP(px,py,RozX,RozY:integer;p:pointer); {!!!!! najprv musi byt GetMem !!!!!}
{ ----- praca s fontmi ----- }
Procedure NacitajFont(Subor:string;var p:pointer);
Procedure Vypis(PosX,PosY:integer;p:pointer;Textik:string;Odtien:byte);{bez diakritiky}
Procedure VypisP(PosX,PosY:word;MSFP:pointer;Text:string;Odtien:byte);
Procedure VypisPO(PosX,PosY:integer;p:pointer;Textik:string;Odtien:byte);
Function LengthDiak(Textik:string):byte;
Function LengthPixel(p:pointer;Textik:string):word;
{ ----- praca s farbami a paletou ----- }
Procedure NastavFarbu(cislo,r,g,b:byte);
Procedure ZistiFarbu(cislo:byte;var r,g,b:byte);
Procedure NacitajPaletu(Subor:string;var p:pointer);
Procedure NastavPaletu(p:pointer);
{ ----- dalsie procedury a funkcie ----- }
Procedure Obdlznik(px,py,DeltaX,DeltaY:integer);
Procedure Ramcek(px,py,DeltaX,DeltaY,FarbaVnutra:integer);
Procedure Kruznica(sx,sy,r:integer;Col:byte); { len 640.000 bodov /s }
Procedure CakajNaVOI; {vertikalne zatemnenie}
Procedure Tlacidlo3D(px,py,RozX,RozY:word;Pismo:pointer;Napis:string;Odtien,ONadpisu:byte;Stlacene:boolean);
Procedure NacitajMGP(var f:file;var Kam:pointer);
Procedure VykresliMGP(p1,PoleBMP,PolePisma:pointer); {sama si vypne mys}
Procedure KopirujObrazovku(VSeg1,VSeg2:word);
{ ----- procedury a funkcie nie priamo suvisiace s grafikou ----- }
Function CitajZnak:char;
Function JeZnak:boolean;
Procedure Presun(Zdroj,Ciel:pointer;Pocet:word); {presun casti pamate - Move}
Procedure Vypln(Ciel:pointer;Pocet:word;Hodnota:byte); {vypln pamate - FillChar. Nahradza (ne)fungujuce Move a FillChar}
{ ----- nepouzitelne pre uzivatela, len pre dalsie unity ----- }
Procedure AkTrebaVypniMys;
Procedure AkTrebaZapniMys;
{Rychlost: 486 DX2/66, VESA CL 5428
ZmazObrazovku 166 krat / s (10.624.000 pixelov / s)
PolozBod 625.000 bodov / s
CiaraVodorovna 5.400.000 pixelov / s
Ciara (Bresenham) 2.800.000 pixelov / s
Bezierova krivka 3. st. 1.120.000 - 2.270.000 pixelov / s (podla kvality, pouziva Ciara-u)
Kruznica 640.000 pixelov / s (pomale, vyuziva PolozBod)
VyplnPlochu 6.400.000 pixelov / s
PrilepBMP 11.200.000 pixelov / s
PrilepBMPP 5.800.000 pixelov / s
PrilepBMPPO 5.700.000 pixelov / s
Vypis 60.000 znakov / s (asi 4.000.000 pixelov / s)
VypisPO 43.000 znakov / s
NastavPaletu 800 / s
}
IMPLEMENTATION
{ ----- int·mnosti, pre uz·vatela nepr·stupn‚ strukt£ry ----- }
const DlzElem:array[1..16] of byte=(8,8,5,6,10,11,0,0,6,10,0,6,10,20,1,5);
type pp=array[0..100] of ^FontStruc;
TPP=^pp;
var JeMysM:boolean; { verejne je v Mys.TPU }
function IOMM:boolean;assembler; { neverejna procedura - z MYS.TPU }
asm
mov ax,0
int 33h
end;
procedure AkTrebaVypniMys;assembler;{neverejna procedura}
asm
cmp JeMysM,False
je @Koniec
cmp VypinajMys,False
je @Koniec
mov ax,2
int 33h
@Koniec:
end;
procedure AkTrebaZapniMys;assembler;{neverejna procedura}
asm
cmp JeMysM,False
je @Koniec
cmp VypinajMys,False
je @Koniec
mov ax,1
int 33h
@Koniec:
end;
procedure InicializujGrafiku;
begin
asm
mov ax,0013h
int 10h
end;
end; { InicializujGrafiku }
procedure ZavriGrafiku;
begin
asm
mov ax,3
int 10h
end;
end; { ZavriGrafiku }
procedure ZmazObrazovku;assembler;
asm
call AkTrebaVypniMys
cld
mov es,VSeg
mov cx,32000
xor di,di
xor ax,ax
rep stosw
call AkTrebaZapniMys
end; { ZmazObrazovku }
procedure PolozBod(px,py:word;pColor:byte);assembler;
asm
mov es,VSeg
mov ax,320
mul py
add ax,px
mov di,ax
mov al,pColor
mov byte[es:di],al
end; { PolozBod }
function ZistiBod(px,py:word):byte;assembler;
asm
call AkTrebaVypniMys
mov es,VSeg
mov ax,320
mul py
add ax,px
mov di,ax
mov al,byte[es:di]
call AkTrebaZapniMys
end; { ZistiBod }
procedure CiaraVodorovna(px,py,Dlzka:integer);assembler;
asm
call AkTrebaVypniMys
mov cx,Dlzka
jcxz @Koniec
cmp cx,320
ja @Koniec
cld
mov es,VSeg
mov ax,320
mul py
add ax,px
mov di,ax
mov al,Color
mov ah,al
shr cx,1
jnc @Parny
stosb
@Parny: rep stosw
@Koniec: call AkTrebaZapniMys
end; { CiaraVodorovna }
procedure CiaraZvisla(px,py,Dlzka:integer);assembler;
asm
call AkTrebaVypniMys
mov es,VSeg
mov ax,320
mul py
add ax,px
mov di,ax
mov al,Color
mov cx,Dlzka
jcxz @Koniec
cmp cx,320
ja @Koniec
@DalsiBod: stosb
add di,319
loop @DalsiBod
@Koniec: call AkTrebaZapniMys
end; { CiaraZvisla }
Procedure Ciara(x1,y1,x2,y2:integer);assembler;
var SmerX,SmerY:integer;
asm
call AkTrebaVypniMys
mov SmerX,1
mov SmerY,320
mov es,VSeg
{ ----- vypocet DI - pociatocny offset ----- }
mov ax,320
mul y1
add ax,x1
mov di,ax {DI = offset pociatocneho bodu}
{ ----- vypocet SI = Abs(2 * DeltaY) a SmerY ----- }
mov si,y2
sub si,y1
cmp si,0
jg @DeltaYOK
neg si
mov SmerY,-320
@DeltaYOK: add si,si
{ ----- vypocet BX = 2 * Abs(DeltaX) a SmerX ----- }
mov bx,x2
sub bx,x1
cmp bx,0
jg @DeltaXOK
neg bx
mov SmerX,-1
@DeltaXOK: mov cx,bx {CX = Delta na riadiacej osi}
add bx,bx
{ ----- vymena smerov pri smernici >1 ----- }
cmp bx,si
ja @Nevymen
mov ax,SmerX
xchg SmerY,ax
mov SmerX,ax
mov cx,si {zmen aj pocet kreslenych bodov}
shr cx,1
xchg si,bx
@Nevymen: jcxz @Koniec {je to ciara nulovej dlzky?}
cmp cx,320
ja @Koniec
mov dx,bx {DX = predikcia. Ak je >=0, ide sa dalej na nie riadiacej osi}
shr dx,1
neg dx {predikcia sa inicializuje na -Delta na riadiacej osi }
inc cx {kresli o 1 bod viac (lebo kreslis od 0)}
{ ----- hlavny cyklus ----- }
mov al,Color {AL = farba ciary}
@DalsiBod: mov byte[es:di],al
add di,SmerX
add dx,si {pripocitaj 2*DeltaY}
cmp dx,0
jl @Neodcitaj
add di,SmerY
sub dx,bx {ak treba, odpocitaj 2*DeltaX}
@Neodcitaj: loop @DalsiBod
@Koniec: call AkTrebaZapniMys
end; { Ciara }
procedure Bezier3(p:PBezier3Struc;PC:word;ColB:byte);assembler;
var OldX,OldY,NewX,NewY,t:integer;
TempColor:byte;
asm
call AkTrebaVypniMys
mov al,Color
mov TempColor,al
mov al,ColB
mov Color,al
mov t,0
mov es,word ptr p+2
mov si,word ptr p {ES:SI ukazuje na riadiace body}
mov ax,word ptr [es:si]
mov OldX,ax
mov ax,word ptr [es:si+2]
mov OldY,ax
mov ax,PC
mov cx,PC
mul cx
mul cx
mov di,ax {DI = PC^3}
@For: mov bx,t {BX = t}
mov cx,PC
sub cx,bx {CX = PC-t}
{ ----- vypocet x-ovej suradnice ----- }
mov ax,cx
mul cx
mul cx
mul word ptr [es:si]
div di
mov NewX,ax {1. riadok je hotovy}
mov ax,3
mul cx
mul cx
mul bx
mul word ptr [es:si+4]
div di
add NewX,ax {2. riadok je hotovy}
mov ax,3
mul cx
mul bx
mul bx
mul word ptr [es:si+8]
div di
add NewX,ax {3. riadok je hotovy}
mov ax,bx
mul bx
mul bx
mul word ptr [es:si+12]
div di
add NewX,ax {4. riadok je hotovy}
{ ----- vypocet y-ovej suradnice ----- }
mov ax,cx
mul cx
mul cx
mul word ptr [es:si+2]
div di
mov NewY,ax {1. riadok je hotovy}
mov ax,3
mul cx
mul cx
mul bx
mul word ptr [es:si+6]
div di
add NewY,ax {2. riadok je hotovy}
mov ax,3
mul cx
mul bx
mul bx
mul word ptr [es:si+10]
div di
add NewY,ax {3. riadok je hotovy}
mov ax,bx
mul bx
mul bx
mul word ptr [es:si+14]
div di
add NewY,ax {4. riadok je hotovy}
{ ----- hotovo, ide kreslenie ----- }
pusha
push OldX
push OldY
push NewX
push NewY
call Ciara
popa
mov es,word ptr p+2 {NEZABUDAJ, ze PUSHA neodklada segmentove registre!!!!!}
mov ax,NewX
mov OldX,ax
mov ax,NewY
mov OldY,ax
inc t
mov ax,t
cmp ax,PC
jbe @For
mov al,TempColor
mov Color,al
call AkTrebaZapniMys
end;
procedure VyplnPlochu(px,py,DeltaX,DeltaY:integer);assembler;
asm
call AkTrebaVypniMys
cmp DeltaX,0
je @Koniec
cmp DeltaX,320
ja @Koniec
cmp DeltaY,0
je @Koniec
cmp DeltaY,200
ja @Koniec
cld
mov es,VSeg
mov ax,320
mul py
add ax,px
mov di,ax
mov bx,DeltaY
mov dx,320
sub dx,DeltaX {v DX je 320-DeltaX}
mov al,Color
mov ah,al
@DalsiRiadok:mov cx,DeltaX
shr cx,1
jnc @Parny
stosb
@Parny: rep stosw
add di,dx
dec bx
jnz @DalsiRiadok
@Koniec: call AkTrebaZapniMys
end; { VyplnPlochu }
Procedure NacitajBMP(var f:file;var p:pointer);
var RozX,RozY:word;
pomp:^BMPStruc;
begin
RozX:=0;RozY:=0;
BlockRead(f,RozX,1);
BlockRead(f,RozY,1);
if (RozX=64) and (RozY=200) then RozX:=320;{!!!!!}
GetMem(p,RozX*RozY+4);
pomp:=p;
pomp^.RozX:=RozX;
pomp^.RozY:=RozY;
BlockRead(f,pomp^.BMP,RozX*RozY);
end; { NacitajBitmapu }
Procedure NacitajAnimaciu(var f:file;Vstup:pointer);
type PP=array[1..100] of ^BMP;
BMP=record
RozX,RozY:word;
Mapa:array[1..10000] of byte;
end;
var p:^PP;
PocSnim,RozX,RozY:byte;
i:word;
begin
p:=Vstup;
BlockRead(f,PocSnim,1);
BlockRead(f,RozX,1);
BlockRead(f,RozY,1);
for i:=1 to PocSnim do begin
GetMem(p^[i],RozX*RozY+4);
p^[i]^.RozX:=RozX;
p^[i]^.RozY:=RozY;
BlockRead(f,p^[i]^.Mapa,word(RozX)*word(RozY));
end;
end;
Procedure PrilepBMP(px,py:integer;p:pointer);assembler;
asm
call AkTrebaVypniMys
cld
push ds
mov es,VSeg {ES do videoram}
lds bx,[p] {DS:BX na rozmery bitmapy}
cmp word ptr [bx],0
je @Koniec
cmp word ptr [bx],320
ja @Koniec
cmp word ptr [bx+2],0
je @Koniec
cmp word ptr [bx+2],200
ja @Koniec
mov si,bx
add si,4 {DS:SI na zaciatok bitmapy}
mov ax,320
mul py
add ax,px
mov di,ax {DI na lavy horny roh bitmapy}
mov dx,[bx+2] {RozY}
@DalsiRiadok:mov cx,[bx] {RozX}
shr cx,1
jnc @Parny
movsb
@Parny: rep movsw
add di,320
sub di,[bx]
dec dx
jnz @DalsiRiadok
@Koniec: pop ds
call AkTrebaZapniMys
end; { PrilepBMP }
procedure PrilepBMPP(px,py:word;Zdroj:pointer);assembler;
asm
call AkTrebaVypniMys
cld
mov es,VSeg
push ds
lds bx,[Zdroj] {DS:BX -> rozmery zdrojovej bitmapy}
cmp word ptr [bx],0 {kontrola suradnic}
je @Koniec
cmp word ptr [bx],320
ja @Koniec
cmp word ptr [bx+2],0
je @Koniec
cmp word ptr [bx+2],200
ja @Koniec
mov si,bx
add si,4 {DS:SI -> zaciatok bitmapy}
mov ax,320
mul py
add ax,px
mov di,ax {ES:DI -> ciel vo VRAM}
mov dx,[bx+2] {DX = RozY}
@DalsiRiadok:mov cx,[bx] {CX = pocet prilep. bajtov}
shr cx,1
jnc @Parne
lodsb {prilep 1. bajt}
cmp al,0
je @Nekresli1
mov byte[es:di],al
@Nekresli1: inc di
@Parne: lodsw {prilepuj po slovach}
cmp al,0
je @Nekresli2
mov byte[es:di],al
@Nekresli2: cmp ah,0
je @Nekresli3
mov byte[es:di+1],ah
@Nekresli3: add di,2
loop @Parne
add di,320 {nastav sa na novu poziciu na dalsom riadku}
sub di,[bx]
dec dx
cmp dx,0
jne @DalsiRiadok
@Koniec: pop ds
call AkTrebaZapniMys
end;
procedure PrilepBMPPO(px,py:integer;Zdroj:pointer);assembler;
var DeltaSI,DeltaDI:word; {kolko treba pripocitat k SI a DI pri prechode na dalsi riadok}
InitSI,InitDI:word; {o kolko treba posunut zaciatok prilepovania bitmapy}
AktRozX,AktRozY:word; {aktualne rozmery vyseku ktory sa prilepuje}
asm
{ ----- inicializacia a vypocet rozmerov a pozicie prilepovanej bitmapy ----- }
call AkTrebaVypniMys
cld
les bx,[Zdroj] {ES:BX -> zatial je bitmapa v ES}
mov ax,OknoXMax {kontrola suradnic}
cmp px,ax
jge @Koniec
mov ax,OknoYMax
cmp py,ax
jge @Koniec
mov ax,OknoXMin
sub ax,word ptr [es:bx]
cmp px,ax
jle @Koniec
mov ax,OknoYMin
sub ax,word ptr [es:bx+2]
cmp py,ax
jle @Koniec
mov ax,320
sub ax,[es:bx]
mov DeltaDI,ax {inicializujem premenne, ako keby nebolo treba orezavat}
mov DeltaSI,0
mov InitSI,0
mov InitDI,0
mov ax,[es:bx]
mov AktRozX,ax
mov ax,[es:bx+2]
mov AktRozY,ax
{Lavy} mov ax,OknoXMin
sub ax,px
js @LavyOK
add DeltaSI,ax {upravy pri orezavani laveho okraja}
add InitSI,ax
add InitDI,ax
add DeltaDI,ax
sub AktRozX,ax
@LavyOK: mov ax,px
{Pravy} add ax,[es:bx]
sub ax,OknoXMax
js @PravyOK
dec ax
add DeltaSI,ax {upravy pri orezavani praveho okraja}
add DeltaDI,ax
sub AktRozX,ax
@PravyOK: mov cx,OknoYMin
{Horny} sub cx,py
js @HornyOK
sub AktRozY,cx {upravy pri orezavani horneho okraja}
mov ax,320
mul cx
add InitDI,ax
mov ax,[es:bx]
mul cx
add InitSI,ax
@HornyOK: mov cx,py
add cx,[es:bx+2]
sub cx,OknoYMax
js @DolnyOK
dec cx
sub AktRozY,cx
end; { Ramcek }
procedure CakajNaVOI;assembler;
asm
mov dx,03DAh
@vz1: in al,dx
and al,08h
jnz @vz1
@vz2: in al,dx
and al,08h
jz @vz2
end; { CakajNaVOI }
procedure NacitajMGP(var f:file;var Kam:pointer);
var i:word;
begin
BlockRead(f,i,2);
GetMem(Kam,i+2);
Seek(f,FilePos(f)-2);
BlockRead(f,Kam^,i+2);
end;
procedure AsmVypis(pSeg,pOfs:word;PolePisma:TPP);
var s2:string;
begin
Move(Mem[pSeg:pOfs+7],s2,255);
Vypis(MemW[pSeg:pOfs+1],MemW[pSeg:pOfs+3],PolePisma^[Mem[pSeg:pOfs+5]],s2,Mem[pSeg:pOfs+6]);
end;
procedure AsmVypisPO(pSeg,pOfs:word;PolePisma:TPP);
var s2:string;
begin
Move(Mem[pSeg:pOfs+7],s2,255);
VypisP(MemW[pSeg:pOfs+1],MemW[pSeg:pOfs+3],PolePisma^[Mem[pSeg:pOfs+5]],s2,Mem[pSeg:pOfs+6]);
end;
procedure AsmTlacidlo3D(pSeg,pOfs:word;PolePisma:TPP);
var s2:string;
begin
Move(Mem[pSeg:pOfs+13],s2,255);
Tlacidlo3D(MemW[pSeg:pOfs+1],MemW[pSeg:pOfs+3],MemW[pSeg:pOfs+5],MemW[pSeg:pOfs+7],
PolePisma^[Mem[pSeg:pOfs+8]],s2,Mem[pSeg:pOfs+10],Mem[pSeg:pOfs+11],boolean(Mem[pSeg:pOfs+12]));
end;