You are on page 1of 32

APPENDIX B LIBRARIES

INTRODUCTION

Appendix B is basically an organization chapter, or perhaps we should say


subdirectory. All through this book you have had one library after another
thrown at you. The basic GFXLIB libraries alone numbered to eight, and
there have been plenty of other libraries to add to the confusion. We need to
finish this book with some sanity.

Now about the libraries. They have been renamed. Initially, we had to use
numbers to indicate that the current library was no longer the previous
library. As routines functions were added, the library numbers grew. Now
we are at the conclusion, and we need simple generic names. The chart on
the next page shows the old names, used throughout this book in some
chapter or chapters and the new name that is used in this appendix. We
suggest you use the new names.

╔══════════════════════════╦══════════════════════════╗
║ OLD NAME ║ NEW NAME ║
╠══════════════════════════╬══════════════════════════╣
║ GFXLIB8.HPP ║ GFX320.HPP ║
╟──────────────────────────╫──────────────────────────╢
║ GFXLIB6.HPP ║ GFX640.HPP ║
╟──────────────────────────╫──────────────────────────╢
║ CLRLIB3.HPP ║ COLOR.HPP ║
╟──────────────────────────╫──────────────────────────╢
║ ANIMLIB4.HPP ║ ANIMATE.HPP ║
╟──────────────────────────╫──────────────────────────╢
║ MOUSE.HPP ║ MOUSE.HPP ║
╟──────────────────────────╫──────────────────────────╢
║ SOUNDLIB.HPP ║ SOUND.HPP ║
╟──────────────────────────╫──────────────────────────╢
║ None ║ BOOL.H ║
╚══════════════════════════╩══════════════════════════╝

Appendix B Include Libraries -B.1-


GFX320.HPP
─────────────────────────────────────────────────────────────────────────
/**********************************************************************/
/*** GFX320 combines all the graphics routines in one library of ***/
/*** optimized and correct routines and functions. This libary ***/
/*** represents the second library that is suitable for actual ***/
/*** graphics programming. This is the final graphics library. ***/
/*** ***/
/*** NOTE: Any programs that utilize this file to to at least the ***/
/*** "compact" memory model size to run. To be safe, put ***/
/*** the compiler in the "large" or "huge" memory model. ***/
/**********************************************************************/
#ifndef _GFX320_HPP
#define _GFX320_HPP

#include <fstream.h>
#include <dos.h>
#include <conio.h>
#include <math.h>
#include <mem.h>
#include "BOOL.H"

/*********************************************************************/
/*** USER DEFINED AND ENUMERATED DATA TYPES ***/
/*********************************************************************/
typedef unsigned short Byte; // Byte type definition.
typedef unsigned int Word; // Word type definition.
struct Coord
{
int X; // X coordinate.
int Y; // Y coordinate.
}; // End struct.

typedef Coord huge StackType[20000]; // Stack type.


/*********************************************************************/
/*** CONSTANT VARIABLE IDENTIFIERS ***/
/*********************************************************************/
char* VGAMEM = (char*) MK_FP(0xA000,0); // Pointer to VGA memory.
const VGA_RAM = 0xA000; // Base segment address of VGA memory.
const int MINX = 0; // Minimum x coordinate value.
const int MIDX = 159; // Midpoint x coordinate value.
const int MAXX = 319; // Maximum x coordinate value.
const int MINY = 0; // Minimum y coordinate value.
const int MIDY = 99; // Midpoint y coordinate value.
const int MAXY = 199; // Maximum y coordinate value.
const int MAXC = 256; // Maximum number of colors.
const float AR = 0.88; // Aspect ratio to make circles symetrical.
const float PI = 3.14159; // Approximation of PI.
const float TWOPI = 6.28; // Approximation of 2 * PI.
const FLOODSIZE = 20000; // Maximum flood fill size.
/*********************************************************************/
/*** GLOBAL VARIABLE IDENTIFIERS ***/
/*********************************************************************/
float SinTab[630]; // Sin lookup table.
float CosTab[630]; // Cos loopup table.
int TopOfStack; // Top of stack.
Byte OldColor; // Last base color for floodfille.
StackType Stack; // Artificial Stack.
/*********************************************************************/
/*** FUNCTION PROTOTYPES ***/
/*********************************************************************/
Boolean InBounds (int X, int Y);

Appendix B Include Libraries -B.2-


// Checks if point (x,y) is within screen limits.

void SetMode(Byte Mode);


// Sets the video mode to "mode".

void StartGfx();
// Starts the mcga (320x200x256) graphics mode.

void EndGfx();
// Restore standard text mode (80x25x16).

void Stop();
// Pauses the program until a key is pressed.

void Pixel(int X, int Y, Byte Color);


// Plots a pixel of specificed color at (x,y).

void BoundedPixel(int X, int Y, Byte Color);


// Same as pixel and performs bounds checking.

Byte GetPixel(int X, int Y);


// Returns the color of the pixel at (x,y).

void Line(int X1, int Y1, int X2, int Y2, Byte Color);
// Draws a line from (x1,y1) to (x2,y2).

void BoundedLine(int X1, int Y1, int X2, int Y2, Byte Color);
// Same as line and performs bounds checking.

void Rectangle(int X1, int Y1, int X2, int Y2, Byte Color, Boolean
Filled);
// Draws a rectangle with corners (x1,y1), (x1,y2), (x2,y1), and
(x2,y2).
// It has a parameter "filled" that will draw a solid rectangle rather
than
// an outline.

void BoundedRectangle(int X1, int Y1, int X2, int Y2, Byte Color, Boolean
Filled);
// Same as rectangle and performs bounds checking.

void MakeTables();
// Creates sin and cos lookup tables.

void Circle(int CX, int CY, int Radius, Byte Color);


// Draws a circle with center (cx,cy) and radius "radius".

void BoundedCircle(int CX, int CY, int Radius, Byte Color);


// Same as circle and performs bounds checking.

void Ellipse(int CX, int CY, int XR, int YR, Byte Color);
// Draws an ellipse with center (cx,cy) and eccentricity of xr for x
// and yr for y.

void BoundedEllipse(int CX, int CY, int XR, int YR, Byte Color);
// Same as ellipse and performs bounds checking.

void Arc(int CX, int CY, int XR, int YR, float Start, float Finish, Byte
Color);
// Draws a portion of an ellipse with center (cx,cy) and eccentricty of
// xr for x and yr for y.

void BoundedArc(int CX, int CY, int XR, int YR,


float Start, float Finish, Byte Color);

Appendix B Include Libraries -B.3-


// Same as arc and performs bounds checking.

void FloodFill(int X, int Y, Byte NewColor);


// Fills an enclosed area starting at (x,y) with the specified color.
// Every pixel inside the enclosed area with the same color as (x,y)
// will be altered.

void ClearGfx(Byte NewColor);


// Clears the graphics screen to the specified color.

void Push(Coord N);


// Stack related function.

void Pop(Coord& N);


// Stack related function.

void Flood(int X, int Y, Byte NewColor);


// Floodfill to "newcolor" starting at (x,y).
// This function will crash if fill object is too big.
// Function FloodFill (see above) is better.

