home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
PROGRAM
/
PASCAL
/
SVGADC30
/
SVGAMAP.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-03-03
|
19KB
|
733 lines
program SVGA_Bitmap_Maker;
{ Use mouse to choose color and draw image }
{ The followig keys can be used as follows }
{ 'Q' - No nonsense quit }
{ 'S' - Save image to disk. Will be prompted }
{ for a filename. }
{ 'L' - Load image from disk. Will be prompted }
{ for a filename. }
{ 'P' - Change width of each pixel element of }
{ drawing. Range 1..9 }
{ 'N' - New image. Clears present image from }
{ memory. Prompts for 'Y' or 'N' }
{ 'C' - Change image size. Will delete present }
{ image from memory and start with new }
{ sized image. Image dimensions are }
{ measured in pixels. If not enough }
{ memory on heap image size will not }
{ be allowed. }
{ 'M' - Move image around screen to get at }
{ hard to reach places. Press escape }
{ when done. }
{ 'X' - Load a palette from disk. Prompts for }
{ filename. }
{ 'E' - Left over from development of this }
{ program. Simply puts image to screen }
{ whereever mouse pointer is. }
{ If you want to exit from 'load' , 'save' etc }
{ without the program doing anything simply }
{ press enter with no input i.e. null string '' }
uses SVGA, Crt;
type YPtr = ^YType;
YType = record
Col1, Col2, Col3, Col4 : byte; { Due to TP's memory }
NextY : YPtr; { memory management }
end; { pointers are multiples}
XPtr = ^XType; { of 8 bytes }
XType = record
NextX : XPtr;
Y : YPtr;
end;
var GM : GraphicMouse;
Vx, Vy, PixelWidth, XPos, YPos, Btn, TX, TY, Bx, By : integer;
ActiveColor, MaxHeight, MaxWidth : byte;
XCoord, YCoord, resp, ImageName, PaletteName : string;
Quit : boolean;
Ch : char;
Image : XPtr;
HeapMem : longint;
procedure PutImage( x, y : integer; Img : XPtr );
var xx, yy : integer;
Offset, bank : longint;
procedure TraverseYPtr( Yp : YPtr );
begin
if Yp <> nil then
begin
Bank := Offset shr 16;
if Bank <> PresentSeg then LoadWriteBank( Bank );
MEM[$A000:Offset] := Yp^.Col1;
inc( Offset, Bytes_per_line );
Bank := Offset shr 16;
if Bank <> PresentSeg then LoadWriteBank( Bank );
MEM[$A000:Offset] := Yp^.Col2;
inc( Offset, Bytes_per_line );
Bank := Offset shr 16;
if Bank <> PresentSeg then LoadWriteBank( Bank );
MEM[$A000:Offset] := Yp^.Col3;
inc( Offset, Bytes_per_line );
Bank := Offset shr 16;
if Bank <> PresentSeg then LoadWriteBank( Bank );
MEM[$A000:Offset] := Yp^.Col4;
inc( Offset, Bytes_per_line );
inc( yy, 4 );
TraverseYPtr( Yp^.NextY );
end;
end;
procedure TraverseXPtr( Xp : XPtr );
begin
if Xp <> nil then
begin
Offset := (longint(yy)*Bytes_per_line)+xx;
TraverseYPtr( Xp^.Y );
yy := y;
inc( xx );
TraverseXPtr( Xp^.NextX );
end;
end;
begin
xx := x;
yy := y;
TraverseXPtr( Img );
end;
procedure SaveImage( Img : XPtr );
var f : file of byte;
procedure TraverseYPtr( Yp : YPtr );
begin
if Yp <> nil then
begin
write( f, Yp^.Col1 );
write( f, Yp^.Col2 );
write( f, Yp^.Col3 );
write( f, Yp^.Col4 );
TraverseYPtr( Yp^.NextY );
end;
end;
procedure TraverseXPtr( Xp : XPtr );
begin
if Xp <> nil then
begin
TraverseYPtr( Xp^.Y );
TraverseXPtr( Xp^.NextX );
end;
end;
begin
assign( f, imagename );
rewrite( f );
write( f, MaxWidth, MaxHeight );
TraverseXPtr( Img );
close( f );
end;
procedure DrawImage;
var xx, yy, vvx, vvy : integer;
procedure TraverseYPtr( Yp : YPtr );
procedure PlotCol( c : byte; x: integer; var y : integer );
begin
if yy < By then
begin
RectFill( x*PixelWidth, y*PixelWidth, x*PixelWidth+PixelWidth-1,
y*PixelWidth+PixelWidth-1, c );
if (500+x < GetMaxX) and (300+y < GetmaxY) then
Plot( 500+x, 300+y, c );
inc( y );
end;
end;
begin
if vvy >= Vy then
begin
if (Yp <> nil) then
begin
PlotCol( Yp^.Col1, xx, yy );
PlotCol( Yp^.Col2, xx, yy );
PlotCol( Yp^.Col3, xx, yy );
PlotCol( Yp^.Col4, xx, yy );
TraverseYPtr( Yp^.NextY );
end;
end
else
begin
inc( vvy, 4 );
if Yp <> nil then TraverseYPtr( Yp^.NextY );
end
end;
procedure TraverseXPtr( Xp : XPtr );
begin
if vvx >= Vx then
begin
if (Xp <> nil) and (xx < Bx) then
begin
TraverseYPtr( Xp^.Y );
yy := 0; vvy := 0;
inc( xx );
TraverseXPtr( Xp^.NextX );
end;
end
else
begin
inc( vvx );
if Xp <> nil then TraverseXPtr( Xp^.NextX );
end;
end;
begin
GM.Show( False );
ClearPort( 0, 0, GetMaxX-140, GetMaxY );
RectFill( 500,300,GetMaxX, GetMaxY, 0 );
xx := 0; vvx := 0;
yy := 0; vvy := 0;
TraverseXPtr( Image );
GM.Show( True );
end;
procedure LoadImage( var ImagePtr : XPtr );
var f : file of byte;
Col1, Col2, Col3, Col4, th : byte;
procedure ReadY( var Yp : YPtr );
var TmpY : YPtr;
begin
new( TmpY );
read( f, Col1, Col2, Col3, Col4 );
TmpY^.Col1 := Col1;
TmpY^.Col2 := Col2;
TmpY^.Col3 := Col3;
TmpY^.Col4 := Col4;
inc( th, 4 );
if th < MaxHeight then
ReadY( TmpY^.NextY )
else
TmpY^.NextY := nil;
Yp := TmpY;
end;
procedure ReadX( var Xp : XPtr );
var TmpX : XPtr;
begin
if not eof( f ) then
begin
new( TmpX );
ReadY( TmpX^.Y );
th := 1;
ReadX( TmpX^.NextX );
Xp := TmpX;
end
else
Xp := nil;
end;
begin
assign( f, ImageName );
reset( f );
read( f, MaxWidth, MaxHeight );
th := 1;
ReadX( ImagePtr );
close( f );
end;
procedure SetImageCol( x, y, NewCol : byte; var Img : XPtr );
var xx, yy : byte;
procedure TraverseYPtr( var Yp : YPtr );
function ic( var t : byte ): byte;
begin
inc( t );
ic := t;
end;
begin
if Yp <> nil then
begin
if yy = y then Yp^.Col1 := NewCol
else if ic(yy) = y then Yp^.Col2 := NewCol
else if ic(yy) = y then Yp^.Col3 := NewCol
else if ic(yy) = y then Yp^.Col4 := NewCol
else
begin
inc( yy );
TraverseYPtr( Yp^.NextY );
end;
end;
end;
procedure TraverseXPtr( var Xp : XPtr );
begin
if Xp <> nil then
begin
if xx = x then
TraverseYPtr( Xp^.Y )
else
begin
inc( xx );
TraverseXPtr( Xp^.NextX );
end
end;
end;
begin
xx := 0;
yy := 0;
TraverseXPtr( Img );
end;
procedure ClearMemory( var Img : XPtr );
procedure TraverseYPtr( Yp : YPtr );
begin
if Yp <> nil then
begin
Yp^.Col1 := 0;
Yp^.Col2 := 0;
Yp^.Col3 := 0;
Yp^.Col4 := 0;
TraverseYPtr( Yp^.NextY );
end;
end;
procedure TraverseXPtr( Xp : XPtr );
begin
if Xp <> nil then
begin
TraverseYPtr( Xp^.Y );
TraverseXPtr( Xp^.NextX );
end;
end;
begin
TraverseXPtr( Img );
end;
procedure InitImage( var ImagePtr : XPtr );
{ Make image of w x h dimensions }
var tw, th : integer; s: string;
procedure InitY( var Yp : YPtr );
var TmpY : YPtr;
begin
if th <= MaxHeight then
begin
new( TmpY );
inc( th, 4 );
InitY( TmpY^.NextY )
end
else
TmpY := nil;
Yp := TmpY;
end;
procedure InitX( var Xp : XPtr );
var TmpX : XPtr;
begin
if tw <= MaxWidth then
begin
new( TmpX );
InitY( TmpX^.Y );
th := 1;
inc( tw );
InitX( TmpX^.NextX );
Xp := TmpX;
end
else
Xp := nil;
end;
begin
tw := 1;
th := 1;
InitX( ImagePtr );
ClearMemory( ImagePtr );
end;
procedure DisposeImage( var Img : XPtr );
procedure TraverseYPtr( Yp : YPtr );
begin
if Yp <> nil then
begin
TraverseYPtr( Yp^.NextY );
Dispose( Yp );
end;
end;
procedure TraverseXPtr( Xp : XPtr );
begin
if Xp <> nil then
begin
TraverseXPtr( Xp^.NextX );
TraverseYPtr( Xp^.Y );
end;
end;
begin
TraverseXPtr( Img );
Img := nil;
end;
procedure SetUp;
var i, j : integer;
begin
SetMode( SVGA6448 );
LoadFont( StandardFont );
SetFontColor( 253, 0, false );
LoadPalette( 'Pal002.pal' );
for i := 0 to 7 do
for j := 0 to 31 do
RectFill( 500+i*15, j*7, 500+i*15+14, j*7+7, i*32+j );
Quit := False;
ActiveColor := 45;
MaxWidth := 10;
MaxHeight := 10;
Bx := MaxWidth;
By := MaxHeight;
Image := nil;
InitImage( Image );
PixelWidth := 4;
HeapMem := MemAvail;
Vx := 0;
Vy := 0;
ImageName := '';
GM.Initialize;
end;
procedure Message2( Note : string );
begin
ClearPort( 500, 225, GetMaxX, GetMaxY );
OutTextXY( 510, 235, Note );
end;
function Message( Note : string ) : string;
var TempStr : string;
Ch : char;
begin
TempStr := '';
ClearPort( 500, 225, GetMaxX, 280 );
OutTextXY( 510, 235, Note );
repeat
ClearPort( 500, 250, GetMaxX, 260 );
OutTextXY( 510, 250, TempStr );
Ch := ReadKey;
case upcase(Ch) of
'A'..'Z',
'0'..'9',
'\', ':',
'.', '_' : TempStr := TempStr+ upcase(Ch);
#$7F,#$08 : if ord( TempStr[0] ) > 0 then
TempStr[0] := chr( ord( TempStr[0] ) - 1 );
end;
until Ch = #$0D;
ClearPort( 500, 225, GetMaxX, 280 );
Message := TempStr;
end;
procedure GetBxBy;
begin
if PixelWidth*(MaxWidth-Vx) > (GetMaxX-140) then Bx := ((GetMaxX-140) div PixelWidth)-1
else Bx := MaxWidth - Vx;
if PixelWidth*(MaxHeight-Vy) > GetMaxY then By := (GetMaxY div PixelWidth)-1
else By := MaxHeight - Vy;
end;
procedure ChangePixelWidth;
var w : string;
begin
repeat
w := Message( 'Pixel Width' );
PixelWidth := ord(w[1]) - ord('0');
until PixelWidth in [1..9];
GetBxBy;
DrawImage;
end;
procedure ChangeImageSize;
var sx, sy : string;
px, py, txx, tyy : integer;
M : Position;
done : boolean;
hp, x,y : longint;
begin
GM.Show( False );
done := false;
Message2( 'Image Size' );
ClearPort( 0, 0, GetMaxX-140, GetMaxY );
GM.QueryBtnDn( 0, M );
MaxHeight := 80;
MaxWidth := 80;
Rectangle( 0, 0, MaxWidth, MaxHeight, 253 );
GM.SetPosition( 80, 80 );
x := 20; px := 20;
y := 20; py := 20;
repeat
repeat
GM.QueryBtnDn( 0, M );
GM.ReadMove( txx, tyy );
if (x + txx) > 63 then x := 63
else if (x + txx) < 1 then x := 1
else x := x + txx;
if (y + tyy) > 63 then y := 63
else if (y + tyy) < 1 then y := 1
else y := y + tyy;
y := y;
x := x;
if (x <> px) or (y <> py) then
begin
Rectangle( 0, 0, px*4, py*4, 0 );
Rectangle( 0, 0, x*4, y*4, 253 );
str( x*4, sx );
str( y*4, sy );
OutTextXY( 525, 260, sx+' ' );
OutTextXY( 575, 260, sy+' ' );
str( MemAvail, sy );
OutTextXY( 400,400, sy );
end;
px := x;
py := y;
until M.OpCount > 0;
hp := x*4*(y*4+1)*8;
if hp < HeapMem then done := true
else
begin
sound(3200); delay( 40 );
sound(2200); delay( 50 );
sound(4000);delay( 40 );
nosound;
end;
until done;
MaxHeight := y*4;
MaxWidth := x*4;
ClearPort( 500, 225, GetMaxX, 280 );
GM.Show( True );
end;
procedure MoveImage;
const i = 20;
var p1, p2 : integer;
procedure minus( var v : integer);
begin
if (v-i) < 0 then v := 0
else v := v - i;
end;
procedure plus( var v : integer; max : integer );
begin
if (v+i) > max then v := max
else v := v + i;
end;
begin
GM.Show( False );
Message2( 'Move Image' );
p1 := Vx; p2 := Vy;
repeat
Ch := ReadKey;
if (Ch = #0) then
begin
Ch := ReadKey;
case ch of
'K' : minus( Vx );
'M' : plus( Vx, MaxWidth );
'H' : minus( Vy );
'P' : plus( Vy, MaxHeight );
'G' : begin
minus( Vx );
minus( Vy );
end;
'I' : begin
plus( Vx, MaxWidth );
minus( Vy );
end;
'O' : begin
minus( Vx );
plus( Vy, MaxHeight );
end;
'Q' : begin
plus( Vx, MaxWidth );
plus( Vy, MaxHeight);
end;
end;
if (Vx <> p1) or (Vy <> p2) then
begin
GetBxBy;
DrawImage;
GM.Show( False );
end;
p1 := Vx; p2 := Vy;
end;
until (Ch = #27);
ClearPort( 500, 225, GetMaxX, 280 );
GetBxBy;
GM.Show( True );
end;
procedure LoadPal;
begin
resp := Message( 'Pallette?' );
if Resp <> '' then
LoadPalette( resp );
end;
begin
SetUp;
DrawImage;
repeat
GM.CheckMouse;
GM.GetPosition( Btn, XPos, YPos );
TX := ( XPos div PixelWidth );
TY := ( YPos div PixelWidth );
if (XPos < (MaxWidth+1)*PixelWidth ) AND (YPos < (MaxHeight+1)*PixelWidth)
and (XPos < Bx*PixelWidth) and (YPos < By*PixelWidth) then
begin
str( (XPos div PixelWidth)+Vx, XCoord );
str( (YPos div PixelWidth)+Vy, YCoord );
OutTextXY( 525, 260, XCoord+' ' );
OutTextXY( 575, 260, YCoord+' ' );
end;
if ( XPos > 500 ) and ( Xpos < 620 ) AND ( Btn AND $01 = $01 )
AND ( YPos < 224 ) then
begin
GM.Show( False );
for TX := 0 to 7 do
for TY := 0 to 31 do
RectFill( 500+TX*15, TY*7, 500+TX*15+14, TY*7+7, TX*32+TY );
TX := ((XPos-500) div 15);
TY := (YPos div 7 );
Rectangle( 500+TX*15, TY*7, 500+TX*15+14, TY*7+7, 255 );
Rectangle( 500+TX*15+1, TY*7+1, 500+TX*15+13, TY*7+6, 252 );
GM.Show( True );
ActiveColor := TX*32 + TY;
end;
if ( XPos < (MaxWidth+1)*PixelWidth) and (Btn AND $03 <> 0)
and (YPos < (MaxHeight+1)*PixelWidth)
and (XPos < Bx*PixelWidth)
and (YPos < By*PixelWidth) then
begin
GM.Show( False );
SetImageCol( TX+Vx, TY+Vy, ActiveColor, Image );
RectFill( TX * PixelWidth, TY * PixelWidth,
TX * PixelWidth+ PixelWidth-1,
TY * PixelWidth+ PixelWidth-1, ActiveColor );
if ((500+tx) <= GetMaxX) and ((300+ty) <= GetMaxY) then
Plot( 500+TX, 300+TY, ActiveColor );
GM.Show( True );
end;
if keypressed then
begin
Ch := ReadKey;
case Ch of
'q','Q' : Quit := True;
's','S' : begin
resp := Message( 'Save Image' );
if resp <> '' then
begin
ImageName := resp;
SaveImage( Image );
end;
end;
'l','L' : begin
resp := Message( 'Load Image' );
if resp <> '' then
begin
ImageName := resp;
DisposeImage( Image );
LoadImage( Image );
GetBxBy;
Vx := 0; Vy := 0;
DrawImage;
end;
end;
'p','P' : ChangePixelWidth;
'n','N' : begin
resp := Message( 'New Image?' );
if resp[1] in ['Y','y'] then
begin
Clearmemory( Image );
DrawImage;
end
end;
'c','C' : begin
DisposeImage( Image );
ChangeImageSize;
InitImage( Image );
PixelWidth := 4;
GetBxBy;
Vx := 0; Vy := 0;
DrawImage;
end;
'm','M' : MoveImage;
'x','X' : LoadPal;
'e','E' : begin
GM.Show( False );
PutImage( XPos, YPos, Image );
Gm.Show( True );
end;
end;
end;
until Quit;
ExitGraphics;
GM.ExitSVGA;
DisposeImage( Image );
end.