unit NVMWgraph; {the new vmw graph unit} {$X+} {$G+} INTERFACE CONST VGA = $a000; var unfadered:array[0..255] of byte; unfadeblue:array[0..255] of byte; unfadegreen:array[0..255] of byte; fontline:array[0..255] of byte; charset:array[0..255,0..15] of byte; charheight:byte; fontseg,fontoff:word; Procedure SetMCGA; Procedure SetText; { This procedure returns you to text mode. } Procedure LoadFont(namest:string); Procedure Cls (Col : Byte; Where:word); Procedure Putpixel (X,Y : Integer; Col : Byte; where:word); Procedure Putpixel240 (X,Y : Integer; Col : Byte; where:word); function getpixel(x,y,where:word):byte; Procedure Pal(Col,R,G,B : Byte); Procedure GetPal(Col : Byte; Var R,G,B : Byte); procedure WaitRetrace; procedure flip(source,dest:Word); procedure outtextlineover(st:string;x,y:integer;col,background:byte;line:integer;where:word); procedure outtextline(st:string;x,y:integer;col,background:byte;line:integer;where:word); procedure outtextxy(st:string;x,y,col,background:integer;where:word;overwrite:boolean); procedure outsmalltextlineover(st:string;x,y:integer;col,background:byte;line:integer;where:word); procedure outsmalltextline(st:string;x,y:integer;col,background:byte;line:integer;where:word); procedure outsmalltextxy(st:string;x,y,col,background:integer;where:word;overwrite:boolean); function sgn(a:real):integer; procedure line(a,b,c,d,col:integer;where:word); procedure horizontalline(FromX1,ToX2,AtY,col:integer;where:word); procedure verticalline(FromY1,ToY2,AtX,col:integer;where:word); procedure fade; procedure unfade; function SavePicSuperPacked(x1,y1,x2,y2,maxcolors:integer;where:word;filename:string):byte; function LoadPicSuperPacked(x1,y1:integer;where:word;LoadPal,LoadPic:boolean;FileName:string):byte; function oldloadpicsuperpacked(x1,y1:integer;where:word;fil:string):byte; procedure box(x1,y1,x2,y2,col:integer;where:word); procedure vdelay(howlong:integer); procedure setupvmwgraph; procedure setuptb1; {Errors for save and load: 0=No error 1=File Not Found 2=Improper file type (No PAINTPROVX.XX header) 3=Improper version 4=Too Many Colors 5=Picture Too Big } IMPLEMENTATION Procedure SetMCGA; { This procedure gets you into 320x200x256 mode. } BEGIN asm mov ax,0013h int 10h end; END; Procedure SetText; { This procedure returns you to text mode. } BEGIN asm mov ax,0003h int 10h end; END; Procedure LoadFont(namest:string); var buff:array[0..15] of byte; f:file; i,fonty:integer; begin assign(f,namest); {$I-} reset(f,16); {$I+} if Ioresult<>0 then writeln(#7); if Ioresult<>0 then exit; fonty:=0; while (not eof(F)) and (fonty<4097) do begin blockread(f,buff,1); for i:=0 to 15 do charset[fonty div 16,i]:=buff[i]; inc(fonty,16); end; close(f); end; Procedure Cls (Col : Byte; Where:word); { This clears the screen to the specified color } BEGIN asm push es mov cx, 32000; mov es,[where] xor di,di mov al,[col] mov ah,al rep stosw pop es End; END; Procedure Putpixel (X,Y : Integer; Col : Byte; where:word); { This puts a pixel on the screen by writing directly to memory. } BEGIN Asm push ds push es mov ax,[where] mov es,ax mov bx,[X] mov dx,[Y] push bx {; and this again for later} mov bx, dx {; bx = dx} mov dh, dl {; dx = dx * 256} xor dl, dl shl bx, 1 shl bx, 1 shl bx, 1 shl bx, 1 shl bx, 1 shl bx, 1 {; bx = bx * 64} add dx, bx {; dx = dx + bx (ie y*320)} pop bx {; get back our x} add bx, dx {; finalise location} mov di, bx {; es:di = where to go} xor al,al mov ah, [Col] mov es:[di],ah pop es pop ds End; END; Procedure Putpixel240 (X,Y : Integer; Col : Byte; where:word); BEGIN Asm push ds push es mov ax,[where] mov es,ax mov bx,[y] shl bx,4 mov dx,bx {; and this again for later} shl bx, 1 {; bx = dx} add dx, bx {; dx = dx * 256} shl bx,1 add dx,bx shl bx, 1 add dx, bx add dx,[x] {; bx = bx * 64} {; dx = dx + bx (ie y*320)} {; get back our x} {; finalise location} mov di, dx {; es:di = where to go} xor al,al mov ah, [Col] mov es:[di],ah pop es pop ds End; END; function getpixel(x,y,where:word):byte; begin getpixel:=mem[where:x+(y*320)]; end; Procedure Pal(Col,R,G,B : Byte); { This sets the Red, Green and Blue values of a certain color } Begin asm mov dx,3c8h mov al,[col] out dx,al inc dx mov al,[r] out dx,al mov al,[g] out dx,al mov al,[b] out dx,al end; End; procedure WaitRetrace; assembler; { This waits for a vertical retrace to reduce snow on the screen } label l1, l2; asm mov dx,3DAh l1: in al,dx and al,08h jnz l1 l2: in al,dx and al,08h jz l2 end; Procedure GetPal(Col : Byte; Var R,G,B : Byte); { This gets the Red, Green and Blue values of a certain color } Var rr,gg,bb : Byte; Begin asm mov dx,3c7h mov al,col out dx,al add dx,2 in al,dx mov [rr],al in al,dx mov [gg],al in al,dx mov [bb],al end; r := rr; g := gg; b := bb; end; procedure flip(source,dest:Word); { This copies the entire screen at "source" to destination } begin asm push ds mov ax, [Dest] mov es, ax mov ax, [Source] mov ds, ax xor si, si xor di, di mov cx, 32000 rep movsw pop ds end; end; procedure outtextlineover(st:string;x,y:integer;col,background:byte;line:integer;where:word); label gus1,gus4,gus5,gus7,gus8,gus3; var i,len:word; begin len:=length(St); for i:=1 to (len div 2)+1 do begin fontline[(i-1)*2]:=charset[ord(st[(i*2)]),line]; fontline[((i-1)*2)+1]:=charset[ord(st[(i*2)-1]),line]; end; asm push ds push si push es push di mov ax,[fontseg] mov ds,ax mov ax,[fontoff] mov si,ax mov dh,[col] mov dl,[background] mov ax,[y] {multiplies y value by 320} shl ax,5 mov cx,ax shl ax,1 shl cx,3 add ax,cx add ax,[x] {adds the x-value to get offset} mov di,ax mov ax,[where] mov es,ax mov bx,[len] gus1: cmp bx,02 jnge gus4 mov cx,16 lodsw jmp gus5 gus4: mov cx,8 lodsw gus5: shl ax,1 push ax jc gus7 mov al,dl jmp gus8 gus7: mov al,dh gus8: xor ah,ah stosb pop ax loop gus5 cmp bx,2 jng gus3 dec bx dec bx jmp gus1 gus3: pop di pop es pop si pop ds end; end; procedure outtextline(st:string;x,y:integer;col,background:byte;line:integer;where:word); label gus1,gus4,gus6,gus5,gus7,gus8,gus3; var i,len:word; begin len:=length(St); for i:=1 to (len div 2)+1 do begin fontline[(i-1)*2]:=charset[ord(st[(i*2)]),line]; fontline[((i-1)*2)+1]:=charset[ord(st[(i*2)-1]),line]; end; asm push ds push si push es push di mov ax,[fontseg] mov ds,ax mov ax,[fontoff] mov si,ax mov dh,[col] mov bl,[background] mov ax,[y] {multiplies y value by 320} shl ax,5 mov cx,ax shl ax,1 shl cx,3 add ax,cx add ax,[x] {adds the x-value to get offset} mov di,ax mov ax,[where] mov es,ax mov bx,[len] gus1: cmp bx,02 jnge gus4 mov cx,16 lodsw jmp gus5 gus4: mov cx,8 lodsw gus5: shl ax,1 push ax jc gus7 inc di jmp gus8 gus7: mov al,dh xor ah,ah stosb gus8: pop ax loop gus5 cmp bx,2 jng gus3 dec bx dec bx jmp gus1 gus3: pop di pop es pop si pop ds end; end; procedure outtextxy(st:string;x,y,col,background:integer;where:word;overwrite:boolean); label l0105; var l,len,i,xadd,yadd,lineon:integer; n,k,o,min,max,qwerty:byte; begin for lineon:=0 to (charheight-1) do if overwrite then outtextlineover(st,x,y+lineon,col,background,lineon,where) else outtextline(st,x,y+lineon,col,background,lineon,where); end; procedure OutSmallTextLineOver(st:string;x,y:integer;col,background:byte;line:integer;where:word); label gus1,gus4,gus5,gus7,gus8,gus3; var i,len:word; begin len:=length(St); for i:=1 to (len div 2)+1 do begin fontline[(i-1)*2]:=charset[(ord(st[(i*2)]))+128,line]; fontline[((i-1)*2)+1]:=charset[(ord(st[(i*2)-1]))+128,line]; end; asm push ds push si push es push di mov ax,[fontseg] mov ds,ax mov ax,[fontoff] mov si,ax mov dh,[col] mov dl,[background] mov ax,[y] {multiplies y value by 320} shl ax,5 mov cx,ax shl ax,1 shl cx,3 add ax,cx add ax,[x] {adds the x-value to get offset} mov di,ax mov ax,[where] mov es,ax mov bx,[len] gus1: xor ax,ax cmp bx,02 jnge gus4 mov cx,10 lodsb push bx mov bl,al xor bh,bh lodsb shl ax,5 add ax,bx shl ax,3 pop bx jmp gus5 gus4: mov cx,5 lodsw gus5: shl ax,1 push ax jc gus7 mov al,dl jmp gus8 gus7: mov al,dh gus8: xor ah,ah stosb pop ax loop gus5 cmp bx,2 jng gus3 dec bx dec bx jmp gus1 gus3: pop di pop es pop si pop ds end; end; procedure outsmalltextline(st:string;x,y:integer;col,background:byte;line:integer;where:word); label gus1,gus4,gus6,gus5,gus7,gus8,gus3; var i,len:word; begin len:=length(St); for i:=1 to (len div 2)+1 do begin fontline[(i-1)*2]:=charset[(ord(st[(i*2)]))+128,line]; fontline[((i-1)*2)+1]:=charset[(ord(st[(i*2)-1]))+128,line]; end; asm push ds push si push es push di mov ax,[fontseg] mov ds,ax mov ax,[fontoff] mov si,ax mov dh,[col] mov bl,[background] mov ax,[y] {multiplies y value by 320} shl ax,5 mov cx,ax shl ax,1 shl cx,3 add ax,cx add ax,[x] {adds the x-value to get offset} mov di,ax mov ax,[where] mov es,ax mov bx,[len] gus1: xor ax,ax cmp bx,02 jnge gus4 mov cx,10 lodsb push bx mov bl,al xor bh,bh lodsb shl ax,5 add ax,bx shl ax,3 pop bx jmp gus5 gus4: mov cx,5 lodsw gus5: shl ax,1 push ax jc gus7 inc di jmp gus8 gus7: mov al,dh xor ah,ah stosb gus8: pop ax loop gus5 cmp bx,2 jng gus3 dec bx dec bx jmp gus1 gus3: pop di pop es pop si pop ds end; end; procedure outsmalltextxy(st:string;x,y,col,background:integer;where:word;overwrite:boolean); label l0105; var l,len,i,xadd,yadd,lineon:integer; n,k,o,min,max,qwerty:byte; begin for lineon:=0 to 4 do if overwrite then outsmalltextlineover(st,x,y+lineon,col,background,lineon,where) else outsmalltextline(st,x,y+lineon,col,background,lineon,where); end; function sgn(a:real):integer; begin if a>0 then sgn:=+1; if a<0 then sgn:=-1; if a=0 then sgn:=0; end; procedure line(a,b,c,d,col:integer;where:word); var u,s,v,d1x,d1y,d2x,d2y,m,n:real; i:integer; begin u:= c - a; v:= d - b; d1x:= SGN(u); d1y:= SGN(v); d2x:= SGN(u); d2y:= 0; m:= ABS(u); n := ABS(v); IF NOT (M>N) then BEGIN d2x := 0 ; d2y := SGN(v); m := ABS(v); n := ABS(u); END; s := INT(m / 2); FOR i := 0 TO round(m) DO BEGIN putpixel(a,b,col,where); s := s + n; IF not (s0 then dec(r); if g>0 then dec(g); if b>0 then dec(b); pal(j,r,g,b); end; end; end; procedure unfade; var i,j:integer; r,g,b:byte; begin for i:=0 to 63 do begin for j:=0 to 255 do begin getpal(j,r,g,b); if r0 then savepicsuperpacked:=1; if Ioresult<>0 then exit; for i:=0 to 3 do begin buffer[0]:=ord(header[(i*3)+1]); buffer[1]:=ord(header[(i*3)+2]); buffer[2]:=ord(header[(i*3)+3]); blockwrite(f,buffer,1); end; for i:=0 to (maxcolors-1) do begin getpal(i,buffer[0],buffer[1],buffer[2]); blockwrite(f,buffer,1); end; xsize:=abs(x2-x1); ysize:=abs(y2-y1); integer23bytes(xsize,ysize); integer23bytes(maxcolors,0); for y:=y1 to y2 do begin oldcol:=getpixel(x1,y,where); numacross:=1; for x:=(x1+1) to x2 do begin col:=getpixel(x,y,where); if col=oldcol then inc(numacross) else begin integer23bytes(oldcol,numacross); numacross:=1; end; oldcol:=col; end; integer23bytes(col,numacross); end; close(f); end; function LoadPicSuperPacked(x1,y1:integer;where:word;LoadPal,LoadPic:boolean;FileName:string):byte; var buffer:array[0..299] of byte; result,buffpointer:integer; f:file; col,x,y,xsize,ysize,i,oldcol, maxcolors,tempint1,tempint2,numacross:integer; header:string; lastread:boolean; tempbyte,r,g,b:byte; procedure sixbytes2twoint; var temp1,temp2,temp3:byte; int1,int2:integer; begin temp1:=buffer[buffpointer]; temp2:=buffer[buffpointer+1]; temp3:=buffer[buffpointer+2]; inc(buffpointer,3); if (buffpointer>=result) then if (result=300) then begin blockread(f,buffer,300,result); buffpointer:=0; end else lastread:=true; asm mov ah,temp1 mov al,temp2 shr ax,4 mov int1,ax mov ah,temp2 mov al,temp3 shl ah,4 shr ah,4 mov int2,ax end; tempint1:=int1; tempint2:=int2; end; begin lastread:=false; loadpicsuperpacked:=0; header:=''; buffpointer:=0; assign(f,filename); {$I-} reset(f,1); {$I+} if IOresult<>0 then LoadPicSuperPacked:=1; if IOresult<>0 then exit; blockread(f,buffer,300,result); for i:=1 to 9 do header:=concat(header,chr(buffer[i-1])); if header<> 'PAINTPROV' then LoadPicSuperPacked:=2; if header<> 'PAINTPROV' then exit; header:=''; header:=concat(header,chr(buffer[9]),chr(buffer[10]),chr(buffer[11])); if header<>'5.0' then LoadPicSuperPacked:=3; if header<>'5.0' then exit; buffpointer:=12; for i:=0 to 255 do begin r:=buffer[buffpointer]; g:=buffer[buffpointer+1]; b:=buffer[buffpointer+2]; inc(buffpointer,3); if (buffpointer>=result) then if (result=300) then begin blockread(f,buffer,300,result); buffpointer:=0; end else lastread:=true; if loadpal then pal(i,r,g,b); end; sixbytes2twoint; xsize:=tempint1; ysize:=tempint2; sixbytes2twoint; maxcolors:=tempint1; {if maxcolors>256 then error=4} x:=x1; y:=y1; if loadpic=true then begin while (lastread=false) do begin sixbytes2twoint; col:=tempint1; numacross:=tempint2; horizontalline(x,x+numacross,y,col,where); { for i:=x to (x+numacross) do putpixel(i,y,col,where);} if (x+numacross)>xsize+x1 then begin inc(y); x:=x1; numacross:=0; end; x:=x+numacross; end; end; close(f); end; function oldloadpicsuperpacked(x1,y1:integer;where:word;fil:string):byte; var buffer:array[0..255] of byte; f:file; col,x,y,xsize,ysize,buffpointer,i,oldcol, tempint1,tempint2,numacross:integer; header:string; lastread,done:boolean; temp7:string; procedure readbuffer; begin blockread(f,buffer,1); if buffer[255]=90 then lastread:=true; end; procedure sixbytes2twoint; var temp1,temp2,temp3:byte; int1,int2:integer; begin if buffpointer>=253 then begin readbuffer; buffpointer:=0; end; if not done then begin temp1:=buffer[buffpointer]; temp2:=buffer[buffpointer+1]; temp3:=buffer[buffpointer+2]; if (temp1=255) and (temp2=255) and (temp3=255) then done:=true; inc(buffpointer,3); asm mov ah,temp1 mov al,temp2 shr ax,1 shr ax,1 shr ax,1 shr ax,1 mov int1,ax mov ah,temp2 mov al,temp3 shl ah,4 shr ah,4 mov int2,ax end; tempint1:=int1; tempint2:=int2; end; end; label ender; begin done:=false; header:='PAINTPROV4.00'; assign(f,fil); reset(f,256); readbuffer; buffpointer:=0; temp7:=header; for i:=1 to 13 do temp7[i]:=chr(buffer[i-1]); if temp7<>header then begin oldloadpicsuperpacked:=01; exit; end; buffpointer:=13; sixbytes2twoint; xsize:=tempint1; ysize:=tempint2; sixbytes2twoint; x:=x1; y:=y1; repeat sixbytes2twoint; if done then goto ender; col:=tempint1; numacross:=tempint2; for i:=x to (x+numacross) do putpixel(i,y,col,where); if (x+numacross)>xsize+x1 then begin inc(y); x:=x1; numacross:=0; end; x:=x+numacross; ender: until done=true; close(f); end; procedure box(x1,y1,x2,y2,col:integer;where:word); begin line(x1,y1,x1,y2,col,where); horizontalline(x1,x2,y2,col,where); line(x2,y2,x2,y1,col,where); horizontalline(x1,x2,y1,col,where); end; procedure vdelay(howlong:integer); var i:integer; begin for i:=1 to howlong do waitretrace; end; procedure setupvmwgraph; begin loadfont('8x8font.tb1'); charheight:=8; fontseg:=seg(fontline[0]); fontoff:=ofs(fontline[0]); end; procedure setuptb1; begin loadfont('tbfont.tb1'); charheight:=8; fontseg:=seg(fontline[0]); fontoff:=ofs(fontline[0]); end; begin end.