int Round(float X);


// Rounds a decimal number (x) to an integer.

void SaveImage(char* FName, int Left, int Top, int Right, int Bottom);
// Saves an image in an area bounded by (left,top) and (right,bottom);

void LoadImage(char* FileName, int left, int Top);


// Loads an image from a file to (left,top).

/***********************************************************************/
/*** FUNCTION IMPLEMENTATIONS ***/
/***********************************************************************/
/*** INBOUNDS ***/
/****************/
Boolean InBounds (int X, int Y)
{
if ( (X > 0) && (Y > 0) && (X < MAXX) && (Y < MAXY) )
return True;
else
return False;
}
/****************/
/*** Set Mode ***/
/****************/
void SetMode(Byte Mode)
{
_AH = 0x00; // Select "set video mode" function (00h)
_AL = Mode; // Set mode selected.
geninterrupt(0x10); // Call video interrupt (10h).
}
/*****************/
/*** Start GFX ***/
/*****************/
void StartGfx()
{
SetMode(0x13); // Set MCGA 320x200x256 mode (13h).
MakeTables();
}
/***************/
/*** End GFX ***/
/***************/
void EndGfx()
{

Appendix B Include Libraries -B.4-


SetMode(0x03); // Set standard text mode (03h).
}
/************/
/*** Stop ***/
/************/
void Stop()
{
getch(); // Provides a pause .
}
/*************/
/*** Pixel ***/
/*************/
void Pixel(int X, int Y, Byte Color)
{
pokeb(VGA_RAM, X+Y * 320, Color);
}
/********************/
/*** BoundedPixel ***/
/********************/
void BoundedPixel(int X, int Y, Byte Color)
{
if( (X > 0) && (Y > 0) && (X < MAXX) && (Y < MAXY) )
pokeb(VGA_RAM, X+Y*320, Color);
}
/****************/
/*** GetPixel ***/
/****************/
Byte GetPixel(int X, int Y)
{
return peekb(VGA_RAM, X+Y * 320);
}
/************/
/*** Line ***/
/************/
void Line(int X1, int Y1, int X2, int Y2, Byte Color)
{
int XDist, YDist; // X and Y distances.
int XDir, YDir; // X and Y directions.
int XCount, YCount; // X and Y counters.
int XYInc; // X and Y incrementer.

int Sign(int Number);

if (X1 == X2)
{
int X = X1;
if (Y1 > Y2)
{
int Temp = Y1;
Y1 = Y2;
Y2 = Temp;
} // End if.
for(int Y = Y1; Y <= Y2; Y++)
pokeb(VGA_RAM, X + Y * 320, Color);
} // End if.
else
{
if(Y1 == Y2)
{
int Y = Y1;
if(X1 > X2)
{
int Temp = X1;
X1 = X2;

Appendix B Include Libraries -B.5-


X2 = Temp;
} // End if.
memset(VGAMEM + X1 + Y * 320, Color, X2 - X1 + 1);
} // End if.
} // End else.

if ( ! ((X1 == X2) || (Y1 == Y2)) )


{
XDist = X2 - X1;
YDist = Y2 - Y1;
XDir = Sign(XDist);
YDir = Sign(YDist);
XDist = abs(XDist);
YDist = abs(YDist);
XCount = X1;
YCount = Y1;
XYInc = 0;
while ((XCount != X2) || (YCount != Y2))
{
pokeb(VGA_RAM, XCount + YCount * 320, Color);
if (YDist < XDist)
{
XYInc += YDist;
XCount += XDir;
if (XYInc >= XDist)
{
XYInc -= XDist;
YCount += YDir;
} // End if.
} // End if.
else
{
XYInc += XDist;
YCount += YDir;
if (XYInc >= YDist)
{
XYInc -= YDist;
XCount += XDir;
} // End if.
} // End else.
} // End While.
pokeb(VGA_RAM, XCount + YCount * 320, Color);
} // End if.
}
/*******************/
/*** BoundedLine ***/
/*******************/
void BoundedLine(int X1, int Y1, int X2, int Y2, Byte Color)
{
int XDist, YDist; // X and Y distances.
int XDir, YDir; // X and Y directions.
int XCount, YCount; // X and Y counters.
int XYInc; // X and Y incrementer.

void DoNothing(); // Does absolutely nothing.


int Sign(int Number); // Returns the sign of a number.

if (X1 == X2)
{
if (Y1 > Y2)
{
int Temp = Y1;
Y1 = Y2;
Y2 = Temp;

Appendix B Include Libraries -B.6-


} // End if.
if( (X1 < 0) || (Y1 < 0) || (X1 > MAXX) || (Y1 > MAXY) )
goto Exit;
if(Y2 > MAXY)
Y2 = MAXY;
if (Y1 < 0)
Y1 = 0;
int X = X1;
for(int Y = Y1; Y <= Y2; Y++)
pokeb(VGA_RAM, X+Y*320, Color);
} // End if.
else
{
if(Y1 == Y2)
{
if(X1 > X2)
{
int Temp = X1;
X1 = X2;
X2 = Temp;
} // End if.
if( (X1 < 0) || (Y2 < 0) || (X1 > MAXX) || (Y1 > MAXY) )
goto Exit;
if(X2 > MAXX)
X2 = MAXX;
if (X1 < 0)
X1 = 0;
int Y = Y1;
for(int X = X1; X <= X2; X++)
pokeb(VGA_RAM, X+Y*320, Color);
} // End if.
} // End else.

if ( ! ((X1 == X2) || (Y1 == Y2)) )


{
XDist = X2 - X1;
YDist = Y2 - Y1;
XDir = Sign(XDist);
YDir = Sign(YDist);
XDist = abs(XDist);
YDist = abs(YDist);
XCount = X1;
YCount = Y1;
XYInc = 0;
while ((XCount != X2) || (YCount != Y2))
{
BoundedPixel(XCount, YCount, Color);
if (YDist < XDist)
{
XYInc += YDist;
XCount += XDir;
if (XYInc >= XDist)
{
XYInc -= XDist;
YCount += YDir;
} // End if.
} // End if.
else
{
XYInc += XDist;
YCount += YDir;
if (XYInc >= YDist)
{
XYInc -= YDist;

Appendix B Include Libraries -B.7-


XCount += XDir;
} // End if.
} // End else.
} // End While.
BoundedPixel(XCount, YCount, Color);
} // End if.
Exit: DoNothing();
}

int Sign(int Number)


{
if (Number < 0)
return -1;
else
return +1;
}

void DoNothing()
{ }
/*****************/
/*** Rectangle ***/
/*****************/
void Rectangle(int X1, int Y1, int X2, int Y2, Byte Color, Boolean
Filled)
{
void HLine(int X1, int X2, int Y1, Byte Color);
void VLine(int Y1, int Y2, int X1, Byte Color);

if (Filled)
for (int Y = Y1; Y <= Y2; Y++)
memset(VGAMEM + Y * 320 + X1, Color, X2 - X1 + 1);
else
{
HLine(X1, X2, Y1, Color);
HLine(X1, X2, Y2, Color);
VLine(Y1, Y2, X1, Color);
VLine(Y1, Y2, X2, Color);
} // End else.
}

