Metropoli BBS
VIEWER: xsharp.c MODE: TEXT (ASCII)
/* 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 <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#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; i<NumObjects;
            i++, ObjectPtr = ObjectPtr->NextObject) {
         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; i<NumObjects;
            i++, ObjectPtr = ObjectPtr->NextObject) {
         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; i<NumObjects;
            i++, ObjectPtr = ObjectPtr->NextObject)
         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; i<NumObjects;
            i++, ObjectPtr = ObjectPtr->NextObject)
         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, &regset, &regset);
   exit(1);
}

[ RETURN TO DIRECTORY ]