Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédente | Prochaine révisionLes deux révisions suivantes | ||
back2root:archives:denthor:part-08 [2021/09/02 11:34] – frater | back2root:archives:denthor:part-08 [2021/09/05 14:04] – [In closing] frater | ||
---|---|---|---|
Ligne 267: | Ligne 267: | ||
File = Available in file base | File = Available in file base | ||
Past = Previous Parts available | Past = Previous Parts available | ||
+ | |||
+ | ==== Code Source ==== | ||
+ | |||
+ | === PASCAL === | ||
+ | |||
+ | <code pascal> | ||
+ | (*****************************************************************************) | ||
+ | (* *) | ||
+ | (* TUT8.PAS - VGA Trainer Program 8 (in Pascal) | ||
+ | (* *) | ||
+ | (* "The VGA Trainer Program" | ||
+ | (* was limited to Pascal only 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, and *) | ||
+ | (* am NOT the person to ask for help if you are having trouble. | ||
+ | (* *) | ||
+ | (* Program Notes : This program presents the basis of 3D. *) | ||
+ | (* *) | ||
+ | (* Author | ||
+ | (* *) | ||
+ | (*****************************************************************************) | ||
+ | |||
+ | {$X+} | ||
+ | USES Crt; | ||
+ | |||
+ | CONST VGA = $A000; | ||
+ | MaxLines = 12; | ||
+ | Obj : Array [1..MaxLines, | ||
+ | ( | ||
+ | ((-10, | ||
+ | ((-10, | ||
+ | ((-10, | ||
+ | ((-10, | ||
+ | ((-10, | ||
+ | ((10, | ||
+ | ); { The 3-D coordinates of our object ... stored as (X1,Y1,Z1), } | ||
+ | { (X2,Y2,Z2) ... for the two ends of a line } | ||
+ | |||
+ | |||
+ | Type Point = Record | ||
+ | | ||
+ | END; | ||
+ | | ||
+ | | ||
+ | |||
+ | |||
+ | VAR Lines : Array [1..MaxLines, | ||
+ | Translated : Array [1..MaxLines, | ||
+ | Xoff, | ||
+ | lookup : Array [0..360, | ||
+ | Virscr : VirtPtr; | ||
+ | Vaddr : word; { The segment of our virtual screen} | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure SetMCGA; | ||
+ | BEGIN | ||
+ | asm | ||
+ | | ||
+ | | ||
+ | end; | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure SetText; | ||
+ | BEGIN | ||
+ | asm | ||
+ | | ||
+ | | ||
+ | end; | ||
+ | END; | ||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure Cls (Where: | ||
+ | { This clears the screen to the specified color } | ||
+ | BEGIN | ||
+ | asm | ||
+ | push es | ||
+ | mov cx, 32000; | ||
+ | mov | ||
+ | xor di,di | ||
+ | mov | ||
+ | mov ah,al | ||
+ | rep stosw | ||
+ | pop es | ||
+ | End; | ||
+ | END; | ||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure SetUpVirtual; | ||
+ | { This sets up the memory needed for the virtual screen } | ||
+ | BEGIN | ||
+ | GetMem (VirScr, | ||
+ | vaddr := seg (virscr^); | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure ShutDown; | ||
+ | { This frees the memory used by the virtual screen } | ||
+ | BEGIN | ||
+ | FreeMem (VirScr, | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | procedure flip(source, | ||
+ | { This copies the entire screen at " | ||
+ | begin | ||
+ | asm | ||
+ | push ds | ||
+ | mov ax, [Dest] | ||
+ | mov es, ax | ||
+ | mov ax, [Source] | ||
+ | mov ds, ax | ||
+ | xor si, si | ||
+ | xor di, di | ||
+ | mov cx, 32000 | ||
+ | rep movsw | ||
+ | pop ds | ||
+ | end; | ||
+ | end; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure Pal(Col, | ||
+ | { This sets the Red, Green and Blue values of a certain color } | ||
+ | Begin | ||
+ | asm | ||
+ | mov dx,3c8h | ||
+ | mov al,[col] | ||
+ | out dx,al | ||
+ | inc dx | ||
+ | mov al,[r] | ||
+ | out dx,al | ||
+ | mov al,[g] | ||
+ | out dx,al | ||
+ | mov al,[b] | ||
+ | out dx,al | ||
+ | end; | ||
+ | End; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Function rad (theta : real) : real; | ||
+ | { This calculates the degrees of an angle } | ||
+ | BEGIN | ||
+ | rad := theta * pi / 180 | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure SetUpPoints; | ||
+ | { This sets the basic offsets of the object, creates the lookup table and | ||
+ | moves the object from a constant to a variable } | ||
+ | VAR loop1: | ||
+ | BEGIN | ||
+ | Xoff:=160; | ||
+ | Yoff:=100; | ||
+ | Zoff:=-256; | ||
+ | For loop1:=0 to 360 do BEGIN | ||
+ | lookup [loop1, | ||
+ | lookup [loop1, | ||
+ | END; | ||
+ | For loop1:=1 to MaxLines do BEGIN | ||
+ | Lines [loop1, | ||
+ | Lines [loop1, | ||
+ | Lines [loop1, | ||
+ | Lines [loop1, | ||
+ | Lines [loop1, | ||
+ | Lines [loop1, | ||
+ | END; | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure Putpixel (X,Y : Integer; Col : Byte; where: | ||
+ | { This puts a pixel on the screen by writing directly to memory. } | ||
+ | BEGIN | ||
+ | Asm | ||
+ | mov | ||
+ | mov es,ax | ||
+ | mov | ||
+ | mov | ||
+ | mov di,bx | ||
+ | mov bx, dx {; bx = dx} | ||
+ | shl dx, 8 | ||
+ | shl bx, 6 | ||
+ | add dx, bx {; dx = dx + bx (ie y*320)} | ||
+ | add di, dx {; finalise location} | ||
+ | mov al, [Col] | ||
+ | stosb | ||
+ | End; | ||
+ | END; | ||
+ | |||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure Line(a, | ||
+ | { This draws a solid line from a,b to c,d in colour col } | ||
+ | function sgn(a: | ||
+ | begin | ||
+ | if a>0 then sgn:=+1; | ||
+ | if a<0 then sgn:=-1; | ||
+ | if a=0 then sgn:=0; | ||
+ | end; | ||
+ | var i, | ||
+ | begin | ||
+ | u:= c - a; | ||
+ | v:= d - b; | ||
+ | d1x:= SGN(u); | ||
+ | d1y:= SGN(v); | ||
+ | d2x:= SGN(u); | ||
+ | d2y:= 0; | ||
+ | m:= ABS(u); | ||
+ | n := ABS(v); | ||
+ | IF NOT (M>N) then | ||
+ | BEGIN | ||
+ | d2x := 0 ; | ||
+ | d2y := SGN(v); | ||
+ | m := ABS(v); | ||
+ | n := ABS(u); | ||
+ | END; | ||
+ | s := m shr 1; | ||
+ | FOR i := 0 TO m DO | ||
+ | BEGIN | ||
+ | putpixel(a, | ||
+ | s := s + n; | ||
+ | IF not (s<m) THEN | ||
+ | BEGIN | ||
+ | s := s - m; | ||
+ | a:= a + d1x; | ||
+ | b := b + d1y; | ||
+ | END | ||
+ | ELSE | ||
+ | BEGIN | ||
+ | a := a + d2x; | ||
+ | b := b + d2y; | ||
+ | END; | ||
+ | end; | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure DrawLogo; | ||
+ | { This draws ' | ||
+ | CONST ball : Array [1..5,1..5] of byte = | ||
+ | | ||
+ | (1, | ||
+ | (1, | ||
+ | (1, | ||
+ | (0, | ||
+ | |||
+ | VAR Logo : Array [1..5] of String; | ||
+ | loop1, | ||
+ | BEGIN | ||
+ | pal (13, | ||
+ | pal (1,0,0,40); | ||
+ | pal (2,0,0,45); | ||
+ | pal (3,0,0,50); | ||
+ | pal (4,0,0,60); | ||
+ | Logo[1]: | ||
+ | Logo[2]: | ||
+ | Logo[3]: | ||
+ | Logo[4]: | ||
+ | Logo[5]: | ||
+ | For loop1:=1 to 5 do | ||
+ | For loop2:=1 to 31 do | ||
+ | if logo[loop1][loop2]=' | ||
+ | For loop3:=1 to 5 do | ||
+ | For loop4:=1 to 5 do | ||
+ | putpixel (loop2*10+loop3, | ||
+ | END; | ||
+ | |||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure RotatePoints (X, | ||
+ | { This rotates object lines by X,Y and Z; then places the result in | ||
+ | TRANSLATED } | ||
+ | VAR loop1: | ||
+ | temp:point; | ||
+ | BEGIN | ||
+ | For loop1:=1 to maxlines do BEGIN | ||
+ | temp.x: | ||
+ | temp.y: | ||
+ | temp.z: | ||
+ | |||
+ | translated[loop1, | ||
+ | |||
+ | If y>0 then BEGIN | ||
+ | temp.x: | ||
+ | temp.y: | ||
+ | temp.z: | ||
+ | translated[loop1, | ||
+ | END; | ||
+ | |||
+ | If z>0 then BEGIN | ||
+ | temp.x: | ||
+ | temp.y: | ||
+ | temp.z: | ||
+ | translated[loop1, | ||
+ | END; | ||
+ | |||
+ | temp.x: | ||
+ | temp.y:=cos (rad(X))*lines[loop1, | ||
+ | temp.z:=sin (rad(X))*lines[loop1, | ||
+ | |||
+ | translated[loop1, | ||
+ | |||
+ | If y>0 then BEGIN | ||
+ | temp.x:=cos (rad(Y))*translated[loop1, | ||
+ | temp.y:=sin (rad(Y))*translated[loop1, | ||
+ | temp.z: | ||
+ | translated[loop1, | ||
+ | END; | ||
+ | |||
+ | If z>0 then BEGIN | ||
+ | temp.x:=cos (rad(Z))*translated[loop1, | ||
+ | temp.y: | ||
+ | temp.z: | ||
+ | translated[loop1, | ||
+ | END; | ||
+ | END; | ||
+ | END; | ||
+ | |||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure DrawPoints; | ||
+ | { This draws the translated object to the virtual screen } | ||
+ | VAR loop1: | ||
+ | nx, | ||
+ | temp: | ||
+ | BEGIN | ||
+ | For loop1:=1 to MaxLines do BEGIN | ||
+ | If (translated[loop1, | ||
+ | temp:=round (translated[loop1, | ||
+ | nx :=round (256*translated[loop1, | ||
+ | ny :=round (256*translated[loop1, | ||
+ | temp:=round (translated[loop1, | ||
+ | nx2:=round (256*translated[loop1, | ||
+ | ny2:=round (256*translated[loop1, | ||
+ | If (NX > 0) and (NX < 320) and (NY > 25) and (NY < 200) and | ||
+ | | ||
+ | line (nx, | ||
+ | END; | ||
+ | END; | ||
+ | END; | ||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure ClearPoints; | ||
+ | { This clears the translated object from the virtual screen ... believe it | ||
+ | or not, this is faster then a straight "cls (vaddr, | ||
+ | VAR loop1: | ||
+ | nx, | ||
+ | temp: | ||
+ | BEGIN | ||
+ | For loop1:=1 to MaxLines do BEGIN | ||
+ | If (translated[loop1, | ||
+ | temp:=round (translated[loop1, | ||
+ | nx :=round (256*translated[loop1, | ||
+ | ny :=round (256*translated[loop1, | ||
+ | temp:=round (translated[loop1, | ||
+ | nx2:=round (256*translated[loop1, | ||
+ | ny2:=round (256*translated[loop1, | ||
+ | If (NX > 0) and (NX < 320) and (NY > 25) and (NY < 200) and | ||
+ | | ||
+ | line (nx, | ||
+ | END; | ||
+ | END; | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure MoveAround; | ||
+ | { This is the main display procedure. Firstly it brings the object towards | ||
+ | the viewer by increasing the Zoff, then passes control to the user } | ||
+ | VAR deg, | ||
+ | ch:char; | ||
+ | BEGIN | ||
+ | deg:=0; | ||
+ | ch:=#0; | ||
+ | Cls (vaddr,0); | ||
+ | DrawLogo; | ||
+ | For loop1:=-256 to -40 do BEGIN | ||
+ | zoff: | ||
+ | RotatePoints (deg, | ||
+ | DrawPoints; | ||
+ | flip (vaddr, | ||
+ | ClearPoints; | ||
+ | deg: | ||
+ | END; | ||
+ | |||
+ | Repeat | ||
+ | if keypressed then BEGIN | ||
+ | ch:=upcase (Readkey); | ||
+ | Case ch of ' | ||
+ | ' | ||
+ | ',' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | END; | ||
+ | END; | ||
+ | DrawPoints; | ||
+ | flip (vaddr, | ||
+ | ClearPoints; | ||
+ | RotatePoints (deg, | ||
+ | deg: | ||
+ | Until ch=#27; | ||
+ | END; | ||
+ | |||
+ | |||
+ | BEGIN | ||
+ | SetUpVirtual; | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln ('When it gets close, you get control. " | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln ('it should be easy enough to put in yourself ... if you have any'); | ||
+ | Writeln (' | ||
+ | Writeln; | ||
+ | Writeln ('Read the main text file for ideas on improving this code ... and'); | ||
+ | Writeln (' | ||
+ | writeln; | ||
+ | writeln; | ||
+ | Write (' | ||
+ | Readkey; | ||
+ | SetMCGA; | ||
+ | SetUpPoints; | ||
+ | MoveAround; | ||
+ | SetText; | ||
+ | ShutDown; | ||
+ | Writeln ('All done. This concludes the eigth sample program in the ASPHYXIA' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln ('For discussion purposes, I am also the moderator of the Programming' | ||
+ | Writeln (' | ||
+ | Writeln ('The numbers are available in the main text. You may also write to me at:'); | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln ('I hope to hear from you soon!' | ||
+ | Writeln; Writeln; | ||
+ | Write | ||
+ | Readkey; | ||
+ | END. | ||
+ | </ | ||
+ | |||
+ | === C === | ||
+ | |||
+ | <code c file: | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // TUTPROG8.CPP - VGA Trainer Program 8 (in Turbo C++ 3.0) // | ||
+ | // // | ||
+ | // "The VGA Trainer Program" | ||
+ | // 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 and // | ||
+ | // am NOT the person to ask for help if you are having trouble. | ||
+ | // // | ||
+ | // Program Notes : This program presents the basics of 3D. Please note // | ||
+ | // that the compiled C++ version of this program runs // | ||
+ | // much faster than the Pascal version. | ||
+ | // a 486DX/33 or higher, you may wish to turn turbo off. // | ||
+ | // // | ||
+ | // If you are compiling this program from within the // | ||
+ | // Turbo C++ environment, | ||
+ | // | ||
+ | // 80 or greater. | ||
+ | // 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 tut8.cpp | ||
+ | // // | ||
+ | // The way things are set up, there is no need to compile | ||
+ | // or link tut8.cpp and gfx1.cpp seperately. | ||
+ | // // | ||
+ | // The Compact memory model (-mc) seems to provide the // | ||
+ | // best results for this tutorial. | ||
+ | // | ||
+ | // and lots of data. // | ||
+ | // // | ||
+ | // Author | ||
+ | // Translator | ||
+ | // // | ||
+ | // Last Modified : January 14, 1995 // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | // // | ||
+ | // INCLUDE FILES // | ||
+ | // // | ||
+ | |||
+ | #include < | ||
+ | // farcalloc() | ||
+ | #include < | ||
+ | // clrscr(), getch(), kbhit() | ||
+ | #include < | ||
+ | // FP_SEG, geninterrupt() | ||
+ | #include < | ||
+ | // cout | ||
+ | #include < | ||
+ | // sin(), cos() | ||
+ | #include < | ||
+ | // exit() | ||
+ | #include " | ||
+ | |||
+ | // // | ||
+ | // TYPEDEFS // | ||
+ | // // | ||
+ | |||
+ | typedef unsigned char byte; | ||
+ | typedef unsigned int word; | ||
+ | |||
+ | // // | ||
+ | // CONSTANTS // | ||
+ | // // | ||
+ | |||
+ | const MAXLINES = 12; // the number of lines in our cube | ||
+ | |||
+ | // The 3-D coordinates of our object ... stored as {X1,Y1,Z1}, | ||
+ | // {X2,Y2,Z2} ... for the two ends of a line | ||
+ | const int Obj[MAXLINES][2][3] = | ||
+ | { {{-10, | ||
+ | {{-10, | ||
+ | {{-10, 10,-10}, { 10, 10,-10}}, // 2 9 | A | | ||
+ | {{ 10, | ||
+ | {{-10,-10, 10}, { 10,-10, 10}}, // 4 .------6---. | ||
+ | {{-10,-10, 10}, {-10, 10, 10}}, // 5 | | ||
+ | {{-10, 10, 10}, { 10, 10, 10}}, // 6 | | ||
+ | {{ 10,-10, 10}, { 10, 10, 10}}, // 7 | | ||
+ | {{-10,-10, 10}, {-10, | ||
+ | {{-10, 10, 10}, {-10, 10,-10}}, // 9 | / | ||
+ | {{ 10, 10, 10}, { 10, 10,-10}}, // A | 8 | B | ||
+ | {{ 10,-10, 10}, { 10, | ||
+ | }; // | ||
+ | |||
+ | // // | ||
+ | // FUNCTION PROTOTYPES // | ||
+ | // // | ||
+ | |||
+ | // MEMORY ALLOCATION FUNCTIONS | ||
+ | void SetUpVirtual (); | ||
+ | void ShutDown | ||
+ | |||
+ | // LOGO-FUNCTION | ||
+ | void DrawLogo | ||
+ | |||
+ | // 3D POINTS FUNCTIONS | ||
+ | void SetUpPoints | ||
+ | void RotatePoints (int X, int Y, int Z); | ||
+ | void DrawPoints | ||
+ | void ClearPoints | ||
+ | |||
+ | // MID-LEVEL FUNCTION | ||
+ | void MoveAround | ||
+ | |||
+ | // // | ||
+ | // STRUCTURES // | ||
+ | // // | ||
+ | |||
+ | // The data on every point we rotate | ||
+ | struct Point { | ||
+ | float x; | ||
+ | float y; | ||
+ | float z; | ||
+ | }; | ||
+ | |||
+ | // // | ||
+ | // GLOBAL VARIABLE DECLARATIONS // | ||
+ | // // | ||
+ | |||
+ | byte far *Virscr=NULL; | ||
+ | word Vaddr; | ||
+ | float Lookup[360][2]; | ||
+ | int Xoff, Yoff, Zoff; // Used for movement of the objects | ||
+ | Point Lines[MAXLINES][2]; | ||
+ | Point Translated[MAXLINES][2]; | ||
+ | |||
+ | |||
+ | /////////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // MAIN FUNCTION | ||
+ | // // | ||
+ | /////////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void main() { | ||
+ | |||
+ | SetUpVirtual(); | ||
+ | clrscr(); | ||
+ | cout | ||
+ | << " | ||
+ | << "year! ;-) ... Anyway, this tutorial is on 3-D, so this is what is\n" | ||
+ | << "going to happen ... a wireframe square will come towards you.\n" | ||
+ | << "When it gets close, you get control. "" | ||
+ | << " | ||
+ | << " | ||
+ | << "it should be easy enough to put in yourself ... if you have any\n" | ||
+ | << " | ||
+ | cout | ||
+ | << "Read the main text file for ideas on improving this code ... and\n" | ||
+ | << " | ||
+ | cout << "Hit any key to contine ...\n"; | ||
+ | getch(); | ||
+ | |||
+ | SetMCGA(); | ||
+ | |||
+ | SetUpPoints(); | ||
+ | MoveAround(); | ||
+ | |||
+ | ShutDown(); | ||
+ | SetText(); | ||
+ | |||
+ | cout | ||
+ | << "All done. This concludes the eigth sample program in the ASPHYXIA\n" | ||
+ | << " | ||
+ | << " | ||
+ | << " | ||
+ | << "For discussion purposes, I am also the moderator of the Programming\n" | ||
+ | << " | ||
+ | << "The numbers are available in the main text. You may also write to me at:\n" | ||
+ | << " | ||
+ | << " | ||
+ | << " | ||
+ | << " | ||
+ | << "I hope to hear from you soon!\n\n\n"; | ||
+ | cout << "Hit any key to exit ...\n"; | ||
+ | getch(); | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // SetUpVirtual() - This sets up the memory needed for the virtual screen. // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void SetUpVirtual() { | ||
+ | |||
+ | Virscr = (byte far *) farcalloc(64000, | ||
+ | |||
+ | // always check to see if enough memory was allocated | ||
+ | if (Virscr == NULL) { | ||
+ | SetText(); | ||
+ | cout << " | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | Vaddr = FP_SEG(Virscr); | ||
+ | |||
+ | } | ||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // ShutDown() - This frees the memory used by the virtual screen. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void ShutDown() { | ||
+ | free(Virscr); | ||
+ | } | ||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // DrawLogo() - This draws ' | ||
+ | // balls. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void DrawLogo() { | ||
+ | |||
+ | const byte ball[5][5] = { 0,1,1,1,0, | ||
+ | 1,4,3,2,1, | ||
+ | 1,3,3,2,1, | ||
+ | 1,2,2,2,1, | ||
+ | 0,1,1,1,0 | ||
+ | }; | ||
+ | |||
+ | const char *Logo[5] = { {"OOO OOO OOO O O O O O OOO OOO"}, | ||
+ | {" | ||
+ | {"OOO O O O O O O O O O O OOO O O"}, | ||
+ | {" | ||
+ | {"OOO O O OOO O O O O O O O O O"} | ||
+ | }; | ||
+ | |||
+ | int loop1, loop2, loop3, loop4; | ||
+ | |||
+ | Pal(13, 0,63, 0); // set the color for the cube lines | ||
+ | Pal( 1, 0, 0,40); // set the colors for the dots | ||
+ | Pal( 2, 0, 0,45); | ||
+ | Pal( 3, 0, 0,50); | ||
+ | Pal( 4, 0, 0,60); | ||
+ | |||
+ | for (loop1=0; loop1<5; loop1++) | ||
+ | for (loop2=0; loop2< | ||
+ | if (Logo[loop1][loop2] == ' | ||
+ | for (loop3=0; loop3<5; loop3++) | ||
+ | for (loop4=0; loop4<5; loop4++) | ||
+ | Putpixel ((loop2+1)*10+loop3, | ||
+ | ball[loop3][loop4], | ||
+ | |||
+ | } | ||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // SetUpPoints() - This sets the basic offsets of the object, creates the // | ||
+ | // | ||
+ | // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void SetUpPoints() { | ||
+ | |||
+ | int loop1; | ||
+ | |||
+ | // set the starting offsets of the cube | ||
+ | Xoff = 160; | ||
+ | Yoff = 100; | ||
+ | Zoff = -256; | ||
+ | |||
+ | // generate the sin() and cos() tables | ||
+ | for (loop1=0; loop1< | ||
+ | Lookup [loop1][0] = sin(rad(loop1)); | ||
+ | Lookup [loop1][1] = cos(rad(loop1)); | ||
+ | } | ||
+ | |||
+ | // move the Obj constant array into the Lines array | ||
+ | for (loop1=0; loop1< | ||
+ | Lines[loop1][0].x = Obj[loop1][0][0]; | ||
+ | Lines[loop1][0].y = Obj[loop1][0][1]; | ||
+ | Lines[loop1][0].z = Obj[loop1][0][2]; | ||
+ | Lines[loop1][1].x = Obj[loop1][1][0]; | ||
+ | Lines[loop1][1].y = Obj[loop1][1][1]; | ||
+ | Lines[loop1][1].z = Obj[loop1][1][2]; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // RotatePoints() - This rotates object lines by X, Y, and Z. Then it // | ||
+ | // places the result in Translated. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void RotatePoints (int X,int Y,int Z) { | ||
+ | |||
+ | int loop1; | ||
+ | Point temp; | ||
+ | |||
+ | // for each line... | ||
+ | for (loop1=0; loop1< | ||
+ | |||
+ | // start point of line | ||
+ | |||
+ | temp.x = Lines[loop1][0].x; | ||
+ | temp.y = Lookup[X][1]*Lines[loop1][0].y - Lookup[X][0]*Lines[loop1][0].z; | ||
+ | temp.z = Lookup[X][0]*Lines[loop1][0].y + Lookup[X][1]*Lines[loop1][0].z; | ||
+ | Translated[loop1][0] = temp; | ||
+ | |||
+ | if (Y > 0) { | ||
+ | temp.x = Lookup[Y][1]*Translated[loop1][0].x - Lookup[Y][0]*Translated[loop1][0].y; | ||
+ | temp.y = Lookup[Y][0]*Translated[loop1][0].x + Lookup[Y][1]*Translated[loop1][0].y; | ||
+ | temp.z = Translated[loop1][0].z; | ||
+ | Translated[loop1][0] =temp; | ||
+ | } | ||
+ | |||
+ | if (Z > 0) { | ||
+ | temp.x = Lookup[Z][1]*Translated[loop1][0].x + Lookup[Z][0]*Translated[loop1][0].z; | ||
+ | temp.y = Translated[loop1][0].y; | ||
+ | temp.z = (-Lookup[Z][0])*Translated[loop1][0].x + Lookup[Z][1]*Translated[loop1][0].z; | ||
+ | Translated[loop1][0] = temp; | ||
+ | } | ||
+ | |||
+ | // end point of line | ||
+ | |||
+ | temp.x = Lines[loop1][1].x; | ||
+ | temp.y = cos(rad(X))*Lines[loop1][1].y - sin(rad(X))*Lines[loop1][1].z; | ||
+ | temp.z = sin(rad(X))*Lines[loop1][1].y + cos(rad(X))*Lines[loop1][1].z; | ||
+ | Translated[loop1][1] = temp; | ||
+ | |||
+ | if (Y > 0) { | ||
+ | temp.x = cos(rad(X))*Translated[loop1][1].x - sin(rad(Y))*Translated[loop1][1].y; | ||
+ | temp.y = sin(rad(Y))*Translated[loop1][1].x + cos(rad(Y))*Translated[loop1][1].y; | ||
+ | temp.z = Translated[loop1][1].z; | ||
+ | Translated[loop1][1] = temp; | ||
+ | } | ||
+ | |||
+ | if (Z > 0) { | ||
+ | temp.x = cos(rad(Z))*Translated[loop1][1].x + sin(rad(Z))*Translated[loop1][1].z; | ||
+ | temp.y = Translated[loop1][1].y; | ||
+ | temp.z = (-sin(rad(Z)))*Translated[loop1][1].x + cos(rad(Z))*Translated[loop1][1].z; | ||
+ | Translated[loop1][1] = temp; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // DrawPoints() - This draws the translated object to the virtual screen. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void DrawPoints() { | ||
+ | |||
+ | int loop1, nx, ny, nx2, ny2, temp; | ||
+ | |||
+ | for (loop1=0; loop1< | ||
+ | if ((Translated[loop1][0].z+Zoff< | ||
+ | |||
+ | // start point of line | ||
+ | temp = Translated[loop1][0].z + Zoff; | ||
+ | nx = ((256*Translated[loop1][0].x) / temp) + Xoff; | ||
+ | ny = ((256*Translated[loop1][0].y) / temp) + Yoff; | ||
+ | |||
+ | // end point of line | ||
+ | temp = Translated[loop1][1].z + Zoff; | ||
+ | nx2 = ((256*Translated[loop1][1].x) / temp) + Xoff; | ||
+ | ny2 = ((256*Translated[loop1][1].y) / temp) + Yoff; | ||
+ | |||
+ | // check to make sure the line is within bounds | ||
+ | if ((nx >-1) && (nx <320) && (ny >25) && (ny <200) && | ||
+ | (nx2>-1) && (nx2< | ||
+ | Line(nx, | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // ClearPoints() - This clears the translated object from the virtual | ||
+ | // | ||
+ | // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void ClearPoints() { | ||
+ | |||
+ | int loop1, nx, ny, nx2, ny2, temp; | ||
+ | |||
+ | for (loop1=0; loop1< | ||
+ | if ((Translated[loop1][0].z+Zoff< | ||
+ | |||
+ | // start point of line | ||
+ | temp = Translated[loop1][0].z + Zoff; | ||
+ | nx = ((256*Translated[loop1][0].x) / temp) + Xoff; | ||
+ | ny = ((256*Translated[loop1][0].y) / temp) + Yoff; | ||
+ | |||
+ | // end point of line | ||
+ | temp = Translated[loop1][1].z + Zoff; | ||
+ | nx2 = ((256*Translated[loop1][1].x) / temp) + Xoff; | ||
+ | ny2 = ((256*Translated[loop1][1].y) / temp) + Yoff; | ||
+ | |||
+ | // check to make sure the line is within bounds | ||
+ | if ((nx >-1) && (nx <320) && (ny >25) && (ny <200) && | ||
+ | (nx2>-1) && (nx2< | ||
+ | Line(nx, | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // MoveAround() - This is the main display function. | ||
+ | // object towards the viewer by increasing the Zoff, then // | ||
+ | // it passes control to the user. // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void MoveAround() { | ||
+ | |||
+ | // For some reason, the values we defined Xoff, Yoff, and Zoff to be in | ||
+ | // the function SetUpPoints() won't hold until this point. | ||
+ | // the reason, please send it to r3cgm@dax.cc.uakron.edu | ||
+ | Xoff = 160; // redefined | ||
+ | Yoff = 100; // redefined | ||
+ | Zoff = -256; // redefined | ||
+ | |||
+ | int deg=0, loop1; | ||
+ | byte ch=1; // assign a dummy value to ch | ||
+ | |||
+ | Cls(0, | ||
+ | |||
+ | DrawLogo(); | ||
+ | |||
+ | for (loop1=(-256); | ||
+ | Zoff = loop1 * 2; | ||
+ | RotatePoints(deg, | ||
+ | DrawPoints(); | ||
+ | Flip(Vaddr, | ||
+ | ClearPoints(); | ||
+ | deg = (deg + 5) % 360; | ||
+ | } | ||
+ | |||
+ | do { | ||
+ | |||
+ | if (kbhit()) { | ||
+ | ch = getch(); | ||
+ | switch (ch) { | ||
+ | // We are not going to use toupper() because if we did, we'd have | ||
+ | // to include the whole ctype.h file. This might take a little more | ||
+ | // time, but the program will be smaller. | ||
+ | // files, and its getting a bit rediculous. | ||
+ | case ' | ||
+ | case ' | ||
+ | case ',': | ||
+ | case ' | ||
+ | case ' | ||
+ | case ' | ||
+ | } | ||
+ | } | ||
+ | DrawPoints(); | ||
+ | Flip(Vaddr, | ||
+ | ClearPoints(); | ||
+ | RotatePoints(deg, | ||
+ | deg = (deg + 5) % 360; | ||
+ | |||
+ | // if the key pressed above was 0 (i.e. a control character) then | ||
+ | // read the character code | ||
+ | if (ch == 0) ch = getch(); | ||
+ | |||
+ | } while (ch != 27); // if the escape code was 27 (escape key) then exit | ||
+ | } | ||
+ | </ | ||
<nspages back2root/ | <nspages back2root/ |