Category : C++ Source Code
Archive   : C_ALL.ZIP
Filename : TI1031.ASC

 
Output of file : TI1031.ASC contained in archive : C_ALL.ZIP







PRODUCT : Borland C++ NUMBER : 1031
VERSION : 3.x
OS : DOS
DATE : October 23, 1992 PAGE : 1/11

TITLE : Some Graphics primitives using 256-Color VGA Mode.





// A graphics library demonstrating the simplicity of fast
// graphics in 320x200x256-color VGA mode. The code is not
// fully optimized but it is pretty close; an extra 5% or so
// might be squeezed out of the putimage() for example. Be
// careful when altering pseuodoregisters; while doing one
// load the compiler may trash another register which was just
// loaded with something pertinent.


// Functions provided include point, row, and array (image)
// drawing functions, as well as palette functions using BIOS
// and line-drawing and circle-drawing functions.

// Main() demonstrates most of the functions in a pretty and
// interesting way.


void GrInit(void);
void GrClose(void);
unsigned char GetPixel(unsigned int x, unsigned int y);
void PutPixel(unsigned int x, unsigned int y, unsigned char
color);
void FillRow(unsigned x, unsigned y, unsigned char color,
unsigned length);
void PutRow(unsigned x, unsigned y, char *data, unsigned length);
void GetRow(unsigned x, unsigned y, char *data, unsigned length);
void PutImage(unsigned x, unsigned y, char *data, unsigned rows,
unsigned cols);
void GetImage(unsigned x, unsigned y, char *data, unsigned rows,
unsigned cols);
void GetAllPalette(char (*palette)[3]);
void SetAllPalette( char (*palette)[3]);
void Circle(int x, int y, int radius, unsigned char color);
void Line(unsigned x1, unsigned y1, unsigned x2, unsigned y2,
unsigned char color);



#define VIDEOINT 0x10

#pragma inline














PRODUCT : Borland C++ NUMBER : 1031
VERSION : 3.x
OS : DOS
DATE : October 23, 1992 PAGE : 2/11

TITLE : Some Graphics primitives using 256-Color VGA Mode.




// 'dos.h' is essential
#include
// we need 'math.h' for sqrt() in Circle() and abs() in Line()
#include
// we need 'conio.h' for getch()
#include

int rowOffset[200]; // as an optimization,
// rowOffset will be used as a table to
// avoid the multiplication column+(320*row)
// when getting the actual memory address of
// a pixel or a row



// GrInit() initializes the rowOffset table and switches video
// modes to 320x200 with 256 colors
void GrInit()
{
int i;
// Pre-setup our multipications for column,
//row -> screen address
for (i=0; i<200; ++i)
{
rowOffset[i]=i*320;
}
// Set video mode to 320x200 --
// sophisticated users may wish to research checking
// for the availability of VGA/MCGA prior to switching
// modes.

_AH=0;
_AL=0x13;
geninterrupt(VIDEOINT);
}



// GrClose sets the video back into text mode
void GrClose()
{
// set video mode 80x25 color text -- we're assuming
// that that's available













PRODUCT : Borland C++ NUMBER : 1031
VERSION : 3.x
OS : DOS
DATE : October 23, 1992 PAGE : 3/11

TITLE : Some Graphics primitives using 256-Color VGA Mode.




// if we're using VGA
_AH=0;
_AL=0x3;
geninterrupt(VIDEOINT);
}



// GetPixel returns the pixel value at a given (x,y) screen
// location
unsigned char GetPixel(unsigned int x, unsigned int y)
{
return *((char far *) 0xA0000000L+ (x+rowOffset[y]));
}



// PutPixel changes the pixel at a given (x,y) screen location
// to value 'color'
void PutPixel( unsigned int x, unsigned int y,
unsigned char color)
{
*((char far *) 0xA0000000L + (x+rowOffset[y]))=color;
}



// FillRow writes a row of 'color' color pixels of length
// 'length' starting at screen location (x,y).
void FillRow( unsigned x, unsigned y, unsigned char color,
unsigned length )
{
_ES=0xA000; // The segment for screen memory
_DI=x+rowOffset[y]; // The offset in screen to write at
_CX=length; // Number of bytes for rep stosb
_AL=color; // The value stosb will store in video
// memory
asm {
cld // set direction flag so DI
// will increment
rep stosb // zap a row of color AL out to
// video memory al->[es:di]
}













PRODUCT : Borland C++ NUMBER : 1031
VERSION : 3.x
OS : DOS
DATE : October 23, 1992 PAGE : 4/11

TITLE : Some Graphics primitives using 256-Color VGA Mode.




}



