[Back to TEXTWNDW SWAG index] [Back to Main SWAG index] [Original]
{
STG>Does anyone know off hand if I can be in text mode and window in a
STG>window and put the wondow only in graphics mode?
STG>I have a program that I need to have a graph in. Does anyone have some
STG>code for using the PLOT procedure to plot variables. The values for
STG>the Y axis are from 1 - 2000, and for the X axis from 1 - 24.
Yes, it's possible... sort of. If you have a VGA (or
EGA) you can have 2 separate character sets on screen at once.
Use one character set for text, and redefine the other for your
graphics window. The only problem is that your graphics window
can only be composed of 256 characters total. So, a 16 X 16
character square would only give you a vertical resolution of 256
pixels and a horizontal resolution of 128 pixels. The following
code is an example of how one would do this.
Dave
}
Program GraphicsInTextModeExample;
{================================================
Graphics In Text Mode Example
Programmed by David Dahl
12/24/93
This program and source are PUBLIC DOMAIN
------------------------------------------------
This example uses a second font as a pseudo-
graphics window. This program requires VGA.
================================================}
Uses CRT;
Const { Dimentions of The Graphics Window in Characters }
ChrSizeX = 32;
ChrSizeY = 256 DIV ChrSizeX;
{ Dimentions of The Graphics Window in Pixels }
MaxX = ChrSizeX * 8;
MaxY = ChrSizeY * 16;
{-[ Set Character Width to 8 Pixels ]-------------------------------------}
Procedure SetCharWidthTo8; Assembler;
Asm
{ Change To 640 Horz Res }
MOV DX, $3CC
IN AL, DX
AND AL, Not(4 OR 8)
MOV DX, $3C2
OUT DX, AL
{ Turn Off Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 0
OUT DX, AL
{ Reset Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 3
OUT DX, AL
{ Switch To 8 Pixel Wide Fonts }
MOV DX, $3C4
MOV AL, 1
OUT DX, AL
MOV DX, $3C5
IN AL, DX
OR AL, 1
OUT DX, AL
{ Turn Off Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 0
OUT DX, AL
{ Reset Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 3
OUT DX, AL
{ Center Screen }
MOV DX, $3DA
IN AL, DX
MOV DX, $3C0
MOV AL, $13 OR 32
OUT DX, AL
MOV AL, 0
OUT DX, AL
End;
{-[ Turn On Dual Fonts ]--------------------------------------------------}
Procedure SetDualFonts; Assembler;
ASM
{ Set Fonts 0 & 1 }
MOV BL, 4
MOV AX, $1103
INT $10
END;
{-[ Turn On Access To Font Memory ]---------------------------------------}
Procedure SetAccessToFontMemory; Assembler;
ASM
{ Turn Off Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 1
OUT DX, AL
{ Reset Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 3
OUT DX, AL
{ Change From Odd/Even Addressing to Linear }
MOV DX, $3C4
MOV AL, 4
OUT DX, AL
MOV DX, $3C5
MOV AL, 7
OUT DX, AL
{ Switch Write Access To Plane 2 }
MOV DX, $3C4
MOV AL, 2
OUT DX, AL
MOV DX, $3C5
MOV AL, 4
OUT DX, AL
{ Set Read Map Reg To Plane 2 }
MOV DX, $3CE
MOV AL, 4
OUT DX, AL
MOV DX, $3CF
MOV AL, 2
OUT DX, AL
{ Set Graphics Mode Reg }
MOV DX, $3CE
MOV AL, 5
OUT DX, AL
MOV DX, $3CF
MOV AL, 0
OUT DX, AL
{ Set Misc. Reg }
MOV DX, $3CE
MOV AL, 6
OUT DX, AL
MOV DX, $3CF
MOV AL, 12
OUT DX, AL
End;
{-[ Turn On Access to Text Memory ]---------------------------------------}
Procedure SetAccessToTextMemory; Assembler;
ASM
{ Turn Off Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 1
OUT DX, AL
{ Reset Sequence Controller }
MOV DX, $3C4
MOV AL, 0
OUT DX, AL
MOV DX, $3C5
MOV AL, 3
OUT DX, AL
{ Change To Odd/Even Addressing }
MOV DX, $3C4
MOV AL, 4
OUT DX, AL
MOV DX, $3C5
MOV AL, 3
OUT DX, AL
{ Switch Write Access }
MOV DX, $3C4
MOV AL, 2
OUT DX, AL
MOV DX, $3C5
MOV AL, 3 {?}
OUT DX, AL
{ Set Read Map Reg }
MOV DX, $3CE
MOV AL, 4
OUT DX, AL
MOV DX, $3CF
MOV AL, 0
OUT DX, AL
{ Set Graphics Mode Reg }
MOV DX, $3CE
MOV AL, 5
OUT DX, AL
MOV DX, $3CF
MOV AL, $10
OUT DX, AL
{ Set Misc. Reg }
MOV DX, $3CE
MOV AL, 6
OUT DX, AL
MOV DX, $3CF
MOV AL, 14
OUT DX, AL
End;
{-[ Clear The Pseudo-Graphics Window by Clearing Font Definition ]--------}
Procedure ClearGraphicsWindow;
Begin
SetAccessToFontMemory;
FillChar (MEM[$B800:$4000], 32 * 256, 0);
SetAccessToTextMemory;
End;
{-[ Turn The Cursor Off ]-------------------------------------------------}
Procedure TurnCursorOff; Assembler;
ASM
MOV DX, $3D4
MOV AL, $0A
OUT DX, AL
MOV DX, $3D5
IN AL, DX
OR AL, 32
OUT DX, AL
End;
{-[ Turn The Cursor On ]--------------------------------------------------}
Procedure TurnCursorOn; Assembler;
ASM
MOV DX, $3D4
MOV AL, $0A
OUT DX, AL
MOV DX, $3D5
IN AL, DX
AND AL, Not(32)
OUT DX, AL
End;
{-[ Set Up The Pseudo-Graphics Window ]-----------------------------------}
Procedure SetGraphicsWindow (XCoord, YCoord : Byte;
Color, BackGround : Byte);
Var CounterX,
CounterY : Byte;
Begin
For CounterY := 0 to (ChrSizeY-1) do
For CounterX := 0 to (ChrSizeX-1) do
MEMW[$B800:CounterX*2 + XCoord*2 + (YCoord * 80 * 2) +
(CounterY * 80 * 2)] :=
(CounterX + CounterY * ChrSizeX) OR
(((Color OR 8) OR ((BackGround AND 15) SHL 4)) SHL 8);
End;
{-[ Plot a Pixel in The Pseudo-Graphics Window ]--------------------------}
Procedure PutPixel (Xin, Yin : Word);
Var RealY,
RealX : Word;
Begin
If (Xin < MaxX) AND
(Yin < MaxY)
Then
Begin
RealX := (Xin DIV 8) * 32;
RealY := (Yin MOD 16) + ((Yin DIV 16) * (32 * ChrSizeX));
SetAccessToFontMemory;
MEM[$B800:$4000 + RealX + RealY] :=
MEM[$B800:$4000 + RealX + RealY] OR (128 SHR (Xin MOD 8));
SetAccessToTextMemory;
End;
End;
{-[ Draw A Line ]---------------------------------------------------------}
{ OCTANT DDA Subroutine converted from the BASIC listing on pages 26 - 27 }
{ from the book _Microcomputer_Displays,_Graphics,_ And_Animation_ by }
{ Bruce A. Artwick }
Procedure Line (XStart, YStart, XEnd, YEnd : Word);
Var StartX,
StartY,
EndX,
EndY : Word;
DX,
DY : Integer;
CNTDWN : Integer;
Errr : Integer;
Temp : Integer;
NotDone : Boolean;
Begin
NotDone := True;
StartX := XStart;
StartY := YStart;
EndX := XEnd;
EndY := YEnd;
If EndX < StartX Then
Begin
{ Mirror Quadrants 2,3 to 1,4 }
Temp := StartX;
StartX := EndX;
EndX := Temp;
Temp := StartY;
StartY := EndY;
EndY := Temp;
End;
DX := EndX - StartX;
DY := EndY - StartY;
If DY < 0 Then
Begin
If -DY > DX Then
Begin
{ Octant 7 Line Generation }
CntDwn := -DY + 1;
ERRR := -(-DY shr 1); {Fast Divide By 2}
While NotDone do
Begin
PutPixel (StartX, StartY);
Dec (CntDwn);
If CntDwn <= 0
Then NotDone := False
Else
Begin
Dec(StartY);
Inc(Errr, DX);
If Errr >= 0 Then
Begin
Inc(StartX);
Inc(Errr, DY);
End;
End;
End;
End
Else
Begin
{ Octant 8 Line Generation }
CntDwn := DX + 1;
ERRR := -(DX shr 1); {Fast Divide By 2}
While NotDone do
Begin
PutPixel (StartX, StartY);
Dec (CntDwn);
If CntDwn <= 0
Then NotDone := False
Else
Begin
Inc(StartX);
Dec(Errr, DY);
If Errr >= 0 Then
Begin
Dec(StartY);
Dec(Errr, DX);
End;
End;
End;
End;
End
Else If DY > DX Then
Begin
{ Octant 2 Line Generation }
CntDwn := DY + 1;
ERRR := -(DY shr 1); {Fast Divide By 2}
While NotDone do
Begin
PutPixel (StartX, StartY);
Dec (CntDwn);
If CntDwn <= 0
Then NotDone := False
Else
Begin
Inc(StartY);
Inc(Errr, DX);
If Errr >= 0 Then
Begin
Inc(StartX);
Dec(Errr, DY);
End;
End;
End;
End
Else
{ Octant 1 Line Generation }
Begin
CntDwn := DX + 1;
ERRR := -(DX shr 1); {Fast Divide By 2}
While NotDone do
Begin
PutPixel (StartX, StartY);
Dec (CntDwn);
If CntDwn <= 0
Then NotDone := False
Else
Begin
Inc(StartX);
Inc(Errr, DY);
If Errr >= 0 Then
Begin
Inc(StartY);
Dec(Errr, DX);
End;
End;
End;
End;
End;
{-[ Draw A Circle ]-----------------------------------------------------}
{ Algorithm based on the Pseudocode from page 83 of the book _Advanced }
{ Graphics_In_C_ by Nelson Johnson }
Procedure Circle (XCoord, YCoord, Radius : Integer);
Var d : Integer;
X, Y : Integer;
Procedure Symmetry (xc, yc, x, y : integer);
Begin
PutPixel ( X+xc, Y+yc);
PutPixel ( X+xc, -Y+yc);
PutPixel (-X+xc, -Y+yc);
PutPixel (-X+xc, Y+yc);
PutPixel ( Y+xc, X+yc);
PutPixel ( Y+xc, -X+yc);
PutPixel (-Y+xc, -X+yc);
PutPixel (-Y+xc, X+yc);
End;
Begin
x := 0;
y := abs(Radius);
d := 3 - 2 * y;
While (x < y) do
Begin
Symmetry (XCoord, YCoord, x, y);
if (d < 0) Then
inc(d, (4 * x) + 6)
else
Begin
inc (d, 4 * (x - y) + 10);
dec (y);
End;
inc(x);
End;
If x = y then
Symmetry (XCoord, YCoord, x, y);
End;
{-[ Draw A Rectangle ]----------------------------------------------------}
Procedure Rectangle (X1, Y1, X2, Y2 : Word);
Begin
{ Draw Top Of Box }
Line (X1, Y1, X2, Y1);
{ Draw Right Side Of Box }
Line (X2, Y1, X2, Y2);
{ Draw Left Side Of Box }
Line (X1, Y1, X1, Y2);
{ Draw Botton Of Box }
Line (X1, Y2, X2, Y2);
End;
{=[ Main Program ]========================================================}
Var C : Word;
Key : Char;
Begin
TextMode (C80);
TurnCursorOff;
SetCharWidthTo8;
SetDualFonts;
ClearGraphicsWindow;
TextColor(LightGray);
ClrScr;
SetGraphicsWindow (40, 0, White, Blue); {X, Y, Color, BGColor}
Writeln ('Graphics In Text Mode Example');
Writeln ('Programmed by David Dahl');
Writeln ('This is PUBLIC DOMAIN');
Writeln;
Writeln ('The graphics window to the right is');
Writeln ('made up of custom characters of the');
Writeln ('second font.');
Writeln;
Writeln ('There are four graphics primitives');
Writeln ('available in this example program.');
Writeln ('Circle, Line, PutPixel, and ');
Writeln ('Rectangle are avaiable for your own');
Writeln ('use.');
Writeln;
Randomize;
For C := 1 to 10 do
Begin
Line (Random(MaxX), Random(MaxY),
Random(MaxX), Random(MaxY));
Circle (Random(MaxX), Random(MaxY), Random(30));
Rectangle (Random(MaxX), Random(MaxY),
Random(MaxX), Random(MaxY));
End;
Writeln ('Press [RETURN] to exit.');
Readln;
TurnCursorOn;
TextMode (C80);
End.
[Back to TEXTWNDW SWAG index] [Back to Main SWAG index] [Original]