void HLine(int X1, int X2, int Y1, Byte Color)


{
memset(VGAMEM + Y1 * 320 + X1, Color, X2 - X1 + 1);
}

void VLine(int Y1, int Y2, int X1, Byte Color)


{
for (int Y = Y1; Y <= Y2; Y++)
pokeb(VGA_RAM, X1 + Y * 320, Color);
}
/************************/
/*** BoundedRectangle ***/
/************************/
void BoundedRectangle(int X1, int Y1, int X2, int Y2, Byte Color, Boolean
Filled)
{
void BHLine(int X1, int X2, int Y1, Byte Color);
void BVLine(int Y1, int Y2, int X1, Byte Color);

if(X1 < 0) X1 = 0;
if(Y1 < 0) Y1 = 0;
if(X2 < 0) X2 = 0;
if(Y2 < 0) Y2 = 0;
if(X1 > MAXX) X1 = MAXX;

Appendix B Include Libraries -B.8-


if(Y1 > MAXY) Y1 = MAXY;
if(X2 > MAXX) X2 = MAXX;
if(Y2 > MAXY) Y2 = MAXY;
if(Filled)
for (int Y=Y1; Y<=Y2; Y++)
memset(VGAMEM + Y * 320 + X1, Color, X2 - X1 + 1);
else
{
BHLine(X1, X2, Y1, Color);
BHLine(X1, X2, Y2, Color);
BVLine(Y1, Y2, X1, Color);
BVLine(Y1, Y2, X2, Color);
}
}

void BHLine(int X1, int X2, int Y1, Byte Color)


{
memset(VGAMEM + Y1 * 320 + X1, Color, X2 - X1 + 1);
}

void BVLine(int Y1, int Y2, int X1, Byte Color)


{
for (int Y = Y1; Y <= Y2; Y++)
Pixel(X1, Y, Color);
}
/******************/
/*** MakeTables ***/
/******************/
void MakeTables()
{
float Radian; // Radian measure.

for (int X=0; X<=629; X++)


{
Radian = float(X) / 100;
SinTab[X] = sin(Radian);
CosTab[X] = cos(Radian);
} // End for loop.
}
/**************/
/*** Circle ***/
/**************/
void Circle(int CX, int CY, int Radius, Byte Color)
{
int X, Y; // X and Y coordinate.
for (int K = 1; K <= 629; K++)
{
X = Radius * CosTab[K] + CX;
Y = Radius * SinTab[K] * AR + CY;
pokeb(VGA_RAM, X+Y*320, Color);
} // End for loop.
}
/*********************/
/*** BoundedCircle ***/
/*********************/
void BoundedCircle(int CX, int CY, int Radius, Byte Color)
{
const QTR1 = 157; // First Quarter.
const QTR2 = 314; // Second Quarter.
const QTR3 = 471; // Third Quarter.
const QTR4 = 627; // Fourth Quarter ... not used in this
program.

int X, Y; // X and Y Coordinates.

Appendix B Include Libraries -B.9-


Boolean On; // Check if the pixel is on screen.
Boolean Tmp; // Check if the pixel is on screen.

On = InBounds(CosTab[0] * Radius + CX,


SinTab[0] * Radius * AR + CY);

for (int K=1; K<=629; K++)


{
X = Radius * CosTab[K] + CX;
Y = Radius * SinTab[K] * AR + CY;
Tmp = InBounds(X, Y);
if ( !Tmp && On )
{
if (K < QTR1) K = QTR1;
if (K > QTR3) K = QTR4;
if((K > QTR1) && (K < QTR2)) K = QTR2;
if((K > QTR2) && (K < QTR3)) K = QTR3;
} // End if.
else if (Tmp)
pokeb(VGA_RAM, X + Y * 320, Color);
On = Tmp;
} // End for loop.
}
/***************/
/*** Ellipse ***/
/***************/
void Ellipse(int CX, int CY, int XR, int YR, Byte Color)
{
int X, Y; // X and Y coordinate.
for (int K = 1; K <= 629; K++)
{
X = XR * CosTab[K] + CX;
Y = YR * SinTab[K] * AR + CY;
pokeb(VGA_RAM, X+Y*320, Color);
} // End for loop.
}
/**********************/
/*** BoundedEllipse ***/
/**********************/
void BoundedEllipse(int CX, int CY, int XR, int YR, Byte Color)
{
const QTR1 = 157; // First Quarter.
const QTR2 = 314; // Second Quarter.
const QTR3 = 471; // Third Quarter.
const QTR4 = 627; // Fourth Quarter ... not used in this
program.

int X, Y; // X and Y Coordinates.


Boolean On; // Check if the pixel is on screen.
Boolean Tmp; // Check if the pixel is on screen.

On = InBounds(CosTab[0] * XR + CX,
SinTab[0] * YR * AR + CY);

for (int K=1; K<=629; K++)


{
X = XR * CosTab[K] + CX;
Y = YR * SinTab[K] * AR + CY;
Tmp = InBounds(X, Y);
if ( !Tmp && On )
{
if (K < QTR1) K = QTR1;
if (K > QTR3) K = QTR4;
if((K > QTR1) && (K < QTR2)) K = QTR2;

Appendix B Include Libraries -B.10-


if((K > QTR2) && (K < QTR3)) K = QTR3;
} // End if.
else if (Tmp)
pokeb(VGA_RAM, X + Y * 320, Color);
On = Tmp;
} // End for loop.
}
/***********/
/*** Arc ***/
/***********/
void Arc(int CX, int CY, int XR, int YR, float Start, float Finish,
Byte Color)
{
int X, Y; // X and Y Coordinates.
int RealK; // Check K for wrap-around.

int Start2 = Start * 100;


int Finish2 = Finish * 100;
int Direction = (Finish > Start) ? 1 : -1;
for (int K=Start2; K<=Finish2; K+=Direction)
{
RealK = (K > 629) ? K - 629 : K;
X = XR * CosTab[RealK] + CX;
Y = YR * SinTab[RealK] * AR + CY;
pokeb(VGA_RAM, X + Y * 320, Color);
} // End for loop.
}
/******************/
/*** BoundedArc ***/
/******************/
void BoundedArc(int CX, int CY, int XR, int YR,
float Start, float Finish, Byte Color)
{
const QTR1 = 157; // First Quarter.
const QTR2 = 314; // Second Quarter.
const QTR3 = 471; // Third Quarter.
const QTR4 = 627; // Fourth Quarter

int X, Y; // X and Y Coordinates.


Boolean On; // Check if the pixel is on screen.
Boolean Tmp; // Check if the pixel is on screen.
int RealK; // Check K for wrap-around.

int Start2 = Start * 100;


int Finish2 = Finish * 100;
int Direction = (Finish > Start) ? 1 : -1;

On = InBounds(CosTab[0] * XR + CX,
SinTab[0] * YR * AR + CY);

for (int K=Start2; K<=Finish2; K+=Direction)


{
RealK = (K > 629) ? K - 629 : K;
X = XR * CosTab[RealK] + CX;
Y = YR * SinTab[RealK] * AR + CY;
Tmp = InBounds(X, Y);
if ( !Tmp && On )
{
if (K < QTR1) K = QTR1;
if (K > QTR3) K = QTR4;
if((K > QTR1) && (K < QTR2)) K = QTR2;
if((K > QTR2) && (K < QTR3)) K = QTR3;
} // End if.
else if (Tmp)

Appendix B Include Libraries -B.11-


pokeb(VGA_RAM, X + Y * 320, Color);
On = Tmp;
} // End for loop.
}
/*****************/
/*** FloodFill ***/
/*****************/
void FloodFill(int X, int Y, Byte NewColor)
{
int XTR, YTR; // Temporary x and y values.

void QuadFlood(int X, int Y, Byte NewColor);

OldColor = GetPixel(X, Y);

// Draw horizontal line to left.


XTR = X;
YTR = Y;
do
{
pokeb(VGA_RAM, XTR+YTR*320, NewColor);
XTR--;
} // End do loop.
while( (GetPixel(XTR, YTR) == OldColor) && (XTR > 0) );

// Draw horizontal line to right.


XTR = X;
YTR = Y;
do
{
pokeb(VGA_RAM, XTR+YTR*320, NewColor);
XTR++;
} // End do loop.
while( (GetPixel(XTR, YTR) == OldColor) && (XTR < MAXX) );

// Draw vertical line to bottom.


XTR = X;
YTR = Y;
do
{
pokeb(VGA_RAM, XTR+YTR*320, NewColor);
YTR++;
} // End do loop.
while( (GetPixel(XTR, YTR) == OldColor) && (YTR < MAXY) );

// Draw vertical line to top.


XTR = X;
YTR = Y;
do
{
pokeb(VGA_RAM, XTR+YTR*320, NewColor);
YTR--;
} // End do loop.
while( (GetPixel(XTR, YTR) == OldColor) && (YTR > 0) );

QuadFlood(X-1, Y-1, NewColor);


QuadFlood(X+1, Y-1, NewColor);
QuadFlood(X+1, Y+1, NewColor);
QuadFlood(X-1, Y+1, NewColor);
} // End void function Flood.

