home *** CD-ROM | disk | FTP | other *** search
- {$I defines.inc}
- Unit SURFGRAF;
- {Graphics primitives for Surfmodl. These primitives use the borland .BGI }
- {routines. If you add support for a new graphics system, you must update }
- {the SYS_NAME, LGLSYS, MAXSYS, and perhaps OLDSYS routines. You also must}
- {update the SURFBGI bgi emulation routines}
-
- INTERFACE
- uses crt,
- {$IFDEF EXTERNAL}
- SURFbgi;
- {$ELSE}
- Graph;
- {$ENDIF}
-
- {$IFDEF USE8087}
- type real = single;
- {$ENDIF}
- { Names of all the systems currently supported by SURFMODL: }
- const MAXSYS = 11; { maximum # of systems currently supported }
-
-
- const Sys_name: array[1..MAXSYS] of string[30] = (
- 'IBM Color Graphics Adapter',
- 'IBM MCGA Graphics Adapter',
- 'IBM Enhanced Graphics Adapter',
- 'IBM EGA with 64K memory',
- 'IBM EGA with Mono Display',
- 'RESERVED',
- 'Hercules Nono Graphics Adapter',
- 'AT&T 6300 400 line mode',
- 'IBM VGA Graphics Adapter',
- 'IBM 3270',
- {$IFDEF VAXMATE }
- 'DEC Vaxmate'
- {$ELSE}
- 'RESERVED' {<<<<<< Note, this must be present and in CAPS to work}
- {$ENDIF}
-
- );
-
- LGLSYS: array[1..MAXSYS] of integer = (
- CGA,
- MCGA,
- EGA,
- EGA64,
- EGAMONO,
- RESERVED,
- HERCMONO,
- ATT400,
- VGA,
- PC3270,
- {$IFDEF VAXMATE} {Make unused systems RESERVED}
- VM400
- {$ELSE}
- RESERVED
- {$ENDIF}
- );
-
- {table to convert old Surfmodl 1.x system number to new}
- const oldsys :array[1..10] of integer = (
- CGA, { CGA : old number 1}
- EGA, { EGA : old number 2}
- HERCMono, { HERCMono : old number 3}
- detect, { Sanyo Unsupported, try to detect}
- detect, { Heath/Zenith Z-100 Unsupported, try to detect }
- CGA, { Toolbox CGA, old number 6 }
- ATT400, { AT&T 6300 mode, old number 7 }
- PC3270, { IBM 3270, old number 8 }
- EGA64, { Old QUADEGA (640x480), closest is (640x350) }
- EGA64); { Old QUADEGA (752x410), closest is (640x350) }
-
-
- var
- driveron : boolean; { flag for if driver is on or not }
- grsys : integer; { Graphics system being used }
- grmode : integer; { Graphics mode in the system }
- dorandom : boolean; { flag for random interpolation }
- RandShade : real; { Random shade pattern }
- Ngraphchar: integer; { #chars across graphics screen}
- { If 0 then no text will be
- displayed on the graphics screen }
- Gxmin, Gxmax,
- Gymin, Gymax: integer; { graphics screen limits }
- ncolors : integer; { Number of colours supported in current mode}
- MONO : boolean; { Flag for monochrome graphics }
- Viewchanged : boolean; { Flag for changed viewpoint }
- Flpurpose: string[127]; { title for plot }
- BGIDIR : string;
-
- procedure gplot (x,y,color:integer);
- procedure exgraphic;
- procedure closedriver; {shuts down entire graphics system }
- procedure GDRAW (X1t, Y1t, X2t, Y2t, Color: integer);
- procedure GHDRAW (X1, X2, Y, Color: integer);
- procedure SHPLOT (X, Y, Color: integer; Fmod: integer);
- procedure SHDRAW (X1, X2, Y, Color: integer; Fmod: integer);
- procedure setsys;
-
- procedure SETGMODE;
- procedure stopstat;
- function grafstat : boolean;
- function checkey : boolean;
-
-
- function savescrn (filename : string) : boolean;
-
- function readscrn (filename : string; var grsys,grmode : integer;
- var bitmap : pointer) : boolean;
-
- IMPLEMENTATION
-
-
-
-
- procedure gplot (x,y,color:integer);
- {plot one dot in given colour, with clipping}
- begin
- putpixel (x,y,color);
- end;
-
- procedure EXGRAPHIC;
- { Exit graphics mode }
- begin
- RestoreCrtMode;
- end; { procedure EXGRAPHIC }
-
- procedure closedriver;
- { closes down the existing graphics system }
- begin
- if driveron then begin
- setgraphmode(grmode);
- closegraph;
- driveron := false;
- end;
- end;
-
- { NOTE: This file contains several routines, which are the system-independent
- graphics primitives of SURFMODL:
- GDRAW - Line drawing routine
- GHDRAW - Horizontal line drawing routine
- SHPLOT - Shaded pixel plot routine
- SHDRAW - Shaded line drawing routine
- DITHPLOT - Dithered pixel plot routine
- DITHDRAW - Dithered line drawing routine
- INTRPLOT - Interpolated pixel plot routine
- INTRDRAW - Interpolated line drawing routine
- }
-
-
- { System Independent Line draw }
- procedure GDRAW (X1t, Y1t, X2t, Y2t, Color: integer);
- { This routine was written by Russell Nelson, to draw a line using the
- GPLOT primitive -- for systems that do not provide a line drawing
- primitive. This routine does NOT clip. }
- var
- delta_x, delta_y : integer;
- inc_x, inc_y : integer;
- epsilon, count : integer;
- x1, y1, x2, y2: integer;
- begin
- if (x2t < x1t) then begin
- { Make sure the lines are always plotted in the same direction, for
- smooth line drawing in hidden line removal. }
- x1 := x2t;
- y1 := y2t;
- x2 := x1t;
- y2 := y1t;
- end else begin
- x1 := x1t;
- y1 := y1t;
- x2 := x2t;
- y2 := y2t;
- end;
- delta_x := abs(x2 - x1);
- delta_y := abs(y2 - y1);
- { if x2 > x1 then inc_x := 1 else inc_x := -1; }
- inc_x := 1;
- if y2 > y1 then inc_y := 1 else inc_y := -1;
- if delta_x > delta_y then begin
- count := delta_x + 1;
- epsilon := delta_x div 2;
- while count>0 do begin
- GPLOT(x1, y1, Color);
- epsilon := epsilon + delta_y;
- if epsilon > delta_x then begin
- epsilon := epsilon - delta_x;
- y1 := y1 + inc_y;
- end;
- x1 := x1 + inc_x;
- count := count - 1;
- end;
- end else begin
- count := delta_y + 1;
- epsilon := delta_y div 2;
- while count>0 do begin
- GPLOT(x1, y1, Color);
- epsilon := epsilon + delta_x;
- if epsilon > delta_y then begin
- epsilon := epsilon - delta_y;
- x1 := x1 + inc_x;
- end;
- y1 := y1 + inc_y;
- count := count - 1;
- end;
- end;
- end; { procedure GDRAW }
-
-
- { GHDRAW: Horizontal line draw.}
- procedure GHDRAW (X1, X2, Y, Color: integer);
- { Special fast version that does its own clipping}
- var X: integer;
- X1t, X2t: integer;
- begin
- gdraw (x1,y,x2,y,color);
- end; { procedure GHDRAW }
-
- procedure SHPLOT (X, Y, Color: integer; Fmod: integer);
- { system-independent shaded pixel plot command }
- { This routine uses the system's colors as shades of grey }
- begin
- if (Fmod > 1) then begin
- if (X mod Fmod = Y mod Fmod) then
- gplot (X, Y, Color)
- else
- gplot (X, Y, 0);
- end else if (Fmod < -1) then begin
- if (X mod -Fmod = Y mod -Fmod) then
- gplot (X, Y, 0)
- else
- gplot (X, Y, Color);
- end else
- gplot (X, Y, Color);
- end; { procedure SHPLOT }
-
- procedure SHDRAW (X1, X2, Y, Color: integer; Fmod: integer);
- { system-independent shaded horizontal line drawing command }
- { This routine uses the system's colors as shades of grey }
- var X: integer; { x coord }
-
- begin
- if (abs(Fmod) < 2) then
- ghdraw (X1, X2, Y, Color)
- else if (Fmod > 1) then begin
- for X := X1 to X2 do
- if (X mod Fmod = Y mod Fmod) then
- gplot (X, Y, Color)
- else
- gplot (X, Y, 0);
- end else begin
- for X := X1 to X2 do
- if (X mod -Fmod = Y mod -Fmod) then
- gplot (X, Y, 0)
- else
- gplot (X, Y, Color);
- end;
- end; { procedure SHDRAW }
-
-
-
- procedure SETSYS;
- { Initialize system-dependent parameters, and check for hardware presence
- if possible. (Ncolors is set to 0 if the hardware is known to not be
- present.
- }
- var
- sys : integer;
- message : string;
- modelow,modehi : integer;
- num : integer;
- code : integer;
-
- begin
-
- if not driveron then begin
- initgraph (grsys,grmode,BGIDIR);
- if graphresult < 0 then begin
- grsys := detect;
-
- initgraph (grsys,grmode,BGIDIR);
- if graphresult < 0 then begin
- writeln (grapherrormsg(grsys));
- writeln;
- writeln ('If the .BGI files are not in the current directory');
- writeln ('then you can use SET to set an environment variable');
- writeln ('called BGIDIR which points to the .BGI file directory.');
- writeln;
- writeln ('SurfModl Halted');
- halt(1);
- end; {Error initializing hardware from detect}
- end; { error initializing selected hardware, try detect }
- restorecrtmode;
- driveron := true;
- end {Driver not successfully initialized yet }
- else
- driveron := false;
-
- Message := 'No error';
-
- {Write the menu options}
- While not driveron do begin
-
- clrscr;
- if Message = 'No error' then
- writeln
- else
- writeln ('GRAPH ERROR: ',message,^G);
-
- writeln;
- writeln ('Choose from the following system types:');
- for Sys := 1 to MAXSYS do
- if (Sys_name[lglsys[sys]] <> 'RESERVED') then
- writeln (Lglsys[Sys]:3,' ',Sys_name[Lglsys[Sys]]);
-
- grsys := 1;
- repeat
- write ('System Number (',grsys,'): ');
- readln (message);
- if message = '' then
- str (grsys,message);
- val(message,num,code);
- until ((code = 0) and (trunc(num) in [1..MAXSYS]) and
- (SYS_NAME[lglsys[num]] <> 'RESERVED'));
- grsys := trunc(num);
-
- {Get mode for this driver}
- clrscr;
-
- getmoderange(grsys,modelow,modehi);
- if modelow <> modehi then begin {Select the graphics mode}
- writeln ('Choose from the following graphics modes:');
- Case grsys of
- CGA : begin
- writeln (' 0: 320x200, Lightgreen Lightred, Yellow');
- writeln (' 1: 320x200, LightCyan, LightMagenta, White');
- writeln (' 2: 320x200, Green, Red, Brown');
- writeln (' 3: 320x200, Cyan, Magenta, Lightgrey');
- writeln (' 4: 640x200, one colour');
- end;
- MCGA: Begin
- writeln (' 0: 320x200, Lightgreen Lightred, Yellow');
- writeln (' 1: 320x200, LightCyan, LightMagenta, White');
- writeln (' 2: 320x200, Green, Red, Brown');
- writeln (' 3: 320x200, Cyan, Magenta, Lightgrey');
- writeln (' 4: 640x200, one colour');
- writeln (' 5: 640x480, one colour');
- end;
- EGA : Begin
- writeln (' 0: 640x200, 16 Colour');
- writeln (' 1: 640x350, 16 Colour');
- end;
- EGA64: Begin
- writeln (' 0: 640x200, 16 Colour');
- writeln (' 1: 640x350, 4 Colour');
- end;
- EGAMONO: Begin
- writeln (' 3: 640x350, 1 Colour');
- end;
- HercMONO: Begin
- writeln (' 0: 720x348, 1 Colour');
- end;
- ATT400: Begin
- writeln (' 0: 320x200, Lightgreen Lightred, Yellow');
- writeln (' 1: 320x200, LightCyan, LightMagenta, White');
- writeln (' 2: 320x200, Green, Red, Brown');
- writeln (' 3: 320x200, Cyan, Magenta, Lightgrey');
- writeln (' 4: 640x200, one colour');
- writeln (' 5: 640x400, one colour');
- end;
- VGA: Begin
- writeln (' 0: 640x200, 16 Colour');
- writeln (' 1: 640x350, 16 Colour');
- writeln (' 2: 640x480, 16 Colour');
- end;
- PC3270: Begin
- writeln (' 0: 720x350, 1 Colour');
- end;
- {$IFDEF VAXMATE} {DEC VAXMATE modes}
- VM400 : begin
- writeln (' 0: 320x200, Lightgreen Lightred, Yellow');
- writeln (' 1: 320x200, LightCyan, LightMagenta, White');
- writeln (' 2: 320x200, Green, Red, Brown');
- writeln (' 3: 320x200, Cyan, Magenta, Lightgrey');
- writeln (' 4: 640x200, one colour');
- writeln (' 5: 640x400, four colour');
- writeln (' 6: 640x400, one colour');
- end;
- {$ENDIF}
- end; {case}
-
- grmode := modehi;
- repeat
- write ('Enter Graphic Mode (',grmode,'): ');
- readln (message);
- if message = '' then
- str (grmode,message);
- val(message,num,code);
- until ((code = 0) and (trunc(num) in [modelow..modehi]));
- grmode := trunc(num);
-
- end; {then}
-
- setgraphmode(grmode);
- CLOSEGRAPH;
- if graphresult = 0 then; {clear the graphresult}
-
- initgraph (grsys,grmode,BGIDIR);
- message := grapherrormsg (graphresult);
- driveron := message = 'No error';
- restorecrtmode;
- viewchanged := true;
- end; { while }
-
- ngraphchar := GetMaxX div 8;
- GXmin := 0;
- GXMax := GetMaxX ;
- Gymin := 0;
- GYMax := GetMaxY;
- Ncolors := GetMaxColor;
-
- if grsys = RESERVED then
- setsys; {force display of menu}
- end; { procedure SETSYS }
-
-
- function CHECKEY: boolean;
- { Return TRUE if the 'A' key has been pressed, or FALSE otherwise }
- var c: char;
-
- begin
- c := ' ';
- if (keypressed) then begin
- c := readkey;
- if (upcase (c) = 'A') then
- Checkey := TRUE
- else
- Checkey := FALSE;
- end else
- Checkey := FALSE;
- end; { function CHECKEY }
-
-
- { GRAFSTAT and STOPSTAT control the plotting of "status dots" at the bottom
- of the graphics screen. STOPSTAT clears the line away and also
- reinitializes the local (static) variables.
- }
- var Statpos: integer; { next X-position to plot a status dot }
-
- procedure STOPSTAT;
- var c: char;
- begin
- Statpos := Gxmin+3;
- gdraw (Gxmin+1, Gymax-1, Gxmax-1, Gymax-1, 0);
- { Clear out the console input buffer }
- while (keypressed) do
- c := readkey;
- end; { procedure STOPSTAT }
-
- function GRAFSTAT: boolean;
- { Every call to GRAFSTAT produces a new status dot, and also
- checks the keyboard for a run abort. GRAFSTAT returns TRUE if the
- user wishes to abort the run (by pressing the 'A' key), or FALSE otherwise.
- }
- begin
- Statpos := Statpos + 1;
- if (Statpos > Gxmax-3) then
- stopstat;
- gplot (Statpos, Gymax-1, 1);
- Grafstat := checkey;
- end; { procedure GRAFSTAT }
-
-
-
- procedure SETGMODE;
-
- { Set up graphics mode and draw the window }
- var
- message: string;
- temp : integer;
-
- begin
-
- setgraphmode(grmode);
- temp := (graphresult);
- message := grapherrormsg(temp);
- if message <> 'No error' then begin
- restorecrtmode;
- writeln;
- writeln ('SETGraphMODE: BGI error: ',message);
- writeln ('Error number: ',temp);
- writeln ('GrSys is: ',Grsys);
- writeln ('GrMode is: ',Grmode);
- writeln ('SurfModl Halted');
- halt;
- end
- else begin
-
- gdraw (Gxmin, Gymin, Gxmax, Gymin, 1);
- gdraw (Gxmax, Gymin, Gxmax, Gymax, 1);
- gdraw (Gxmax, Gymax, Gxmin, Gymax, 1);
- gdraw (Gxmin, Gymax, Gxmin, Gymin, 1);
-
- stopstat; { Initialize the graphics status line }
-
- setcolor(1);
- if ngraphchar < length (flpurpose) then
- flpurpose := copy (flpurpose,1,ngraphchar);
-
- outtextXY ((ngraphchar - length(flpurpose)) * 4,1 ,Flpurpose);
- end; {else}
- end; { procedure SETGMODE }
-
-
-
-
- function savescrn (filename : string) : boolean;
- var
- imagefile : file;
- bitmap : pointer;
- success : boolean;
-
- begin
- success := true;
- getmem (bitmap,imagesize(0,0,GetMaxX, GetMaxY));
-
- if bitmap = nil then {error}
- success := false
- else begin
- getimage (0,0,GetMaxX,GetMaxY,bitmap^);
- putimage (0,0,bitmap^,NOTput);
- if (graphresult = GrOK) AND (bitmap <> nil) then begin
- {$I-}
- assign (imagefile,filename);
-
- if ioresult <> 0 then
- success := false;
-
- rewrite (imagefile,1);
- if ioresult <> 0 then
- success := false;
-
- blockwrite (imagefile,grsys,sizeof(grsys));
- if ioresult <> 0 then
- success := false;
-
- blockwrite (imagefile,grmode,sizeof(grmode));
- if ioresult <> 0 then
- success := false;
-
- blockwrite (imagefile,bitmap^,imagesize(0,0,GetMaxX, GetMaxY));
- if ioresult <> 0 then
- success := false;
-
- close (imagefile);
- if ioresult <> 0 then
- success := false;
- {$I+}
- end { Image successfuly read }
- else { getimage not successful }
- success := false;
- putimage (0,0,bitmap^,NormalPut);
- release (bitmap);
- end; {memory available}
-
- savescrn := success;
- end; {savescrn}
-
-
-
- function readscrn (filename : string; var grsys,grmode : integer;
- var bitmap : pointer) : boolean;
- var
- imagefile : file;
- success : boolean;
-
- begin
- success := true;
- {$I-}
- assign (imagefile,filename);
-
- if ioresult <> 0 then begin
- success := false;
- writeln ('File "',filename,'" not found');
- end;
-
- reset (imagefile,1);
- if ioresult <> 0 then begin
- success := false;
- writeln ('File "',filename,'" not found');
- end;
-
- blockread (imagefile,grsys,sizeof(grsys));
- if ioresult <> 0 then begin
- success := false;
- writeln ('Could not read grsys');
- end;
-
- blockread (imagefile,grmode,sizeof(grmode));
- if ioresult <> 0 then begin
- success := false;
- writeln ('Could not read grmode');
- end;
- {$I+}
-
-
- if success then begin
- getmem (bitmap,filesize(imagefile) - sizeof(grmode) - sizeof(grsys));
- if bitmap = nil then begin
- success := false;
- writeln ('Could not allocate memory for bitmap');
- end
- else begin {memory successfully allocated}
- {$I-}
- blockread (imagefile,bitmap^,filesize(imagefile) - sizeof(grmode)
- - sizeof(grsys));
- if ioresult <> 0 then begin
- success := false;
- writeln ('Could not read image');
- end;
- {$I+}
- end; {Memory allocated}
- end; { Image successfuly read }
-
- {$I-}
- close (imagefile);
- {$I+}
- if ioresult <> 0 then
- success := false;
-
- readscrn := success;
- end; {readscrn}
-
-
- {************************************************************************}
- function get_env
- (env_var: String) { environment variable to look for }
- : String; { Value of environment variable }
- { }
- { Description: }
- { Returns the value associated with the given environment variable }
- { }
- {************************************************************************}
- { }
- { Revision History: }
- { "a" means Alpha version, Not Completed }
- { "b" means Beta Test Version, Completed but in testing }
- { "c" means Completed Version. This version is now frozen }
- { }
- {************************************************************************}
-
- var
- i,j: integer;
- result: String;
- found: boolean;
- table_address: integer;
-
- begin { get_environment }
- result := '';
- i := 0;
- table_address := memW[PrefixSeg:$002c];
-
- if length (env_var) <> 0 then begin
- for j := 1 to length(env_var) do begin {convert to uppercase}
- if env_var[j] in ['a'..'z'] then begin
- env_var[j] := chr(ord(env_var[j])-32);
- end; {then}
- end; {for}
-
- repeat
- result := '';
- while (mem[table_address:i]) <> 0 do begin
- result := result + chr(mem[table_address:i]);
- i := i + 1;
- end;
-
- if pos (env_var,result) = 1 then begin
- found := true;
- result := copy (result,length(env_var) + 2,length(result));
- end
- else
- found := false;
-
- i := i + 1;
- until found or (result = '');
-
- end; { Then find value }
- get_env := result;
-
- end; {get_env}
-
- {The following procedures link in the appropriate .OBJ files so the graphics }
- {drivers are always memory resident. If you get an error message, then you }
- {must copy the .BGI files into this directory, then run the BGI2OBJ batch }
- {file. It uses the turbo pascal 4.0 utility BINOBJ. }
-
- {$IFDEF LINKATT}
- {$DEFINE LINKING}
- procedure ATTDriver; external;
- {$L ATT.OBJ }
- {$ENDIF}
-
- {$IFDEF LINKCGA}
- {$DEFINE LINKING}
- procedure CgaDriver; external;
- {$L CGA.OBJ }
- {$ENDIF}
-
- {$IFDEF LINKEGAVGA}
- {$DEFINE LINKING}
- procedure EgaVgaDriver; external;
- {$L EGAVGA.OBJ }
- {$ENDIF}
-
- {$IFDEF LINKHERC}
- {$DEFINE LINKING}
- procedure HercDriver; external;
- {$L HERC.OBJ }
- {$ENDIF}
-
- {$IFDEF LINKPC3270}
- {$DEFINE LINKING}
- procedure PC3270Driver; external;
- {$L PC3270.OBJ }
- {$ENDIF}
-
- {$IFDEF LINKING}
- procedure Abort(Msg : string);
- begin
- Writeln(Msg, ': ', GraphErrorMsg(GraphResult));
- Halt(1);
- end;
- {$ENDIF}
-
- BEGIN
- driveron := false;
- DoRandom := false;
- RandShade := 1.0 / 16.0;
- Mono := true;
- grsys := -1;
- grmode := -1;
- viewchanged := true;
-
- {Get the directory the .BGI drivers are in}
- BGIDIR := get_env('BGIDIR');
-
- {$IFDEF LINKCGA}
- if RegisterBGIdriver(@CGADriver) < 0 then
- Abort('CGA');
- {$ENDIF}
-
- {$IFDEF LINKEGAVGA}
- if RegisterBGIdriver(@EGAVGADriver) < 0 then
- Abort('EGA/VGA');
- {$ENDIF}
-
- {$IFDEF LINKHERC}
- if RegisterBGIdriver(@HercDriver) < 0 then
- Abort('Herc');
- {$ENDIF}
-
- {$IFDEF LINKATT}
- if RegisterBGIdriver(@ATTDriver) < 0 then
- Abort('AT&T');
- {$ENDIF}
-
- {$IFDEF LINKPC2370}
- if RegisterBGIdriver(@PC3270Driver) < 0 then
- Abort('PC 3270');
- {$ENDIF}
-
- {vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv}
- {If you get an error message, "Error 15: File not found (xxx.OBJ)" then you }
- {must copy the .BGI files into this directory, then run the BGI2OBJ batch }
- {file. It uses the turbo pascal 4.0 utility BINOBJ so it must be available }
- {^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^}
- END.
-