We're almost done with creating a library, right now we have a single object
file to add to the library. However, we also want to add the object
code for our Line
and Circle
functions
to the library in their own seperate modules. This will ultimately entail
creating a LINE.OBJ
and a CIRCLE.OBJ
file. To have
to keep track of these files can get tedious so what we'll ultimately do is store
them in a library file.
Let's begin by making a library file using VMODE.OBJ
. To do this
we use thee librarian to store one or many objects files into a single library file.
This, of course, eliminates the need to keep track of many individual object code
files and allows us a single library file to reference all of our object code with.
This library file, which we'll call GAMELIB.LIB
, will contain
VMODE.OBJ
and others. Using Turbo C++ at the command prompt, type:
tlib gamelib.lib +vmode.obj, gamelib.txt
The new library is created and the GAMELIB.TXT
file contains the listing.
Now let's add the code for the Line
and Circle
functions
too. To do this, we need header files, here's a header file that we'll use for both.
/* FGRAPH.H -- Floating point graphics. * * Graphics functions which use floating point math. * * by Gary Neal, Jr. */ #ifndef _FGRAPH_H #define _FGRAPH_H /* Prevent further includes */ #include <math.h> /* Needed for sin and cos functions */ #include "vmode.h" /* Needed for ScreenWidth and ScreenHeight */ extern float angleIncr; #ifdef __cplusplus extern "C" { /* Functions must use C type compilation */ #endif void Line(int X1, int Y1, int X2, int Y2, unsigned char C); void Circle(int xOffset, int yOffset, int radius, unsigned char C); #ifdef __cplusplus } #endif #endif /* _FGRAPH_H */
Now for the source code of each function, let's start with the Line
function code:
/* LINE.C -- Line function * * Revised line function that will draw full lines * in any slope at any angle. */ #include "fgraph.h" /* Needed for ScreenWidth & ScreenHeight */ void Line(int X1, int Y1, int X2, int Y2, unsigned char C) { float currX, currY; /* Current pixel to be plotted */ float deltaX, deltaY, slope; /* 2 deltas and slope */ int tempVal; /* Holds temporary values */ deltaX = X2 - X1; /* Get value for delta X */ deltaY = Y2 - Y1; /* Get value for delta Y */ if (deltaX < 0) deltaX = -deltaX; /* Need absolute */ if (deltaY < 0) deltaY = -deltaY; /* values only. */ if (deltaY > deltaX) { /* |slope| > 1 */ if (Y2 < Y1) { /* Swap coordinates, Y1 must be < Y2 */ tempVal = Y2; Y2 = Y1; Y1 = tempVal; tempVal = X2; X2 = X1; X1 = tempVal; } /* Compute deltas and slope */ deltaX = X2 - X1; deltaY = Y2 - Y1; /* Slope off the vertical axis */ slope = deltaX / deltaY; /* Plot each pixel starting at (X1, Y1) */ currX = X1; for (currY = Y1; (currY <= Y2 && currY < ScreenHeight); currY++) { if (currX < ScreenWidth) SetPixel((int)currX, (int)currY, C); currX += slope; /* increment X by the slope */ } return; } else if ((deltaY || deltaX) != 0) { /* |slope| < 1 */ if (X2 < X1) { /* Swap coordinates, X1 must be < X2 */ tempVal = X2; X2 = X1; X1 = tempVal; tempVal = Y2; Y2 = Y1; Y1 = tempVal; } /* Compute deltas and slope */ deltaX = X2 - X1; deltaY = Y2 - Y1; /* Slope off the horizontal axis */ slope = deltaY / deltaX; /* Plot each pixel starting at (X1, Y1) */ currY = Y1; for (currX = X1; (currX <= X2 && currX < ScreenWidth); currX++) { if (currY < ScreenHeight) SetPixel((int)currX, (int)currY, C); currY += slope; /* increment Y by the slope */ } return; } else /* Set a single pixel because Y1 = Y2 and X1 = X2 */ if (X1 >= 0 && Y1 >= 0 && X1 < ScreenWidth && Y1 < ScreenHeight) SetPixel(X1, Y1, C); }
Now for the Circle
function in CIRCLE.C
.
/* CIRCLE.C -- by Gary Neal, Jr. * * This function draws a circle on the graphics screen using floating * point math. */ #include "fgraph.h" /* Needed for ScreenWidth & ScreenHeight */ float angleIncr = 0.5; void Circle(int xOffset, int yOffset, int radius, unsigned char C) { float xPlot, yPlot; /* Current pixel being plotted */ float angle, angleRad; /* Current angle degrees & radiens */ /* Check limits for Angle Increment */ if (angleIncr < 1) angleIncr = 0.5; else if (angleIncr > 360.) angleIncr = 360.; for (angle = 0.; angle < 360.; angle += angleIncr) { /* Convert degrees to radiens */ angleRad = angle * (3.141592654 / 180); /* Convert polar to rectangular coordinates */ xPlot = (radius * cos(angleRad)) + xOffset; yPlot = (radius * sin(angleRad)) + yOffset; /* Check boundaries */ if (xPlot < 0) xPlot = 0; else if (xPlot >= ScreenWidth) xPlot = ScreenWidth - 1; if (yPlot < 0) yPlot = 0; else if (yPlot >= ScreenHeight) yPlot = ScreenHeight - 1; /* Plot the pixel on the graphics screen */ SetPixel((int)xPlot, (int)yPlot, C); } }
Now we're ready for the object code so at the command prompt, type:
tcc -c -mm -1 line.c tcc -c -mm -1 circle.c
These two lines compile the two source code files into object code (-c
),
using medium memory module (-mm
), and 186/286 instructions (-1
).
Now we can add these to the game library as follows:
tlib gamelib.lib +line.obj +circle.obj, gamelib.txt
There you have it, our game library now contains code for all the functions
that we've discussed up to this point. To ensure that all modules
(vmode.obj
, line.obj
, and circle.obj
)
are all compiled using the same memory module, let's recompile VMODE.C
.
tcc -c -mm -1 vmode.c
Now let's put it in the library, replacing the old module already in the library.
tlib gamelib.lib -+vmode.obj, gamelib.txt
Okay, I think it's time for a quick time-out and time to answer some questions.