void QuadFlood(int X, int Y, Byte NewColor)


{
Coord Temp; // Temporary coordinate.

Appendix B Include Libraries -B.12-


Boolean RangeOK(Coord Temp);
void MoveToNext(Coord& N);

TopOfStack = 1;
Temp.X = X;
Temp.Y = Y;
do
{
if( (GetPixel(Temp.X, Temp.Y) == OldColor) && RangeOK(Temp) )
{
pokeb(VGA_RAM, Temp.X + Temp.Y * 320, NewColor);
Push(Temp);
MoveToNext(Temp);
} // End if.
else
{
Pop(Temp);
MoveToNext(Temp);
} // End else.
} // End do loop.
while(TopOfStack > 0);
} // End void function Flood::QuadFlood.

Boolean RangeOK(Coord N)
{
return Boolean( (N.X >= 0) && (N.X <= MAXX) &&
(N.Y >= 0) && (N.Y <= MAXY) );
} // End function Flood::RangeOK.

void MoveToNext(Coord& N)
{
if ( ( GetPixel(N.X+1, N.Y) == OldColor ) )
N.X++;
else if ( ( GetPixel(N.X, N.Y -1) == OldColor ) )
N.Y--;
else if ( ( GetPixel(N.X-1, N.Y) == OldColor ) )
N.X--;
else if ( ( GetPixel(N.X, N.Y+1) == OldColor ) )
N.Y++;
} // End void function Flood::MoveToNext.
/************/
/*** Push ***/
/************/
void Push(Coord N)
{
if (TopOfStack >= FLOODSIZE)
TopOfStack -= FLOODSIZE;
TopOfStack++;
Stack[TopOfStack] = N;
} // End void function Push.
/***********/
/*** Pop ***/
/***********/
void Pop(Coord& N)
{
if (TopOfStack > 0)
{
N = Stack[TopOfStack];
TopOfStack--;
} // End if.
}
/****************/
/*** ClearGfx ***/

Appendix B Include Libraries -B.13-


/****************/
void ClearGfx(Byte Color)
{
memset(VGAMEM,Color,64000);
}
/*************/
/*** Flood ***/
/*************/
void Flood(int X, int Y, Byte NewColor)
{
void RecursiveFill(int X, int Y, Byte OldColor, Byte NewColor); //
Function prototype.

Byte OldColor = GetPixel(X,Y);


RecursiveFill(X,Y,OldColor, NewColor);
}
void RecursiveFill(int X, int Y, Byte OldColor, Byte NewColor)
{
Boolean Stuck = False;

if (GetPixel(X,Y) != OldColor)
Stuck = True;
if ((X < MINX) || (X > MAXX))
Stuck = True;
if ((Y < MINY) || (Y > MAXY))
Stuck = True;
if (!Stuck)
{
Pixel(X, Y, NewColor);
RecursiveFill(X+1, Y, OldColor, NewColor);
RecursiveFill(X-1, Y, OldColor, NewColor);
RecursiveFill( X, Y+1, OldColor, NewColor);
RecursiveFill( X, Y-1, OldColor, NewColor);
} // End if.
}
/*************/
/*** Round ***/
/*************/
int Round(float X)
{
return (floor(X+0.05));
}
/*****************/
/*** SaveImage ***/
/*****************/
void SaveImage(char* FName, int Left, int Top, int Right, int Bottom)
{
ofstream Outfile(FName, ios::binary);
unsigned int Width = Right - Left + 1;
unsigned int Height = Bottom - Top + 1;
unsigned char Buffer[320];
unsigned char Temp[2];

Temp[0] = Width; // Temp[0] = 1st byte of Width.


Temp[1] = Width >> 8; // Temp[1] = 2nd byte after swapping bytes.
Outfile.write(Temp,2); // Write Width to file.
Temp[0] = Height; // Temp[0] = 1st byte of Height.
Temp[1] = Height >> 8; // Temp[1] = 2nd byte after swapping bytes.
Outfile.write(Temp,2); // Write Height to file.

for (int Row = Top; Row <= Bottom; Row++)


{
memcpy(Buffer, VGAMEM + Left + Row * 320, Width);
Outfile.write(Buffer, Width);

Appendix B Include Libraries -B.14-


} // End for loop.
Outfile.close();
}
/*****************/
/*** LoadImage ***/
/*****************/
void LoadImage(char* FileName, int Left, int Top)
{
ifstream Infile(FileName, ios::binary);
int Width;
int Height;
unsigned char Buffer[320];
unsigned char Temp[2];
Infile.read(Temp, 2);
Width = (Temp[1] << 8) + Temp[0];
Infile.read(Temp, 2);
Height = (Temp[1] << 8) + Temp[0];

for (int Row = Top; Row <= Top+Height-1; Row++)


{
Infile.read(Buffer, Width);
memcpy(VGAMEM + Row * 320 + Left, Buffer, Width);
} // End for loop.
Infile.close();
}
#endif
─────────────────────────────────────────────────────────────────────────

Appendix B Include Libraries -B.15-