// PutRow transfers a row of pixels from 'data' to screen
// starting at (x,y) and continuing for 'length'. A rep
// movsw instead of rep movsb might optimize this slightly for
// even-length rows
void PutRow(unsigned x, unsigned y, char *data, unsigned length)
{
// You may remove all lines marked with '***' if 'data' is a
// near pointer (i.e. if 'data' was not allocated from the far
// heap and was not declared as 'far' data.) Remove them all
// if you remove any.

_ES=0xA000;
_DI=x+rowOffset[y]; // the offset in video memory for
// the row start
_SI=FP_OFF(data);
// load AX last since many C
// instructions will trash AX
_AX=FP_SEG(data); // store data's segment in AX for
// now ***
asm {
push ds // Save DS since we're going to
// alter it ***
mov ds,ax // load register from AX (loaded
// above) ***
mov cx,length // we're moving 'length' bytes
// total
cld // clear the direction flag to
// increment si and di
rep movsb // dump the whole row out to video
// memory [ds:si]->[es:di]
pop ds // Restore DS ***
}
}



// GetRow() copies a row of pixels of length 'length' out of
// video memory into the buffer at 'data'. rep movsw might be
// slightly faster here also.













PRODUCT : Borland C++ NUMBER : 1031
VERSION : 3.x
OS : DOS
DATE : October 23, 1992 PAGE : 5/11

TITLE : Some Graphics primitives using 256-Color VGA Mode.




void GetRow(unsigned x, unsigned y, char *data, unsigned length)
{
_SI=x+rowOffset[y]; // the offset in video memory for
// the row start
_ES=FP_SEG(data); // set up ES:DI to point to data
_DI=FP_OFF(data);
_AX=0xA000; // load video segment in AX
asm {
push ds // save DS since we have to use DS
// for copying
mov ds,ax // load DS with segment for video
// memory from AX (0xA000)
mov cx,length // we're moving 'length' bytes
// total
cld // clear the direction flag to
// increment si and di
rep movsb // get the whole row from video
// memory [ds:si]->[es:di]
pop ds // Restore DS
}
}



