///////////////////////////////////////////////////////////////////////////// // // // TUTPROG9.CPP - VGA Trainer Program 9 (in Turbo C++ 3.0) // // // // "The VGA Trainer Program" is written by Denthor of Asphyxia. However it // // was limited to only Pascal in its first run. All I have done is taken // // his original release, translated it to C++ and touched up a few things. // // I take absolutely no credit for the concepts presented in this code. // // // // Program Notes : This program demonstrates polygon moving and rotation. // // // // If you are compiling this program from within the // // Turbo C++ environment, you must go under Options, // // Debugger, and change the "Program Heap Size" to a value // // 80 or greater. If you are going to be fooling around // // with the code a bit, I suggest raising this to about // // 100 just to be on the safe side. You don't have to // // worry about this if you are compiling command line. // // // // Just for reference, this is what I use: // // // // tcc -mc -a -G -2 -O tut9.cpp // // // // The way things are set up, there is no need to compile // // or link tut9.cpp and gfx2.cpp seperately. // // // // The Compact memory model (-mc) seems to provide the // // best results for this tutorial. Remember, use this // // memory model when you have little code (less than 64k) // // and lots of data. // // // // Author : Grant Smith (Denthor) - denthor@beastie.cs.und.ac.za // // Translator : Christopher G. Mann - r3cgm@dax.cc.uakron.edu // // // // Last Modified : January 21, 1995 // // // ///////////////////////////////////////////////////////////////////////////// // // // INCLUDE FILES // // // #include // clrscr(), getch(), kbhit() #include // cout() #include // sin(), cos() #include // exit() #include "gfx2.cpp" // our graphics library tools // // // TYPEDEFS // // // typedef unsigned char byte; typedef unsigned int word; // // // CONSTANTS // // // const MAXPOLYS = 5; const POLYPOINTS = 4; const POLYCORDS = 3; // // // LETTER DATA // // // // The 3-D coordinates of our object ... stored as {X1,Y1,Z1}, // {X2,Y2,Z2} ... for the 4 points of a poly. const int A[MAXPOLYS][POLYPOINTS][POLYCORDS] = { {{-10, 10, 0},{ -2,-10, 0},{ 0,-10, 0},{ -5,10, 0}}, // 1 {{ 10, 10, 0},{ 2,-10, 0},{ 0,-10, 0},{ 5,10, 0}}, // 2 {{ -2,-10, 0},{ 2,-10, 0},{ 2, -5, 0},{ -2,-5, 0}}, // 3 {{ -6, 0, 0},{ 6, 0, 0},{ 7, 5, 0},{ -7, 5, 0}}, // 4 {{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}} }; // 5 // 1----1 + 2----2 // |....| | |....| // |....| | |....| // `....` | '....' // |....| | |....| // `.4------+------4.' // ||......|......|| // ``......|......'' // ||.....|.....|| // ||.....|.....|| // -------+---4+----+----+4---+------- // |...| | |...| // `...` | '...' // |...|||...| // |...|...| // |.3-+-3.| // `.|.|.|.' // ||.|.|| // ||.|.|| // `|.|.|' // 3-2-3 const int S[MAXPOLYS][POLYPOINTS][POLYCORDS] = { {{-10,-10, 0},{ 10,-10, 0},{10, -7, 0},{-10, -7, 0}}, {{-10, 10, 0},{ 10, 10, 0},{10, 7, 0},{-10, 7, 0}}, {{-10, 1, 0},{ 10, 1, 0},{10, -2, 0},{-10, -2, 0}}, {{-10, -8, 0},{ -7, -8, 0},{-7, 0, 0},{-10, 0, 0}}, {{ 10, 8, 0},{ 7, 8, 0},{ 7, 0, 0},{ 10, 0, 0}} }; const int P[MAXPOLYS][POLYPOINTS][POLYCORDS] = { {{-10,-10,0},{-7,-10,0},{-7,10,0},{-10,10,0}}, {{10,-10,0},{7,-10,0},{7,0,0},{10,0,0}}, {{-9,-10,0},{9,-10,0},{9,-7,0},{-9,-7,0}}, {{-9,-1,0},{9,-1,0},{9,2,0},{-9,2,0}}, {{0,0,0},{0,0,0},{0,0,0},{0,0,0}} }; const int H[MAXPOLYS][POLYPOINTS][POLYCORDS] = { {{-10,-10,0},{-7,-10,0},{-7,10,0},{-10,10,0}}, {{10,-10,0},{7,-10,0},{7,10,0},{10,10,0}}, {{-9,-1,0},{9,-1,0},{9,2,0},{-9,2,0}}, {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}, {{0,0,0},{0,0,0},{0,0,0},{0,0,0}} }; const int Y[MAXPOLYS][POLYPOINTS][POLYCORDS] = { {{-7,-10,0},{0,-3,0},{0,0,0},{-10,-7,0}}, {{7,-10,0},{0,-3,0},{0,0,0},{10,-7,0}}, {{-2,-3,0},{2,-3,0},{2,10,0},{-2,10,0}}, {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}, {{0,0,0},{0,0,0},{0,0,0},{0,0,0}} }; const int X[MAXPOLYS][POLYPOINTS][POLYCORDS] = { {{-7,-10,0},{10,7,0},{7,10,0},{-10,-7,0}}, {{7,-10,0},{-10,7,0},{-7,10,0},{10,-7,0}}, {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}, {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}, {{0,0,0},{0,0,0},{0,0,0},{0,0,0}} }; const int I[MAXPOLYS][POLYPOINTS][POLYCORDS] = { {{-10,-10,0},{10,-10,0},{10,-7,0},{-10,-7,0}}, {{-10,10,0},{10,10,0},{10,7,0},{-10,7,0}}, {{-2,-9,0},{2,-9,0},{2,9,0},{-2,9,0}}, {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}, {{0,0,0},{0,0,0},{0,0,0},{0,0,0}} }; // // // FUNCTION PROTOTYPES // // // void DrawPoly (int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, byte Col, word Where); void SetUpPoints (); void RotatePoints (int X, int Y, int Z); void DrawPoints (); void Whizz (int sub, int °); void MoveAround (); // // // STRUCTURES // // // // The data for every point we rotate struct Point { float x; float y; float z; }; // // // GLOBAL VARIABLE DECLARATIONS // // // byte far *Virscr=NULL; // Pointer to our virtual screen word Vaddr; // Segment of our virtual screen float Lookup[360][2]; // Our sin and cos lookup tables int Xoff, Yoff, Zoff; // Used for movement of the object Point Lines[MAXPOLYS][4]; // The base object being rotated Point Translated[MAXPOLYS][4]; // The rotated object /////////////////////////////////////////////////////////////////////////////// // // // MAIN FUNCTION // // // /////////////////////////////////////////////////////////////////////////////// void main() { SetUpVirtual(Virscr,Vaddr); // always check to see if enough memory was allocated if (Virscr == NULL) { SetText(); cout << "Insufficient memory for virtual screens, exiting..."; exit(1); } clrscr(); cout << "Hello there! Varsity has begun once again, so it is once again\n" << "back to the grindstone ;-) ... anyway, this tutorial is, by\n" << "popular demand, on poly-filling, in relation to 3-D solids.\n\n" << "In this program, the letters of ASPHYXIA will fly past you. As you\n" << "will see, they are solid, not wireframe. After the last letter has\n" << "flown by, a large A will be left in the middle of the screen.\n\n" << "You will be able to move it around the screen, and you will notice\n" << "that it may have bits only half on the screen, i.e. clipping is\n" << "perfomed. To control it use the following : ""A"" and ""Z"" control the Z\n" << "movement, "","" and ""."" control the X movement, and ""S"" and ""X""\n" << "control the Y movement. I have not included rotation control, but\n" << "it should be easy enough to put in yourself ... if you have any\n" << "hassles, leave me mail.\n\n"; cout << "Hit any key to continue ...\n"; getch(); SetMCGA(); SetUpPoints(); MoveAround(); SetText(); ShutDown(Virscr); cout << "All done. This concludes the ninth sample program in the ASPHYXIA\n" << "Training series. You may reach DENTHOR under the names of GRANT\n" << "SMITH/DENTHOR/ASPHYXIA on the ASPHYXIA BBS. I am also an avid\n" << "Connectix BBS user, and occasionally read RSAProg.\n" << "The numbers are available in the main text. You may also write to me at:\n" << " Grant Smith\n" << " P.O. Box 270\n" << " Kloof\n" << " 3640\n" << "I hope to hear from you soon!\n\n"; cout << "Hit any key to exit ...\n"; getch(); } ///////////////////////////////////////////////////////////////////////////// // // // DrawPoly() - This draws a polygon with 4 points at x1,y1, x2,y2, x3,y3, // // x4,y4 in color Col at location Where // // // ///////////////////////////////////////////////////////////////////////////// void DrawPoly(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, byte Col, word Where) { int x, mny, mxy, mnx, mxx, yc; int mul1, div1, mul2, div2, mul3, div3, mul4, div4; // find the maximum y (mny) and minimum y (mny) mny = y1; mxy = y1; if (y2mxy) mxy = y2; if (y3mxy) mxy = y3; if (y4mxy) mxy = y4; // if the mimimum or maximum is out of bounds, bring it back in if (mny< 0) mny = 0; if (mxy>199) mxy = 199; // verticle range checking if (mny>199) return; if (mxy< 0) return; // constants needed for intersection calculations mul1 = x1-x4; div1 = y1-y4; mul2 = x2-x1; div2 = y2-y1; mul3 = x3-x2; div3 = y3-y2; mul4 = x4-x3; div4 = y4-y3; for (yc=mny; yc= yc) || (y1 >= yc)) if ((y4 <= yc) || (y1 <= yc)) if (y4 != y1) { x = ((yc-y4) * mul1 / div1) + x4; if (xmxx) mxx = x; } if ((y1 >= yc) || (y2 >= yc)) if ((y1 <= yc) || (y2 <= yc)) if (y1 != y2) { x = ((yc-y1) * mul2 / div2) + x1; if (xmxx) mxx = x; } if ((y2 >= yc) || (y3 >= yc)) if ((y2 <= yc) || (y3 <= yc)) if (y2 != y3) { x = ((yc-y2) * mul3 / div3) + x2; if (xmxx) mxx = x; } if ((y3 >= yc) || (y4 >= yc)) if ((y3 <= yc) || (y4 <= yc)) if (y3 != y4) { x = ((yc-y3) * mul4 / div4) + x3; if (xmxx) mxx = x; } // horizontal range checking if (mnx< 0) mnx = 0; if (mxx>319) mxx = 319; if (mnx<=mxx) // draw the horizontal line Hline(mnx,mxx,yc,Col,Where); } } ///////////////////////////////////////////////////////////////////////////// // // // SetUpPoints() - This creates the lookup table. // // // ///////////////////////////////////////////////////////////////////////////// void SetUpPoints() { int loop1; // generate the sin() and cos() tables for (loop1=0; loop1<360; loop1++) { Lookup [loop1][0] = sin(rad(loop1)); Lookup [loop1][1] = cos(rad(loop1)); } } ///////////////////////////////////////////////////////////////////////////// // // // RotatePoints() - This rotates object lines by X,Y and Z, then places // // the result in Translated[] // // // ///////////////////////////////////////////////////////////////////////////// void RotatePoints(int X, int Y, int Z) { int loop1, loop2; Point temp; for (loop1=0; loop10) { temp.x = Lookup[Y][1] * Translated[loop1][loop2].x - Lookup[Y][0] * Translated[loop1][loop2].y; temp.y = Lookup[Y][0] * Translated[loop1][loop2].x + Lookup[Y][1] * Translated[loop1][loop2].y; temp.z = Translated[loop1][loop2].z; Translated[loop1][loop2] = temp; } if (Z>0) { temp.x = Lookup[Z][1] * Translated[loop1][loop2].x + Lookup[Z][0] * Translated[loop1][loop2].z; temp.y = Translated[loop1][loop2].y; temp.z = Lookup[Z][0] * Translated[loop1][loop2].x + Lookup[Z][1] * Translated[loop1][loop2].z; Translated[loop1][loop2] = temp; } } } } ///////////////////////////////////////////////////////////////////////////// // // // DrawPoints() - This draws the translated object to the virtual screen. // // // ///////////////////////////////////////////////////////////////////////////// void DrawPoints() { int nx, ny, nx2, ny2, nx3, ny3, nx4, ny4, temp, loop1; for (loop1=0; loop1