GFX640.HPP
─────────────────────────────────────────────────────────────────────────
/************************************************************************/
/*** NOTE: THIS LIBRARY MUST BE COMPILED USING A "LARGE" OR GREATER ***/
/*** SIZED MEMORY MODEL. IF IT IS NOT, IT MAY CRASH ON ***/
/*** EXECUTION. THE MEMORY MODEL CAN BE SPECIFIED IN "OPTIONS / ***/
/*** COMPILER / CODE GENERATION." ***/
/************************************************************************/
/*** GFX640 combimes all the graphics routines in one library of ***/
/*** optimized and altered routines and functions. This library ***/
/*** represents the first library that is suitable for actual ***/
/*** graphics programming. It is still not the last library. ***/
/*** There are many more routines to be introduced and there will ***/
/*** also be additional optimization. ***/
/************************************************************************/
#ifndef _GFX640_HPP
#define _GFX640_HPP

#include <dos.h>
#include <conio.h>
#include <math.h>
/*********************************************************************/
/*** USER DEFINED AND ENUMERATED DATA TYPES ***/
/*********************************************************************/
typedef unsigned short Byte; // Byte type definition.
typedef unsigned int Word; // Word type definition.
enum Boolean {False,True}; // Boolean type definition.
/*********************************************************************/
/*** CONSTANT VARIABLE IDENTIFIERS ***/
/*********************************************************************/
const int MINX = 0; // Minimum x coordinate value.
const int MIDX = 320; // Midpoint x coordinate value.
const int MAXX = 639; // Maximum x coordinate value.
const int MINY = 0; // Minimum y coordinate value.
const int MIDY = 240; // Midpoint y coordinate value.
const int MAXY = 479; // Maximum y coordinate value.
const int MAXC = 16; // Maximum number of colors.
const float AR = 1.05; // Aspect ratio to make circles symetrical.
const float TWOPI = 6.28; // Approximation of 2 * PI.
const Boolean CLOSED = True; // Constant to draw filled-in rectangle.
const Boolean OPEN = False; // Constant to draw open rectangle.
/*********************************************************************/
/*** GLOBAL VARIABLE IDENTIFIERS ***/
/*********************************************************************/
float SinTab[630]; // Sin lookup table.
float CosTab[630]; // Cos loopup table.
/*********************************************************************/
/*** FUNCTION PROTOTYPES ***/
/*********************************************************************/
void SetMode(Byte Mode);
void StartGfx();
void EndGfx();
void Stop();
void Pixel(int X, int Y, Byte Color);
Byte GetPixel(int X, int Y);
void Line(int X1, int Y1, int X2, int Y2, Byte Color);
void Rectangle(int X1, int Y1, int X2, int Y2, Byte Color,
Boolean Filled);
void MakeTables();
void Circle(int CX, int CY, int Radius, Byte Color);
void Ellipse(int CX, int CY, int XR, int YR, Byte Color);
void Arc(int CX, int CY, int XR, int YR, float Start, float Finish,
Byte Color);

Appendix B Include Libraries -B.16-


void FloodFill(int X, int Y, Byte NewColor);
void ClearGfx(Byte Color);
int Round(float X);
/*********************************************************************/
/*** FUNCTION IMPLEMENTATIONS ***/
/*********************************************************************/
/*** Set Mode ***/
/*********************/
void SetMode(Byte Mode)
{
_AH = 0x00; // Select "set video mode" function (00h)
_AL = Mode; // Set mode selected.
geninterrupt(0x10); // Call video interrupt (10h).
}
/*********************/
/*** Start GFX ***/
/*********************/
void StartGfx()
{
SetMode(0x12); // Set MCGA 320x200x256 mode (13h).
MakeTables();
}
/*********************/
/*** End GFX ***/
/*********************/
void EndGfx()
{
SetMode(0x03); // Set standard text mode (03h).
}
/*********************/
/*** Stop ***/
/*********************/
void Stop()
{
getch(); // Provides a pause .
}
/*********************/
/*** Pixel ***/
/*********************/
void Pixel(int X, int Y, Byte Color)
{
_AH = 0x0C;
_AL = Color;
_BH = 0;
_CX = X;
_DX = Y;
geninterrupt(0x10);
}
/*********************/
/*** GetPixel ***/
/*********************/
Byte GetPixel(int X, int Y)
{
_AH = 0x0D;
_CX = X;
_DX = Y;
geninterrupt(0x10);
return _AL;
}
/*********************/
/*** Line ***/
/*********************/
void Line(int X1, int Y1, int X2, int Y2, Byte Color)
{

Appendix B Include Libraries -B.17-


int XDist, YDist; // X and Y distances.
int XDir, YDir; // X and Y directions.
int XCount, YCount; // X and Y counters.
int XYInc; // X and Y incrementer.

int Sign(int Number);

if (X1 == X2)
{
int X = X1;
if (Y1 > Y2)
{
int Temp = Y1;
Y1 = Y2;
Y2 = Temp;
} // End if.
for(int Y = Y1; Y <= Y2; Y++)
Pixel(X,Y,Color);
} // End if.
else
{
if(Y1 == Y2)
{
int Y = Y1;
if(X1 > X2)
{
int Temp = X1;
X1 = X2;
X2 = Temp;
} // End if.
for (int X=X1; X<=X2; X++)
Pixel(X,Y,Color);
} // End if.
} // End else.

if ( ! ((X1 == X2) || (Y1 == Y2)) )


{
XDist = X2 - X1;
YDist = Y2 - Y1;
XDir = Sign(XDist);
YDir = Sign(YDist);
XDist = abs(XDist);
YDist = abs(YDist);
XCount = X1;
YCount = Y1;
XYInc = 0;
while ((XCount != X2) || (YCount != Y2))
{
Pixel(XCount, YCount, Color);
if (YDist < XDist)
{
XYInc += YDist;
XCount += XDir;
if (XYInc >= XDist)
{
XYInc -= XDist;
YCount += YDir;
} // End if.
} // End if.
else
{
XYInc += XDist;
YCount += YDir;
if (XYInc >= YDist)

Appendix B Include Libraries -B.18-


{
XYInc -= YDist;
XCount += XDir;
} // End if.
} // End else.
} // End While.
Pixel(XCount, YCount, Color);
} // End if.
} // End void function Line.

int Sign(int Number)


{
if (Number < 0)
return -1;
else
return +1;
} // End function Line::Sign.
/*********************/
/*** Rectangle ***/
/*********************/
void Rectangle(int X1, int Y1, int X2, int Y2, Byte Color, Boolean
Filled)
{
if (Filled)
for (int Y = Y1; Y <= Y2; Y++)
Line(X1, Y, X2, Y, Color);
else
{
Line(X1, Y1, X2, Y1, Color);
Line(X1, Y2, X2, Y2, Color);
Line(X1, Y1, X1, Y2, Color);
Line(X2, Y1, X2, Y2, Color);
} // End else.
}
/*********************/
/*** MakeTables ***/
/*********************/
void MakeTables()
{
float Radian; // Radian measure.

for (int X=0; X<=629; X++)


{
Radian = float(X) / 100;
SinTab[X] = sin(Radian);
CosTab[X] = cos(Radian);
} // End for loop.
}
/*********************/
/*** Circle ***/
/*********************/
void Circle(int CX, int CY, int Radius, Byte Color)
{
int X, Y; // X and Y coordinate.
for (int K = 1; K <= 629; K++)
{
X = Radius * CosTab[K] + CX;
Y = Radius * SinTab[K] * AR + CY;
Pixel(X,Y,Color);
} // End for loop.
}
/*********************/
/*** Ellipse ***/
/*********************/