// GetImage() uses repeated GetRow's to store a screen image
// in buffer at 'data'
void GetImage( unsigned x, unsigned y, char *data, unsigned
columns, unsigned rows)
{
int i;
for (i=0; i {
GetRow(x,y+i,data,columns);
data+=columns;
}
}



// PutImage() uses repeated PutRow's to display a screen image
// from 'data' buffer
void PutImage( unsigned x, unsigned y, char *data,
unsigned columns, unsigned rows)













PRODUCT : Borland C++ NUMBER : 1031
VERSION : 3.x
OS : DOS
DATE : October 23, 1992 PAGE : 6/11

TITLE : Some Graphics primitives using 256-Color VGA Mode.




{
int i;
for (i=0; i {
PutRow(x,y+i,data,columns);
data+=columns;
}
}



// traceWait() loops doing in-ports from port 0x3DA until bit 3
// of the value read changes from 1 to 0, meaning a vertical
// retrace just started.
void traceWait()
{
retracewait1:
asm {
mov dx,0x3DA
in al,dx
and al,8
jnz retracewait1
}
retracewait2:
asm {
mov dx,0x3DA
in al,dx
and al,8
jz retracewait2
}
}



// SetAllColors: sets the whole range of palette registers
// from an array containing R,G,B values
void SetAllColors(char (*palette)[3])
{
int paletteSegment,paletteOffset;
traceWait(); // if we change the palette
// while the screen is being
// drawn, parts will appear in the
// old colors and parts in the new













PRODUCT : Borland C++ NUMBER : 1031
VERSION : 3.x
OS : DOS
DATE : October 23, 1992 PAGE : 7/11

TITLE : Some Graphics primitives using 256-Color VGA Mode.




// and this will look odd. So wait
// for vert. retrace!
_ES=FP_SEG(palette); // load ES:DX with palette's
// address
_DX=FP_OFF(palette);
_AX=0x1012; // service 0x10 subservice 0x12
_BX=0; // starting register
_CX=256; // number of registers (256 = all)
geninterrupt(VIDEOINT);
}



void GetAllColors(char (*palette)[3])
{
_ES=FP_SEG(palette); // load ES:DX with palette's
// address
_DX=FP_OFF(palette);
_AX=0x1017; // service 0x10 subservice 0x17
_BX=0; // starting register
_CX=256; // number of registers (256 = all)
geninterrupt(VIDEOINT);
}



// Line takes starting and ending coordinates and a color, and
// draws a line using Bresenham's line drawing algorithm. The
// algorithm uses long ints like ints that also have 16 bits of
// precision after the decimal point.
// Bresenham's assigns an increment of +/- 1.0 to whatever
// variable X or Y has the greater difference and assigns some
// increment smaller than 1 to the axis with a smaller
// differential. Then the line is drawing by successively
// incrementing X and Y from the start until the end is
// reached, and rounding each value to the nearest pixel.
void Line(unsigned x1, unsigned y1, unsigned x2, unsigned y2,
unsigned char color)
{
long xDiff,yDiff,xInc,yInc,x,y;
int screenX,screenY;
xDiff=((long) abs(x1-x2)) << 16;
yDiff=((long) abs(y1-y2)) << 16;













PRODUCT : Borland C++ NUMBER : 1031
VERSION : 3.x
OS : DOS
DATE : October 23, 1992 PAGE : 8/11

TITLE : Some Graphics primitives using 256-Color VGA Mode.




if (xDiff>yDiff)
{
xInc=1L<<16; yInc=yDiff/(xDiff>>16);
}
else
{
xInc=xDiff/(yDiff>>16); yInc=1L<<16;
}
if (x2 < x1) xInc= -xInc;
if (y2 < y1) yInc= -yInc;
x=((long) x1) << 16; y=((long) y1) << 16;
do
{
screenX=(x+32767L)>>16; screenY=(y+32767L)>>16;
PutPixel(screenX,screenY,color);
x+=xInc; y+=yInc;
} while (screenX!=x2 || screenY!=y2);
PutPixel(x2,y2,color); // wrap up the line else we will be
// stopping one pixel before the
// end
}



// Just for fun, a slightly optimized circle drawing routine
void Circle(int centerX, int centerY, int radius, unsigned char
color)
{
int i,newY,radiusSquared,distance;
radiusSquared=radius*radius;
// sqrt(2)/2*radius is the horizontal or vertical portion
// of 1/8 circle

distance=sqrt(2.0)/2.0*radius;

// as an optimization, we will just do 1/8 of a circle and
// do 7 other pixels as reflections, since a circle has
// 8-way symmetry -- all those SQRT's
// can take time! Superfast SQRT's might be done with a
// lookup table.

for (i=0; i<=distance; ++i)
{













PRODUCT : Borland C++ NUMBER : 1031
VERSION : 3.x
OS : DOS
DATE : October 23, 1992 PAGE : 9/11

TITLE : Some Graphics primitives using 256-Color VGA Mode.




// the formula for a circle is x^2+y^2=radius^2
newY=sqrt(radiusSquared-i*i);
PutPixel(centerX+i, centerY+newY,color);
PutPixel(centerX-i, centerY-newY,color);
PutPixel(centerX+i, centerY-newY,color);
PutPixel(centerX-i, centerY+newY,color);
PutPixel(centerX+newY,centerY+i,color);
PutPixel(centerX-newY,centerY-i,color);
PutPixel(centerX+newY,centerY-i,color);
PutPixel(centerX-newY,centerY+i,color);
}
}



#define ROWSIZE 34
char logo[5][ROWSIZE]=
{
1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,1,0,1,1,1,0,
1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,1,0,1,0,1,0,0,1,
1,1,1,0,0,1,0,0,1,0,1,1,1,0,0,1,0,0,0,0,1,1,1,1,0,1,0,1,1,0,1,0,0,1,
1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,
1,1,1,0,0,0,1,1,0,0,1,0,0,1,0,1,1,1,1,0,1,0,0,1,0,1,0,0,1,0,1,1,1,0
};



char image[2700];



int main()
{
int i,j, k;
char palette[256][3], tempRed, tempGreen, tempBlue;
char *temp,color;
GrInit();

// Demonstrate Line function
i=15;
for (j=199; j>0; j-=10)
{
Line(0,j,i,0,j/10+16);













PRODUCT : Borland C++ NUMBER : 1031
VERSION : 3.x
OS : DOS
DATE : October 23, 1992 PAGE : 10/11

TITLE : Some Graphics primitives using 256-Color VGA Mode.




i += 16 ;
}

// Demonstrate FillRow function with a series of rows.
for (i=92; i<=108; i+=2)
{
FillRow(136,i,7,49);
}

// Put BORLAND logo down
PutImage(145,98,&(logo[0][0]),ROWSIZE,5);

// Draw a circle around it
Circle(160,100,25,3);
getch(); // pause to let the user admire our
// work!

// and now some fancy stuff;
// we will get the image and 'shade' it by incrementing the
// color according to the column+row
GetImage(134,74,image,52,52);
temp=image;
for (i=0; i<52; ++i)
{
for (j=0; j<52; ++j)
{
if (*temp!=0)
{
// change BORLAND to 128 higher for contrast
if (*temp==1)
*temp=(*temp+i+j+128)%256;
else
*temp=(*temp+i+j)%256;
}
++temp;
}
}
// put the altered image back down
PutImage(134,74,image,52,52);
GetAllColors(palette);
// now we'll 'rotate' the palette by 1 forever, by copying
// all the colors down to the next lower color, until a key
// is hit. Palette entry 0 is not altered, otherwise the













PRODUCT : Borland C++ NUMBER : 1031
VERSION : 3.x
OS : DOS
DATE : October 23, 1992 PAGE : 11/11

TITLE : Some Graphics primitives using 256-Color VGA Mode.




// background for the whole screen would be flashing.
while (!kbhit())
{
tempRed=palette[1][0]; tempGreen=palette[1][1];
tempBlue=palette[1][2];
for (j=2; j<256; ++j)
{
for (k=0; k<3; ++k) palette[j-1][k]=palette[j][k];
}
palette[255][0]=tempRed; palette[255][1]=tempGreen;
palette[255][2]=tempBlue;
delay(15);
SetAllColors(palette);
}
GrClose();
return(0);
}



DISCLAIMER: You have the right to use this technical information
subject to the terms of the No-Nonsense License Statement that
you received with the Borland product to which this information
pertains.



























  3 Responses to “Category : C++ Source Code
Archive   : C_ALL.ZIP
Filename : TI1031.ASC

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/