/* 3D animation program to rotate 12 cubes. Uses fixed point. All C code tested with Borland C++ 3.0 in C compilation mode and the small model. */ #include #include #include #include #include "polygon.h" #define FIXED_REPS 0 /* set to # of reps to stop after, or to 0 for free-running */ /* Base offset of page to which to draw */ unsigned int CurrentPageBase = 0; /* Clip rectangle; clips to the screen */ int ClipMinX = 0, ClipMinY = 0; int ClipMaxX = SCREEN_WIDTH, ClipMaxY = SCREEN_HEIGHT; static unsigned int PageStartOffsets[2] = {PAGE0_START_OFFSET,PAGE1_START_OFFSET}; int DisplayedPage, NonDisplayedPage; int RecalcAllXforms = 1, NumObjects; Xform WorldViewXform; /* initialized from floats */ /* Object list start and end */ Object ObjectListStart; Object ObjectListEnd; void main() { int Done = 0, i; Object *ObjectPtr; union REGS regset; #if FIXED_REPS int Reps = FIXED_REPS; #endif InitializeObjectList(); InitializeFixedPoint(); /* set up fixed-point data */ InitializeCubes(); /* set up the cubes and add them to the object list */ InitializeBalls(); /* ditto for the balls */ Set320x240Mode(); /* set the screen to mode X */ ShowPage(PageStartOffsets[DisplayedPage = 0]); /* Keep transforming the cube, drawing it to the undisplayed page, and flipping the page to show it */ do { #if FIXED_REPS if ((--Reps) == 0) Done = 1; #endif /* For each object, regenerate viewing info, if necessary */ for (i=0, ObjectPtr = ObjectListStart.NextObject; iNextObject) { if (ObjectPtr->RecalcXform || RecalcAllXforms) { ObjectPtr->RecalcFunc(ObjectPtr); ObjectPtr->RecalcXform = 0; } } RecalcAllXforms = 0; CurrentPageBase = /* select other page for drawing to */ PageStartOffsets[NonDisplayedPage = DisplayedPage ^ 1]; /* For each object, clear the portion of the non-displayed page that was drawn to last time, then reset the erase extent */ for (i=0, ObjectPtr = ObjectListStart.NextObject; iNextObject) { FillRectangleX(ObjectPtr->EraseRect[NonDisplayedPage].Left, ObjectPtr->EraseRect[NonDisplayedPage].Top, ObjectPtr->EraseRect[NonDisplayedPage].Right, ObjectPtr->EraseRect[NonDisplayedPage].Bottom, CurrentPageBase, 0); ObjectPtr->EraseRect[NonDisplayedPage].Left = ObjectPtr->EraseRect[NonDisplayedPage].Top = 0x7FFF; ObjectPtr->EraseRect[NonDisplayedPage].Right = ObjectPtr->EraseRect[NonDisplayedPage].Bottom = 0; } /* Sort the objects so we can draw them back to front */ SortObjects(); /* Draw all objects */ for (i=0, ObjectPtr = ObjectListStart.NextObject; iNextObject) ObjectPtr->DrawFunc(ObjectPtr); /* Flip to display the page into which we just drew */ ShowPage(PageStartOffsets[DisplayedPage = NonDisplayedPage]); /* Move and reorient each object */ for (i=0, ObjectPtr = ObjectListStart.NextObject; iNextObject) ObjectPtr->MoveFunc(ObjectPtr); /* Check the keyboard */ if (kbhit()) if (getch() == 0x1B) Done = 1; /* Esc to exit */ } while (!Done); /* Return to text mode and exit */ regset.x.ax = 0x0003; /* AL = 3 selects 80x25 text mode */ int86(0x10, ®set, ®set); exit(1); }