Appendix B Include Libraries -B.19-


void Ellipse(int CX, int CY, int XR, int YR, Byte Color)
{
int X, Y; // X and Y coordinate.
for (int K = 1; K <= 629; K++)
{
X = XR * CosTab[K] + CX;
Y = YR * SinTab[K] * AR + CY;
Pixel(X,Y,Color);
} // End for loop.
}
/*********************/
/*** Arc ***/
/*********************/
void Arc(int CX, int CY, int XR, int YR, float Start, float Finish, Byte
Color)
{
int X, Y; // X and Y coordinate.

int Start2 = Start * 100;


int Finish2 = ((Finish * 100) < 629) ? (Finish * 100) : 629;
for (int K = Start2; K <= Finish2; K++)
{
X = XR * CosTab[K] + CX;
Y = YR * SinTab[K] * AR + CY;
Pixel(X,Y,Color);
} // End for loop.
}
/*********************/
/*** FloodFill ***/
/*********************/
void FloodFill(int X, int Y, Byte NewColor)
{
void RecursiveFill(int X, int Y, Byte OldColor, Byte NewColor);

Byte OldColor = GetPixel(X,Y);


RecursiveFill(X,Y,OldColor, NewColor);
}
void RecursiveFill(int X, int Y, Byte OldColor, Byte NewColor)
{
Boolean Stuck = False;

if (GetPixel(X,Y) != OldColor)
Stuck = True;
if ((X < MINX) || (X > MAXX))
Stuck = True;
if ((Y < MINY) || (Y > MAXY))
Stuck = True;
if (!Stuck)
{
Pixel(X, Y, NewColor);
RecursiveFill(X+1, Y, OldColor, NewColor);
RecursiveFill(X-1, Y, OldColor, NewColor);
RecursiveFill( X, Y+1, OldColor, NewColor);
RecursiveFill( X, Y-1, OldColor, NewColor);
} // End if.
}
/*********************/
/*** ClearGfx ***/
/*********************/
void ClearGfx(Byte Color)
{
Rectangle(MINX, MINY, MAXX, MAXY, Color, CLOSED);
}
/*********************/

Appendix B Include Libraries -B.20-


/*** Round ***/
/*********************/
int Round(float X)
{
return ( floor(X+0.5) );
}
#endif
─────────────────────────────────────────────────────────────────────────

Appendix B Include Libraries -B.21-


COLOR.HPP
─────────────────────────────────────────────────────────────────────────
/**********************************************************************/
/*** The COLOR.HPP library contains all the color-related routines ***/
/*** introduced in this book. All the routines here are the most ***/
/*** updated and optimized routines introduced. ***/
/**********************************************************************/
#ifndef _COLOR_HPP
#define _COLOR_HPP

#include "GFX320.HPP"

struct RGBSignature
{
Byte Red;
Byte Grn;
Byte Blu;
}; // End struct RGBSignature.

typedef RGBSignature PaletteType[256];

// Global array of different color palettes.


PaletteType GlobalPalette;

// Allows the RGB palette for each one of the 256 different colors.
void SetRGB(Byte Num, RGBSignature Sig);

// Sets the RGB palette for each one of the 256 different colors based
// on the values in the global palette array.
void SetPalette(PaletteType P);

// Sets the RGB palette with 256 combinations of color so that


// red, green, and blue gradually fade into each other.
void MakeRainbow(PaletteType P);

// Cycles the RGB palette of the global array palette to the


// next color value. Doing this continuously simulates a motion
// of colors.
void CyclePalette(PaletteType P);

void SetRGB(Byte Num, RGBSignature Sig)


{
_AH = 0x10;
_AL = 0x10;
_BX = Num;
_CH = Sig.Grn;
_CL = Sig.Blu;
_DH = Sig.Red;
geninterrupt(0x10);
} // End void function SetRGB.

void SetPalette(PaletteType P)
{
unsigned Segment, Offset; // Segment and offset of array.
unsigned char MyPal[768]; // Temporary palette.

for(int K=0; K<=255; K++)


{
MyPal[K*3] = P[K].Red;
MyPal[K*3+1] = P[K].Grn;
MyPal[K*3+2] = P[K].Blu;
} // End for loop.
Segment = FP_SEG(MyPal);
Offset = FP_OFF(MyPal);

_AH = 0x10; // Bios function $10, set palette.


_AL = 0x12; // Subfunction $12, set a block.

Appendix B Include Libraries -B.22-


_BX = 0; // First color number of block.
_CX = 256; // Last color number of block.
_ES = Segment; // Segment address of block.
_DX = Offset; // Offset address of block.
geninterrupt(0x10); // Call the interrupt function.
} // End void function SetPallette.

void MakeRainbow(PaletteType P)
{
Byte Count;
for (Count=0; Count<=63; Count++)
{
P[Count].Red = Count;
P[Count].Grn = 0;
P[Count].Blu = 0;
} // End for loop.
for (Count=64; Count<=127; Count++)
{
P[Count].Red = 127 - Count;
P[Count].Grn = Count - 64;
P[Count].Blu = 0;
} // End for loop.
for (Count=128; Count<=191; Count++)
{
P[Count].Red = 0;
P[Count].Grn = 191 - Count;
P[Count].Blu = Count - 128;
} // End for loop.
for (Count=192; Count<=255; Count++)
{
P[Count].Red = 0;
P[Count].Grn = 0;
P[Count].Blu = 255 - Count;
} // End for loop.
} // End void function MakeRainbow.

void CyclePalette(PaletteType P)
{
Byte Count;
RGBSignature T;

T = P[1];
for(Count=1; Count<=254; Count++)
P[Count] = P[Count + 1];
P[255] = T;
} // End void function CyclePalette.
#endif

─────────────────────────────────────────────────────────────────────────

Appendix B Include Libraries -B.23-


ANIMATE.HPP
─────────────────────────────────────────────────────────────────────────
/***********************************************************************/
/*** ANIMATE.HPP is a collection of all the animation-related
***/
/*** routines introduced.
***/
/***********************************************************************/
/*** NOTE: The heap size for programs using this file ***/
/*** must be greater than 64k. This setting may ***/
/*** be altered under "OPTIONS/DEBUGGER". ***/
/***********************************************************************/
#ifndef _ANIMATE_HPP
#define _ANIMATE_HPP

#include <stdlib.h>
#include "GFXLIB8.HPP"

