Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
back2root:archives:denthor:part-03 [2021/08/26 21:59] – créée frater | back2root:archives:denthor:part-03 [2023/05/18 21:07] (Version actuelle) – frater | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
===== PART 03 : Lines and circles ===== | ===== PART 03 : Lines and circles ===== | ||
- | Greetings! This is the third part of the VGA Trainer series! Sorry it took so long to get out, but I had a running battle with the traffic department for three days to get my car registered, and then the MailBox | + | Greetings! This is the third part of the VGA Trainer series! Sorry it took so long to get out, but I had a running battle with the traffic department for three days to get my car registered, and then the MailBox went down. Ahh, well, life stinks. Anyway, today will do some things vital to most programs : Lines and circles. |
- | went down. Ahh, well, life stinks. Anyway, today will do some things vital to most programs : Lines and circles. | + | |
- | Watch out for next week's part : Virtual screens. The easy way to eliminate flicker, " | + | Watch out for next week's part : Virtual screens. The easy way to eliminate flicker, " |
- | screen (with the exception of the SilkyDemo), so this is one to watch out for. I will also show you how to put all of these loose procedures into units. | + | |
If you would like to contact me, or the team, there are many ways you can do it : | If you would like to contact me, or the team, there are many ways you can do it : | ||
Ligne 40: | Ligne 38: | ||
</ | </ | ||
- | Sorry about my ASCI ;-) ... anyway, Pascal doesn' | + | Sorry about my ASCI ;-) ... anyway, Pascal doesn' |
- | works with radians instead of degrees. (You can convert radians to degrees, | + | |
- | but I'm not going to go into that now. Note though that in pascal, the | + | |
circle goes like this : | circle goes like this : | ||
Ligne 97: | Ligne 93: | ||
</ | </ | ||
- | In the above example, the smaller the amount that deg is increased by, | + | In the above example, the smaller the amount that deg is increased by, the closer the pixels in the circle will be, but the slower the procedure. |
- | the closer the pixels in the circle will be, but the slower the procedure. | + | |
- | 0.005 seem to be best for the 320x200 screen. NOTE : ASPHYXIA does not use | + | |
- | this particular circle algorithm, ours is in assembly language, but this | + | |
- | one should be fast enough for most. If it isn't, give us the stuff you are | + | |
- | using it for and we'll give you ours. | + | |
+ | 0.005 seem to be best for the 320x200 screen. | ||
+ | |||
+ | <WRAP round info> | ||
+ | ASPHYXIA does not use this particular circle algorithm, ours is in assembly language, but this one should be fast enough for most. If it isn't, give us the stuff you are using it for and we'll give you ours. | ||
+ | </ | ||
==== Line algorithms ==== | ==== Line algorithms ==== | ||
- | There are many ways to draw a line on the computer. I will describe one | + | There are many ways to draw a line on the computer. I will describe one and give you two. (The second one you can figure out for yourselves; it is based on the first one but is faster) |
- | and give you two. (The second one you can figure out for yourselves; it | + | |
- | is based on the first one but is faster) | + | |
- | The first thing you need to do is pass what you want the line to look | + | The first thing you need to do is pass what you want the line to look like to your line procedure. What I have done is said that x1,y1 is the first point on the screen, and x2,y2 is the second point. We also pass the |
- | like to your line procedure. What I have done is said that x1,y1 is the | + | color to the procedure. (Remember the screens top left hand corner is (0,0); see Part 1) |
- | first point on the screen, and x2,y2 is the second point. We also pass the | + | |
- | color to the procedure. (Remember the screens top left hand corner is (0,0); | + | |
- | see Part 1) | + | |
- | Ie. | + | {{drawio> |
- | ooooooooo | + | |
- | | + | |
- | oooooooo | + | |
Again, sorry about my drawings ;-) | Again, sorry about my drawings ;-) | ||
Ligne 126: | Ligne 114: | ||
To find the length of the line, we say the following : | To find the length of the line, we say the following : | ||
+ | < | ||
| | ||
| | ||
+ | </ | ||
- | The ABS function means that whatever the result, it will give you an | + | The ABS function means that whatever the result, it will give you an absolute, or posotive, answer. At this stage I set a variable stating wheter the difference between the two x's are negative, zero or posotive. |
- | absolute, or posotive, answer. At this stage I set a variable stating | + | |
- | wheter the difference between the two x's are negative, zero or posotive. | + | |
- | (I do the same for the y's) If the difference is zero, I just use a loop | + | |
- | keeping the two with the zero difference posotive, then exit. | + | |
- | If neither | + | (I do the same for the y's) If the difference |
- | slopes, using the following | + | |
+ | If neither the x's or y's have a zero difference, I calculate the X and Y slopes, using the following two equations : | ||
+ | |||
+ | < | ||
| | ||
| | ||
+ | </ | ||
As you can see, the slopes are real numbers. | As you can see, the slopes are real numbers. | ||
- | NOTE : XSlope = 1 / YSlope | ||
- | Now, there are two ways of drawing the lines : | + | <WRAP round info> |
+ | XSlope = 1 / YSlope | ||
+ | </ | ||
+ | Now, there are two ways of drawing the lines : | ||
+ | < | ||
X = XSlope * Y | X = XSlope * Y | ||
Y = YSlope * X | Y = YSlope * X | ||
+ | </ | ||
- | The question is, which one to use? if you use the wrong one, your line | + | The question is, which one to use? if you use the wrong one, your line will look like this : |
- | will look like this : | + | |
- | o | + | {{drawio> |
- | o | + | |
- | o | + | |
Instead of this : | Instead of this : | ||
- | ooo | + | {{drawio> |
- | ooo | + | |
- | ooo | + | |
Well, the solution is as follows : | Well, the solution is as follows : | ||
- | *\``|``/* | + | < |
- | | + | *\``|``/* |
- | | + | ***\|/*** |
- | | + | ----+---- |
- | | + | ***/|\*** |
+ | */``|``\* | ||
+ | </ | ||
+ | |||
+ | If the slope angle is in the area of the stars (*) then use the first equation, if it is in the other section (`) then use the second one. | ||
+ | |||
+ | What you do is you calculate the variable on the left hand side by putting the variable on the right hand side in a loop and solving. Below is our finished line routine : | ||
- | If the slope angle is in the area of the stars (*) then use the first | + | === function: === |
- | equation, if it is in the other section (`) then use the second one. | + | |
- | What you do is you calculate the variable on the left hand side by | + | |
- | putting the variable on the right hand side in a loop and solving. Below | + | |
- | is our finished line routine | + | |
<code pascal> | <code pascal> | ||
Ligne 229: | Ligne 219: | ||
</ | </ | ||
- | Quite big, isn't it? Here is a much shorter way of doing much the same | + | Quite big, isn't it? Here is a much shorter way of doing much the same thing : |
- | thing : | + | |
<code pascal> | <code pascal> | ||
Ligne 311: | Ligne 300: | ||
Tue 27 July, 1993 | Tue 27 July, 1993 | ||
9:35 pm. | 9:35 pm. | ||
+ | </ | ||
+ | |||
+ | ==== Code Source ==== | ||
+ | |||
+ | === PASCAL === | ||
+ | |||
+ | <code pascal> | ||
+ | (*****************************************************************************) | ||
+ | (* *) | ||
+ | (* TUT3.PAS - VGA Trainer Program 3 (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 many new concepts, including: | ||
+ | (* Cirle and Line algorithms. | ||
+ | (* *) | ||
+ | (* Author | ||
+ | (* *) | ||
+ | (*****************************************************************************) | ||
+ | |||
+ | {$X+} | ||
+ | USES crt; | ||
+ | |||
+ | CONST VGA = $a000; | ||
+ | |||
+ | VAR loop1: | ||
+ | Pall : Array [1..199, | ||
+ | { This is our temporary pallette. We ony use colors 1 to 199, so we | ||
+ | only have variables for those ones. } | ||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure SetMCGA; | ||
+ | BEGIN | ||
+ | asm | ||
+ | | ||
+ | | ||
+ | end; | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure SetText; | ||
+ | BEGIN | ||
+ | asm | ||
+ | | ||
+ | | ||
+ | end; | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure Putpixel (X,Y : Integer; Col : Byte); | ||
+ | { This puts a pixel on the screen by writing directly to memory. } | ||
+ | BEGIN | ||
+ | Mem [VGA: | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | procedure WaitRetrace; | ||
+ | label | ||
+ | l1, l2; | ||
+ | asm | ||
+ | mov dx,3DAh | ||
+ | l1: | ||
+ | in al,dx | ||
+ | and al,08h | ||
+ | jnz l1 | ||
+ | l2: | ||
+ | in al,dx | ||
+ | and al,08h | ||
+ | jz l2 | ||
+ | end; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure Pal(ColorNo : Byte; R,G,B : Byte); | ||
+ | { This sets the Red, Green and Blue values of a certain color } | ||
+ | Begin | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | End; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure Circle (X, | ||
+ | { This draws a circle with centre X,Y, with Rad as it's radius } | ||
+ | VAR deg:real; | ||
+ | BEGIN | ||
+ | deg:=0; | ||
+ | repeat | ||
+ | X: | ||
+ | Y: | ||
+ | putpixel (x+160, | ||
+ | deg: | ||
+ | until (deg> | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure Line2 (x1, | ||
+ | { This draws a line from x1,y1 to x2,y2 using the first method } | ||
+ | VAR x, | ||
+ | xslope, | ||
+ | BEGIN | ||
+ | xlength: | ||
+ | if (x1-x2)< | ||
+ | if (x1-x2)=0 then dx:=0; | ||
+ | if (x1-x2)> | ||
+ | ylength: | ||
+ | if (y1-y2)< | ||
+ | if (y1-y2)=0 then dy:=0; | ||
+ | if (y1-y2)> | ||
+ | if (dy=0) then BEGIN | ||
+ | if dx<0 then for x:=x1 to x2 do | ||
+ | putpixel (x,y1,col); | ||
+ | if dx>0 then for x:=x2 to x1 do | ||
+ | putpixel (x,y1,col); | ||
+ | exit; | ||
+ | END; | ||
+ | if (dx=0) then BEGIN | ||
+ | if dy<0 then for y:=y1 to y2 do | ||
+ | putpixel (x1,y,col); | ||
+ | if dy>0 then for y:=y2 to y1 do | ||
+ | putpixel (x1,y,col); | ||
+ | exit; | ||
+ | END; | ||
+ | xslope: | ||
+ | yslope: | ||
+ | if (yslope/ | ||
+ | if dx<0 then for x:=x1 to x2 do BEGIN | ||
+ | y:= round (yslope*x); | ||
+ | | ||
+ | END; | ||
+ | if dx>0 then for x:=x2 to x1 do BEGIN | ||
+ | y:= round (yslope*x); | ||
+ | | ||
+ | END; | ||
+ | END | ||
+ | ELSE | ||
+ | BEGIN | ||
+ | if dy<0 then for y:=y1 to y2 do BEGIN | ||
+ | x:= round (xslope*y); | ||
+ | | ||
+ | END; | ||
+ | if dy>0 then for y:=y2 to y1 do BEGIN | ||
+ | x:= round (xslope*y); | ||
+ | | ||
+ | END; | ||
+ | END; | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | procedure line(a, | ||
+ | { This draws a line from x1,y1 to x2,y2 using the first method } | ||
+ | |||
+ | function sgn(a: | ||
+ | begin | ||
+ | if a>0 then sgn:=+1; | ||
+ | if a<0 then sgn:=-1; | ||
+ | if a=0 then sgn:=0; | ||
+ | end; | ||
+ | |||
+ | var u, | ||
+ | i:integer; | ||
+ | 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 := INT(m / 2); | ||
+ | FOR i := 0 TO round(m) DO | ||
+ | BEGIN | ||
+ | putpixel(a, | ||
+ | s := s + n; | ||
+ | IF not (s<m) THEN | ||
+ | BEGIN | ||
+ | s := s - m; | ||
+ | a:= a +round(d1x); | ||
+ | b := b + round(d1y); | ||
+ | END | ||
+ | ELSE | ||
+ | BEGIN | ||
+ | a := a + round(d2x); | ||
+ | b := b + round(d2y); | ||
+ | END; | ||
+ | end; | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure PalPlay; | ||
+ | { This procedure mucks about with our " | ||
+ | to screen. } | ||
+ | Var Tmp : Array[1..3] of Byte; | ||
+ | { This is used as a " | ||
+ | loop1 : Integer; | ||
+ | BEGIN | ||
+ | | ||
+ | { This copies color 199 from our virtual pallette to the Tmp variable } | ||
+ | | ||
+ | { This moves the entire virtual pallette up one color } | ||
+ | | ||
+ | { This copies the Tmp variable to the bottom of the virtual pallette } | ||
+ | | ||
+ | For loop1:=1 to 199 do | ||
+ | pal (loop1, | ||
+ | END; | ||
+ | |||
+ | |||
+ | BEGIN | ||
+ | ClrScr; | ||
+ | Writeln ('This sample program will test out our line and circle algorithms.' | ||
+ | Writeln ('In the first part, many circles will be draw creating (hopefully)' | ||
+ | Writeln ('a " | ||
+ | Writeln (' | ||
+ | Writeln ('too. Note : I am using the slower (first) line algorithm (in'); | ||
+ | Writeln (' | ||
+ | Writeln ('the second line routine. NB : For descriptions on how pallette works' | ||
+ | Writeln ('have a look at part two of this series; I won'' | ||
+ | Writeln; | ||
+ | Writeln (' | ||
+ | Writeln; Writeln; | ||
+ | Writeln ('Hit any key to continue ...'); | ||
+ | Readkey; | ||
+ | setmcga; | ||
+ | |||
+ | For Loop1 := 1 to 199 do BEGIN | ||
+ | Pall[Loop1, | ||
+ | Pall[Loop1, | ||
+ | Pall[Loop1, | ||
+ | END; | ||
+ | { This sets colors 1 to 199 to values between 33 to 63. The MOD | ||
+ | | ||
+ | |||
+ | | ||
+ | For loop1:=1 to 199 do | ||
+ | pal (loop1, | ||
+ | { This sets the true pallette to variable Pall } | ||
+ | |||
+ | for loop1:=1 to 90 do | ||
+ | circle (160, | ||
+ | { This draws 90 circles all with centres at 160,100; with increasing | ||
+ | radii and colors. } | ||
+ | |||
+ | Repeat | ||
+ | PalPlay; | ||
+ | Until keypressed; | ||
+ | Readkey; | ||
+ | |||
+ | for loop1:=1 to 199 do | ||
+ | line2 (0, | ||
+ | | ||
+ | { This draws 199 lines, all starting at 0,1 } | ||
+ | |||
+ | Repeat | ||
+ | PalPlay; | ||
+ | Until keypressed; | ||
+ | |||
+ | readkey; | ||
+ | SetText; | ||
+ | Writeln ('All done. Okay, so maybe it wasn'' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln ('on the MailBox BBS, or leave a message to ASPHYXIA on the ASPHYXIA BBS.' | ||
+ | Writeln ('Get the numbers from Roblist, or write to :'); | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln ('I hope to hear from you soon!' | ||
+ | Writeln; Writeln; | ||
+ | Write | ||
+ | Readkey; | ||
+ | END. | ||
+ | </ | ||
+ | |||
+ | === C === | ||
+ | |||
+ | <code c> | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // TUTPROG3.CPP - VGA Trainer Program 3 (in Turbo C++ 3.0) // | ||
+ | // // | ||
+ | // "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 many new concepts, including: | ||
+ | // Cirle and Line algorithms. | ||
+ | // // | ||
+ | // If you are compiling this code command line, be sure to // | ||
+ | // use the " | ||
+ | // | ||
+ | // lock up your system. | ||
+ | // // | ||
+ | // Author | ||
+ | // Translator | ||
+ | // // | ||
+ | // Last Modified : December 7, 1994 // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | // // | ||
+ | // INCLUDE FILES // | ||
+ | // // | ||
+ | |||
+ | #include < | ||
+ | // getch(), clrscr(), kbhit() | ||
+ | #include < | ||
+ | // MK_FP, Geninterrupt() | ||
+ | #include < | ||
+ | // floor(), ceil(), abs(), sin(), cos() | ||
+ | #include < | ||
+ | // cout, endl, memset(), _fmemset() | ||
+ | |||
+ | // // | ||
+ | // FUNCTION PROTOTYPES // | ||
+ | // // | ||
+ | |||
+ | // MODE SETTING FUNCTIONS | ||
+ | void SetMCGA(); | ||
+ | void SetText(); | ||
+ | |||
+ | // PALLETTE FUNCTIONS | ||
+ | void Pal (unsigned char ColorNo, | ||
+ | | ||
+ | void PalPlay(); | ||
+ | |||
+ | // SMALL UTILITY FUNCTIONS | ||
+ | int sgn (long a); | ||
+ | int round (long a); | ||
+ | |||
+ | // DRAWING FUNCTIONS | ||
+ | void Putpixel (int x, int y, unsigned char Col); | ||
+ | void Line | ||
+ | void Line2 (int x1, int y1, int x2, int y2, int col); | ||
+ | void Circle | ||
+ | void WaitRetrace(); | ||
+ | |||
+ | // // | ||
+ | // GLOBAL VARIABLE DECLARATIONS // | ||
+ | // // | ||
+ | |||
+ | // declare a pointer to the offset of VGA memory | ||
+ | unsigned char *vga = (unsigned char *) MK_FP(0xA000, | ||
+ | |||
+ | // This declares the PALL variable. 0 to 255 signifies the colors of the | ||
+ | // pallette, 1 to 3 signifies the Red, Green and Blue values. I am | ||
+ | // going to use this as a sort of " | ||
+ | // as much as I want, then suddenly bang it to screen. Pall2 is used | ||
+ | // to " | ||
+ | // the end of the program. */ | ||
+ | unsigned char Pall[256][3], | ||
+ | |||
+ | /////////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // MAIN FUNCTION | ||
+ | // // | ||
+ | /////////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void main() { | ||
+ | |||
+ | clrscr(); | ||
+ | cout | ||
+ | << "This sample program will test out our line and circle algorithms.\n" | ||
+ | << "In the first part, many circles will be draw creating (hopefully)\n" | ||
+ | << "a "" | ||
+ | << "nice. I will then draw some lines and rotate the pallette on them\n" | ||
+ | << "too. Note : I am using the slower (first) line algorithm (in\n" | ||
+ | << " | ||
+ | << "the second line routine. NB : For descriptions on how pallette works\n" | ||
+ | << "have a look at part two of this series; I won'' | ||
+ | << endl << endl; | ||
+ | cout | ||
+ | << " | ||
+ | << endl << endl; | ||
+ | cout | ||
+ | << "Hit any key to continue ..."; | ||
+ | getch(); | ||
+ | SetMCGA(); | ||
+ | |||
+ | // This sets colors 1 to 199 to values between 33 to 63. The MOD | ||
+ | // function gives you the remainder of a division, ie. 105 mod 10 = 5 } | ||
+ | for (int loop1=1; loop1< | ||
+ | Pall[loop1][0] = (loop1 % 30) + 33; | ||
+ | Pall[loop1][1] = 0; | ||
+ | Pall[loop1][2] = 0; | ||
+ | } | ||
+ | |||
+ | WaitRetrace(); | ||
+ | |||
+ | // This sets the true pallette to variable Pall | ||
+ | for (loop1=1; loop1< | ||
+ | Pal(loop1, Pall[loop1][0], | ||
+ | |||
+ | // This draws 90 circles all with centers at 160,100 with increasing | ||
+ | // radii and colors. | ||
+ | for (loop1=1; loop1< | ||
+ | Circle(160, 100, loop1, loop1); | ||
+ | |||
+ | // wait until a key is pressed | ||
+ | while (!kbhit()) PalPlay(); | ||
+ | // make sure to clear the keyboard buffer | ||
+ | getch(); | ||
+ | |||
+ | // This draws 199 lines, all starting at 0,1 | ||
+ | for (loop1=1; loop1< | ||
+ | Line2 (0, | ||
+ | // second line algorithm *** | ||
+ | |||
+ | while (!kbhit()) PalPlay(); | ||
+ | getch(); | ||
+ | |||
+ | getch(); | ||
+ | |||
+ | SetText(); | ||
+ | |||
+ | cout | ||
+ | << "All done. Okay, so maybe it wasn'' | ||
+ | << " | ||
+ | << " | ||
+ | << "on the MailBox BBS, or leave a message to ASPHYXIA on the ASPHYXIA BBS\n" | ||
+ | << "Get the numbers from Roblist, or write to :\n" | ||
+ | << " | ||
+ | << " | ||
+ | << " | ||
+ | << " | ||
+ | cout << "I hope to hear from you soon!" << endl << endl; | ||
+ | cout << "Hit any key to exit ..."; | ||
+ | |||
+ | getch(); | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // SetMCGA() - This function gets you into 320x200x256 mode. // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void SetMCGA() { | ||
+ | _AX = 0x0013; | ||
+ | geninterrupt (0x10); | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // SetText() - This function gets you into text mode. // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void SetText() { | ||
+ | _AX = 0x0003; | ||
+ | geninterrupt (0x10); | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Pal() - This sets the Red, Green, and Blue values of a certain color. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Pal(unsigned char ColorNo, unsigned char R, | ||
+ | unsigned char G, | ||
+ | |||
+ | outp (0x03C8, | ||
+ | outp (0x03C9,R); | ||
+ | outp (0x03C9,G); | ||
+ | outp (0x03C9,B); | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // PalPlay() - This function mucks about with our " | ||
+ | // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void PalPlay() { | ||
+ | |||
+ | unsigned char Tmp[3]; | ||
+ | |||
+ | // This copies color 199 from our virtual pallette to the Tmp variable. | ||
+ | _fmemmove(Tmp, | ||
+ | |||
+ | // This moves the entire virtual pallette up one color. | ||
+ | _fmemmove(Pall[2], | ||
+ | |||
+ | // This copies the Tmp variable to the bottom of the virtual pallette. | ||
+ | // Don't change 0: leave this always black to not change overscan color. | ||
+ | _fmemmove(Pall[1], | ||
+ | |||
+ | WaitRetrace(); | ||
+ | for (int loop1=0; | ||
+ | | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // sgn() - This function is used by Line() to determine the sign of a long // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | int sgn (long a) { | ||
+ | if (a > 0) return +1; | ||
+ | else if (a < 0) return -1; | ||
+ | else return 0; | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // round() - This function is used by Line() to round a long to the // | ||
+ | // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | int round (long a) { | ||
+ | if ( (a - (int)a) < 0.5) return floor(a); | ||
+ | else return ceil(a); | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Putpixel() - This puts a pixel on the screen by writing directly to // | ||
+ | // memory. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Putpixel (int x, int y, unsigned char Col) { | ||
+ | memset(vga+(x+(y*320)), | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Line() - This draws a line from a,b to c,d of color col. // | ||
+ | // This function will be explained in more detail in tut3new.zip | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Line(int a, int b, int c, int d, int col) { | ||
+ | |||
+ | long u, | ||
+ | int i; | ||
+ | |||
+ | u = c-a; // x2-x1 | ||
+ | v = d-b; // y2-y1 | ||
+ | d1x = sgn(u); | ||
+ | d1y = sgn(v); | ||
+ | d2x = sgn(u); | ||
+ | d2y = 0; | ||
+ | m = abs(u); | ||
+ | n = abs(v); | ||
+ | |||
+ | if (m<=n) { // if the x distance is greater than the y distance | ||
+ | d2x = 0; | ||
+ | d2y = sgn(v); // d2y is the sign of v (x2-x1) (VALUE -1,0,1) | ||
+ | m = abs(v); // m is the distance between y1 and y2 | ||
+ | n = abs(u); // n is the distance between x1 and x2 | ||
+ | } | ||
+ | |||
+ | s = (int)(m / 2); // s is the m distance (either x or y) divided by 2 | ||
+ | |||
+ | for (i=0; | ||
+ | // is = to m (y or x distance) | ||
+ | Putpixel(a, | ||
+ | s += n; // add n (dis of x or y) to s (dis of x of y) | ||
+ | if (s >= m) { // if s is >= m (distance between y1 and y2) | ||
+ | s -= m; | ||
+ | a += d1x; | ||
+ | b += d1y; | ||
+ | } | ||
+ | else { | ||
+ | a += d2x; | ||
+ | b += d2y; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Line2() - This function draws a line from x1,y1 to x2,y2 using the // | ||
+ | // first method. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Line2(int x1, int y1, int x2, int y2, int col) { | ||
+ | |||
+ | int x, y, xlength, ylength, dx, dy; | ||
+ | float xslope, yslope; | ||
+ | |||
+ | xlength = abs(x1-x2); | ||
+ | if ((x1-x2) | ||
+ | if ((x1-x2) == 0) dx = 0; | ||
+ | if ((x1-x2) | ||
+ | |||
+ | ylength = abs(y1-y2); | ||
+ | if ((y1-y2) | ||
+ | if ((y1-y2) == 0) dy = 0; | ||
+ | if ((y1-y2) | ||
+ | |||
+ | if (dy == 0) { | ||
+ | if (dx < 0) | ||
+ | for (x=x1; x<x2+1; x++) | ||
+ | Putpixel (x,y1,col); | ||
+ | if (dx > 0) | ||
+ | for (x=x2; x<x1+1; x++) | ||
+ | Putpixel (x,y1,col); | ||
+ | } | ||
+ | |||
+ | if (dx == 0) { | ||
+ | if (dy < 0) | ||
+ | for (y=y1; y<y2+1; y++) | ||
+ | Putpixel (x1,y,col); | ||
+ | if (dy > 0) | ||
+ | for (y=y2; y<y1+1; y++) | ||
+ | Putpixel (x1,y,col); | ||
+ | } | ||
+ | |||
+ | if ((xlength != 0) && (ylength != 0)) { | ||
+ | xslope = (float)xlength/ | ||
+ | yslope = (float)ylength/ | ||
+ | } | ||
+ | else { | ||
+ | xslope = 0.0; | ||
+ | yslope = 0.0; | ||
+ | } | ||
+ | |||
+ | if ((xslope != 0) && (yslope != 0) && | ||
+ | (yslope/ | ||
+ | if (dx < 0) | ||
+ | for (x=x1; x<x2+1; x++) { | ||
+ | y = round (yslope*x); | ||
+ | Putpixel (x,y,col); | ||
+ | } | ||
+ | if (dx > 0) | ||
+ | for (x=x2; x<x1+1; x++) { | ||
+ | y = round (yslope*x); | ||
+ | Putpixel (x,y,col); | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | if (dy < 0) | ||
+ | for (y=x1; y<x2+1; y++) { | ||
+ | x = round (xslope*y); | ||
+ | Putpixel (x,y,col); | ||
+ | } | ||
+ | if (dy > 0) | ||
+ | for (y=x2; y<x1+1; y++) { | ||
+ | x = round (xslope*y); | ||
+ | Putpixel (x,y,col); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Circle() - This draws a circle with center X,Y, with Rad as its radius. // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Circle(int X, int Y, int rad, int col) { | ||
+ | |||
+ | float deg = 0; | ||
+ | |||
+ | do { | ||
+ | X = round(rad * cos(deg)); | ||
+ | Y = round(rad * sin(deg)); | ||
+ | Putpixel (X+160, Y+100, col); | ||
+ | deg += 0.005; | ||
+ | } | ||
+ | while (deg <= 6.4); | ||
+ | |||
+ | } | ||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // WaitRetrace() - This waits until you are in a Verticle Retrace. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void WaitRetrace() { | ||
+ | |||
+ | _DX = 0x03DA; | ||
+ | |||
+ | l1: asm { | ||
+ | in al,dx; | ||
+ | and al,0x08; | ||
+ | jnz l1; | ||
+ | } | ||
+ | |||
+ | l2: asm { | ||
+ | in al,dx; | ||
+ | and al,0x08; | ||
+ | jz l2; | ||
+ | } | ||
+ | } | ||
</ | </ | ||
<nspages back2root/ | <nspages back2root/ |