Thread: [Dev-C++] code compatibility
Open Source C & C++ IDE for Windows
Brought to you by:
claplace
|
From: <tam...@ms...> - 2002-07-01 14:25:15
|
Hey guys I'm still real green when it comes to code and I'm trying to go =
a little deeper than just the basics so I check out this book by Michael =
Abrash called "ZEN of Graphics Programming." He believes you should writ=
e all graphics in assembly language do to C's lack of compatibility from =
one compiler to another and then he writes this C program. Of course it =
doesn't compile on dev. Could anyone tell me what compiler it does compi=
le on and how maybe I could get it to compile on dev?
Thanks for any help anyone could give to this newbie.
/*
* Illustrates color paging by color-animating a series of
* concentric circles to produce the illusion of motion.
* Runs on the VGA only, because color paging isn't available on
* the EGA.
*/
#include <dos.h>
#define USE_BIOS 0 /* set to 1 to use BIOS functions to perform
color paging, 0 to program color paging
registers directly */
=20
#define SCREEN_WIDTH_IN_BYTES 80 /* # of bytes across one scan
line in mode 12h */
#define SCREEN_SEGMENT 0xA000 /* mode 12h display memory seg*/
#define GC_INDEX 0x3CE /* Graphics Controller index */
#define SET_RESET_INDEX 0 /* Set/Reset reg index in GC */
#define SET_RESET_ENABLE_INDEX 1 /* Set/Reset Enable reg index
in GC */
#define BIT_MASK_INDEX 8 /* Bit Mask reg index in GC */ =
=20
#define INPUT_STATUS_1 0x3DA /* Input Status 1 port */
#define AC_INDEX 0x3C0 /* Attribute Controller index */
#define AC_DATA_W 0x3C0 /* Attribute Controller data
register for reads */
#define AC_DATA_R 0x3C1 /* Attribute Controller data
register for reads */ =20
#define AC_MODE_INDEX 0x30 /* AC Mode reg index, with bit 6
set to avoid blanking screen =
*/
#define AC_COLOR_SELECT_INDEX 0x34 /* Color Select req index, with
bit 6 set to avoid blanking
screen */
void DrawDot(int X, int Y);
void DrawCircle(int X, int Y, int Radius, int Color);
/* Array used to load the DAC. Organized as 256 RGB triplets*/
static unsigned char DACSettings[256*3];
/* Array used to load the palette RAM to a pass-through state.
The 17th entry sets the border color to 0 */
static unsigned char PaletteRAMSettings[] =3D {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
void main()
{
int Radius, Color, Page, Element, i;
union REGS Regs;
struct SREGS Sregs;
unsigned char GreenComponent;
=20
/* Select VGA's hi-res 640x480 graphics mode, mode 12h */
Regs.x.ax =3D 0x0012;
int86(0x10, &Regs, &Regs);
=20
/* Draw concentric circles */
for ( Radius =3D 10, Color =3D 1; Radius < 240; Radius +=3D 2 )
{
DrawCircle(640/2, 480/2, Radius, Color);
if (++Color >=3D 16)
Color =3D 1; /* skip color 0 */
}
=20
/* Load the upper 240 DAC locations (15 pages) with one-postion
rotations of a series of increasingly green colors. Because
page 0 is being displayed, the screen remains unchanged while
the other 15 color pages are being loaded. */
=20
/* First, fill DACSettings with the desired green settings
(because it's a static array, all locations are initialized to
zero, so we don't need to initialize the red or green color
components, which we want to be zero). */
GreenComponent =3D 8;
for ( Page =3D 1; Page <=3D 15; Page++ )
{
GreenComponent =3D Page * 4;
for ( Element =3D 1; Element <=3D 15; Element++ )
{
DACSettings[Page*16*3 + Element*3 +1] =3D GreenComponent;
if ( (GreenComponent +=3D 4) >=3D 64 )
GreenComponent =3D 4;
}
}
=20
/* Now call the BIOS to load the pper 240 DAC locations */
Regs.h.ah =3D 0x10;
Regs.h.al =3D 0x12;
Regs.x.bx =3D 16;
Regs.x.cx =3D 240;
Regs.x.dx =3D (unsigned int)(DACSettings + 16*3);
segread(&Sregs);
Sregs.es =3D Sregs.ds /* point ES:DX to DACSettings */
int86x(0x10, &Regs, &Regs, &Sregs);
=20
/* Put the palette RAM in a pass-through state and set the Overscan
register (boarder color) to 0. We've saved this for last because
it changes the colors being displayed. */
Regs.h.ah =3D 0x10;
Regs.h.al =3D 2;
Regs.x.dx =3D (unsigned int)PaletteRAMSettings;
segread(&Sregs);
Sregs.es =3D Sregs.ds; /* point ES:DS to PaletteRAMSettings */
int86x(0x10, &Regs, &Regs, &Sregs);
=20
/* Enable 16-pages-if-16-colors paging */
#if USE_BIOS
Regs.h.ah =3D 0x10;
Regs.h.al =3D 0x13;
Regs.h.bl =3D 0;
Regs.h.bh =3D 1;
int86(0x10, &Regs, &Regs);
#else
inp(INPUT_STATUS_1);
outp(AC_INDEX, AC_MODE_INDEX);
outp(AC_DATA_W, inp(AC_DATA_R) | 0x80);
#endif /* USE_BIOS */
/* We're read to roll; the upper 15 pages are set up, the
palette RAM is in a pass-through state, and 16-pages-of-16-
colors paging is enabled. Now we'll loop through and display
each of pages 15 through 1 and then back to 15 for one frame
until a key is pressed. */
for ( Page =3D 15, i =3D 0; i < 1000; i++ )
{
#if USE_BIOS
/* Select the desired color page */
Regs.h.ah =3D 0x10;
Regs.h.al =3D 0x13;
Regs.h.bl =3D 1;
Regs.h.bh =3D Page;
int86(0x10, &Regs, &Regs);
#else
/* Wait for the leading edge of the vertical sync pulse; this
ensures that we change color pages during vertical
non-display time, and that the page flips are even spaced
over time */
while ( (inp(INPUT_STATUS_1) & 0x08) !=3D 0 );
/* wait for non-vertical sync time */
while ( (inp(INPUT_STATUS_1) & 0x08) =3D=3D 0 );
/* wait for vertical sync time */
inp(INPUT_STATUS_1);
outp(AC_INDEX, AC_COLOR_SELECT_INDEX);
outp(AC_DATA_W, Page);
#endif /* USE_BIOS */
/* Cycle from page 15 down to page 1, and then back to page 15.
Avoid page 0 entirely */
if (--Page =3D=3D 0)
Page =3D 15;
}
=20
/* Restore text mode and done */
Regs.x.ax =3D 0x0003;
int86(0x10, &Regs, &Regs);
}
/* Draws a pixel at screen coordinate (X,Y) */
void DrawDot(int X, int Y)
{
unsigned char far *ScreenPtr;
=20
/* Point to the byte the pixel is in */
#ifdef __TURBOC__
ScreenPtr =3D MK_FP(SCREEN_SEGMENT,
(Y * SCREEN_WIDTH_IN_BYTES) + (X / 8));
#else
FP_SEG(ScreenPtr) =3D SCREEN_SEGMENT;
FP_OFF(ScreenPtr) =3D(Y * SCREEN_WIDTH_IN_BYTES) + (X / 8);
#endif
/* Set the bit mask within the byte for the pixel */
outp(GC_INDEX + 1, 0x80 >> (X & 0x07));
=20
/* Draw the pixel. ORed to force read/write to load latches
Data written doesn't matter, because set/reset is enabled
for all planes. Note: don't OR with 0; MSC optimizes that
statement to no operation. */
*ScreenPtr |=3D 0xFF;
}
/* Draws a circle of radius Radius in color Color centered at
* screen coordinate (X,Y) */
void DrawCircle(int X, int Y, int Radius, int Color)
{
int MajorAxis, MinorAxis;
unsigned long RadiusSqMinusMajorAxissq;
unsigned long MinorAxisSquaredThreshold;
=20
/* Set drawing color via set/reset */
outpw(GC_INDEX, (0x0F << 8) | SET_RESET_ENABLE_INDEX);
/* enable set/reset for all planes */
outpw(GC_INDEX, (Color << 8) | SET_RESET_INDEX);
/* set set/reset (drawing) color */
outp(GC_INDEX, BIT_MASK_INDEX);
/* Leave the GC Index reg pointing to
the Bit Mask reg */
=20
/* Set up to draw the circle by setting the initial point to one
end of the 1/8th of a circle arc we'll draw */
MajorAxis =3D 0;
MinorAxis =3D Radius;
/* Set initial Radius**2 - MajorAxis**2 (MajorAxis is initially 0) */
RadiusSqMinusMajorAxisSq =3D Raduis * Radius;
/* Set threshold for minor axis movement at (MinorAxis - 0.5)**2 */
MinorAxisSquaredThreshold =3D MinorAxis * MinorAxis - MinorAxis;
=20
/* Draw all points along an arc of 1/8th of the circle, drawing
all 8 symmetries at the same time */
do
{
/* Draw all 8 symmetries of current point */
DrawDot(X+MajorAxis, Y-MinorAxis);
DrawDot(X-MajorAxis, Y-MinorAxis);
DrawDot(X+MajorAxis, Y+MinorAxis);
DrawDot(X-MajorAxis, Y+MinorAxis);
DrawDot(X+MinorAxis, Y-MajorAxis);
DrawDot(X-MinorAxis, Y-MajorAxis);
DrawDot(X+MinorAxis, Y+MajorAxis);
DrawDot(X-MinorAxis, Y+MajorAxis);
=20
/* Advance (Radius**2 - MajorAxis**2); if it equals or passes
the MinorAxis**2 threshold, advance one pixel along the minor
axis and set the next MinorAxis**2 threshold. */
if ( (RadiusSqMinusMajorAxisSq -=3D
MajorAxis + MajorAxis + 1) <=3D MinorAxisSquaredThreshold )
{
MinorAxis--;
MinorAxisSquaredThreshold -=3D MinorAxis + MinorAxis;
}
MajorAxis++; /* advance one pixel along the major axis */ =
=20
}
while ( MajorAxis <=3D MinorAxis );
=20
/* Reset the Bit Mask register to normal */
outp(GC_INDEX + 1, 0xFF);
=20
/* Turn off set/reset enable */
outpw(GC_INDEX, (0x00 << 8) | SET_RESET_ENABLE_INDEX);
} =20
|