struct SpriteType
{
int X, Y; // X and Y position of the sprite.
int OldX, OldY; // Old X and Y position of the sprite.
int Height, Width; // Height and Width of the sprite.
char* Bitmap; // Pointer to the sprite bitmap data.
char* Beneath; // Pointer to data beneath bitmap.
}; // End struct SpriteType.
/*********************************************************************/
/*** GLOBAL CONSTANTS ***/
/*********************************************************************/
const SCREEN_SIZE = 64000; // 320 x 200 pixels.
/*********************************************************************/
/*** FUNCTION PROTOTYPES ***/
/*********************************************************************/
void LoadSprite(char* Filename, SpriteType& Image);
void PutSprite(SpriteType Image);
void ReleaseSprite(SpriteType Image);
void SetupVirtual (char*& Where);
void DestroyVirtualPage(char*& Where);
void FlipPage(char* Source, char* Destination);
void WhPutSprite(SpriteType Image, char* Where);
void WhEraseSprite(SpriteType Image, char* Where);
void WhGetSprite(SpriteType Image, char* Where);
void WhPixel (int X, int Y, Byte Color, char* Where);
Byte WhGetPixel(int X, int Y, char* Where);
void WhTransPutSprite(SpriteType Image, char* Where);
void FlipPortion(SpriteType Image, char* Where);
/*********************************************************************/
/*** FUNCTION IMPLEMENTATIONS ***/
/*********************************************************************/
void LoadSprite(char* Filename, SpriteType& Image)
{
ifstream Infile(Filename, ios::binary); // Open input file.
unsigned char Temp[2]; // Two byte bufffer.

Infile.read(Temp,2);
Image.Width = (Temp[1] << 8) + Temp[0];
Infile.read(Temp,2);
Image.Height = (Temp[1] << 8) + Temp[0];

Image.Bitmap = (char*) malloc(Image.Height * Image.Width);


Image.Beneath = (char*) malloc(Image.Height * Image.Width);

Appendix B Include Libraries -B.24-


if (Image.Bitmap == NULL)
{
EndGfx();
cout << "Memory allocation error. Execution terminated." << endl;
exit(1);
} // End if.
for (int Row = 0; Row <= Image.Height; Row++)
Infile.read(Image.Bitmap + Row * Image.Width, Image.Width);
Infile.close();
} // End void function LoadSprite.

void PutSprite(SpriteType Image)


{
unsigned Segment, Offset;
Byte Color;

Segment = FP_SEG(Image.Bitmap);
Offset = FP_OFF(Image.Bitmap);
for (int Loop1 = 0; Loop1 < Image.Width; Loop1++)
for (int Loop2 = 0; Loop2 < Image.Height; Loop2++)
{
Color = peekb(Segment, Offset + Loop1 + Loop2 * Image.Height);
Pixel(Image.X + Loop1, Image.Y + Loop2, Color);
} // End for loop.
} // End void function PutSprite.

void ReleaseSprite(SpriteType Image)


{
free(Image.Bitmap);
free(Image.Beneath);
} // End void function RelaseSprite.

void SetupVirtual (char*& Where)


{
Where = (char*) malloc(SCREEN_SIZE);
if (Where == NULL)
{
EndGfx();
cout << "Unable to allocate memory for virtual screen." << endl
<< "Execution terminated ....";
Stop();
exit(1);
} // End if.
} // End void function SetupVirtual.

void DestroyVirtualPage(char*& Where)


{
if (Where != NULL) free(Where);
} // End void function DestroyVirtualPage.

void FlipPage(char* Source, char* Destination)


{
memcpy(Destination, Source, SCREEN_SIZE);
} // End void function FlipPage.

void WhPutSprite(SpriteType Image, char* Where)


{
for (int Row = 0; Row < Image.Height; Row++)
memcpy(Where + Image.X + (Image.Y + Row) * 320,
Image.Bitmap + Row * Image.Width,
Image.Width);
} // End void function WhPutSprite.

void WhEraseSprite(SpriteType Image, char* Where)

Appendix B Include Libraries -B.25-


{
for (int Row = 0; Row < Image.Height; Row++)
memcpy(Where + Image.X + (Image.Y + Row) * 320,
Image.Beneath + Row * Image.Width,
Image.Width);
} // End void function WhEraseSprite.

void WhGetSprite(SpriteType Image, char* Where)


{
for (int Row = 0; Row < Image.Height; Row++)
memcpy(Image.Beneath + Row * Image.Width,
Where + Image.X + (Image.Y + Row) * 320,
Image.Width);
} // End void function WhGetSprite.

void WhPixel (int X, int Y, Byte Color, char* Where)


{
memset(Where + X + Y * 320, Color, 1);
} // End void function WhPixel.

Byte WhGetPixel(int X, int Y, char* Where)


{
return peekb(FP_SEG(Where), FP_OFF(Where) + X + Y * 320);
} // End void function WhGetPixel.

void FlipPortion(SpriteType Image, char* Where)


{
for (int Loop = 0; Loop < Image.Height; Loop++)
memmove(VGAMEM + Image.X + (Image.Y + Loop) * 320,
Where + Image.X + (Image.Y + Loop) * 320,
Image.Width);
for (Loop = 0; Loop < Image.Height; Loop++)
memmove(VGAMEM + Image.OldX + (Image.OldY + Loop) * 320,
Where + Image.OldX + (Image.OldY + Loop) * 320,
Image.Width);
} // End void function FlipPortion.

void WhTransPutSprite(SpriteType Image, char* Where)


{
unsigned Seg, Ofs;
Byte Color;

Seg = FP_SEG(Image.Bitmap);
Ofs = FP_OFF(Image.Bitmap);
for (int Loop1 = 0; Loop1 < Image.Width; Loop1++)
for (int Loop2 = 0; Loop2 < Image.Height; Loop2++)
{
Color = peekb(Seg, Ofs + Loop1 + Loop2 * Image.Width);
if (Color)
WhPixel(Image.X + Loop1, Image.Y + Loop2, Color, Where);
} // End for loop.
} // End void function WhTransPutSprite.
#endif
─────────────────────────────────────────────────────────────────────────

Appendix B Include Libraries -B.26-


MOUSE.HPP
─────────────────────────────────────────────────────────────────────────
/**********************************************************************/
/*** This is a library of all introduced mouse routines. Some of ***/
/*** these routines have been split up for better customization. ***/
/**********************************************************************/
/*** MOUSE.HPP includes the following routines: ***/
/*** ***/
/*** Boolean DetectMouse(); ***/
/*** void NumberOfButtons(); ***/
/*** void MouseCursorOn(); ***/
/*** void MouseCursorOff(); ***/
/*** void MouseInfo(Word X, Word Y, Byte Buttons); ***/
/*** Word ButtonInfo(); ***/
/*** Word XMousePos(); ***/
/*** Word YMousePos(); ***/
/*** void PlaceMouseCursor(); ***/
/*** void LimitMouseX(Word Xmin, Word Xmax); ***/
/*** void LimitMouseY(Word Ymin, Word Ymax); ***/
/*** void SetMouseBoundary(Word Xmin, Ymin, Xmax, Ymax); ***/
/*** Boolean XYInclusive(Word XVal, YVal, XMin, YMin, XMax, YMax); ***/
/*** void WaitForRelease(); ***/
/**********************************************************************/
#ifndef _MOUSE_HPP
#define _MOUSE_HPP

#include "GFX320.HPP"
#include "BOOL.H"

const MOUSE_INT = 0x33; // Mouse service interrupt value.


const MOUSE_TEST = 0x0000; // Function value to detect mouse.
const CURSOR_ON = 0x0001; // Function value to turn the cursor on
const CURSOR_OFF = 0x0002; // Function value to turn the cursor off.
const MOUSE_INFO = 0x0003; // Function value for button and (x,y) data.
const PLACE_CURSOR = 0x0004; // Function value to relocate cursor.
const LIMIT_X = 0x0007; // Function value to limit x range of cursor.
const LIMIT_Y = 0X0008; // Function value to limit y range of
cursor.
const LEFT = 1; // Left button constant.
const RIGHT = 2; // Right button constant.
const BOTH = 3; // Left and Right button constant.

Boolean DetectMouse()
{
_AX = MOUSE_TEST;
geninterrupt(MOUSE_INT);
return Boolean(_AX == 0xFFFF);
} // End function DetectMouse.

Word NumberOfButtons()
{
_AX = MOUSE_TEST;
geninterrupt(MOUSE_INT);
return _BX;
} // End function Number of Buttons.

void MouseCursorOn()
{
_AX = CURSOR_ON;
geninterrupt(MOUSE_INT);
} // End function MouseCursorOn.

void MouseCursorOff()

Appendix B Include Libraries -B.27-


{
_AX = CURSOR_OFF;
geninterrupt(MOUSE_INT);
} // End function MouseCursorOff.

Appendix B Include Libraries -B.28-


void MouseInfo(Word& X, Word& Y, Byte& Buttons)
{
_AX = MOUSE_INFO;
geninterrupt(MOUSE_INT);
Buttons = _BL;
X = _CX/2; // Must be divided by 2 in mode 0x13
(320x200).
Y = _DX;
} // End void function MouseInfo.

Word ButtonInfo()
{
_AX = MOUSE_INFO;
geninterrupt(MOUSE_INT);
return ( _BL );
} // End function ButtonInfo.

Word XMousePos()
{
_AX = MOUSE_INFO;
geninterrupt(MOUSE_INT);
return ( _CX/2 );
} // End function XMousePos.

Word YMousePos()
{
_AX = MOUSE_INFO;
geninterrupt(MOUSE_INT);
return ( _DX );
} // End function YMousePos.

void PlaceMouseCursor(Word X, Word Y)


{
_AX = 0x0004;
_CX = X * 2;
_DX = Y;
geninterrupt(MOUSE_INT);
} // End void function PlaceMouseCursor.

void LimitMouseX(Word Xmin, Word Xmax)


{
_AX = 0x0007;
_CX = Xmin;
_DX = Xmax;
geninterrupt(MOUSE_INT);
} // End void function LimitMouseX.

void LimitMouseY(Word Ymin, Word Ymax)


{
_AX = 0x0008;
_CX = Ymin;
_DX = Ymax;
geninterrupt(MOUSE_INT);
} // End void function LimitMouseY.

void SetMouseBoundary(Word Xmin, Word Ymin, Word Xmax, Word Ymax)


{
LimitMouseX(Xmin*2, Xmax*2);
LimitMouseY(Ymin, Ymax);
} // End void function SetMouseBoundary.

Boolean XYInclusive(Word Xval,Word Yval,Word Xmin,Word Ymin,Word Xmax,Word Ymax)


{
return Boolean ((Xval>=Xmin)&&(Xval<=Xmax)&&(Yval>=Ymin)&&(Yval<=Ymax));

Appendix B Include Libraries -B.29-


} // End function XYInclusive.

void WaitForRelease()
{
do{} while (ButtonInfo() != 0);
} // End void function WaitForRelease().
#endif
─────────────────────────────────────────────────────────────────────────
SOUND.HPP
─────────────────────────────────────────────────────────────────────────
/**********************************************************************/
/*** SOUND.HPP is a collection of all the sound-related routines ***/
/*** and constants introduced in this book. This library can be ***/
/*** used to create sound and music using the PC speaker. ***/
/**********************************************************************/
#ifndef _SOUND_HPP
#define _SOUND_HPP

#include <dos.h>

const C1 = 131; // low C


const CD1 = 139; // C# or Db
const D1 = 147;
const DE1 = 156; // D# or Eb
const E1 = 165;
const F1 = 175;
const FG1 = 185; // F# or Gb
const G1 = 196;
const GA1 = 208; // G# or Ab
const A1 = 220;
const AB1 = 233; // A# or Bb
const B1 = 247;

const C2 = 262; // middle C


const CD2 = 278; // C# or Db
const D2 = 294;
const DE2 = 312; // D# or Eb
const E2 = 330;
const F2 = 349;
const FG2 = 370; // F# or Gb
const G2 = 392;
const GA2 = 415; // G# or Ab
const A2 = 440;
const AB2 = 466; // A# or Bb
const B2 = 494;

const C3 = 523; // high C


const CD3 = 554; // C# or Db
const D3 = 587;
const DE3 = 622; // D# or Eb
const E3 = 659;
const F3 = 698;
const FG3 = 739; // F# or Gb
const G3 = 783;
const GA3 = 832; // G# or Ab
const A3 = 879;
const AB3 = 932; // A# or Bb
const B3 = 987;

const C4 = 1045; // high C

Appendix B Include Libraries -B.30-


const CD4 = 1108; // C# or Db
const D4 = 1174;
const DE4 = 1224; // D# or Eb
const E4 = 1318;
const F4 = 1396;
const FG4 = 1479; // F# or Gb
const G4 = 1567;
const GA4 = 1660; // G# or Ab
const A4 = 1759;
const AB4 = 1863; // A# or Bb
const B4 = 1974;

void RealDelay(int D);


void Note(int S, int D);

void RealDelay(int D)
{
unsigned int T1,T2;

_AH = 0x0000; //read clock counter subfunction


geninterrupt(0x1A);
T1 = _DX; // get number of ticks since midnight
do
{
_AX = 0x0000; // read clock counter subfunction
geninterrupt(0x1A);
T2 = _DX; // get number of ticks since midnight
} // do
while (!(T2 >= T1 + D * (18.2 / 1000)));
} // void function realdelay

void Note(int S, int D)


{
sound(S);
RealDelay(D);
nosound();
} // void function note

#endif
─────────────────────────────────────────────────────────────────────────

Appendix B Include Libraries -B.31-


BOOL.H
─────────────────────────────────────────────────────────────────────────
/***********************************************************************/
/*** BOOL.H defines the Boolean data type needed for the files ***/
/*** The Bool.H file must be used with Turbo 3.0 since the data type ***/
/*** has not been predefined. ***/
/***********************************************************************/

#ifndef _BOOL_H
#define _BOOL_H

enum Boolean {False,True}; // Boolean type definition.


const Boolean CLOSED = True; // Constant to draw filled-in rectangle.
const Boolean OPEN = False; // Constant to draw open rectangle.

#endif
─────────────────────────────────────────────────────────────────────────
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄

Appendix B Include Libraries -B.32-

You might also like