Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
back2root:archives:denthor:part-04 [2021/08/26 22:21] – [In closing] frater | back2root:archives:denthor:part-04 [2021/09/04 22:44] (Version actuelle) – frater | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | ===== PART 4 : Virtual Screen ===== | + | ===== PART 04 : Virtual Screen ===== |
Howdy all! Welcome to the fourth part of this trainer series! It's a little late, but I am sure you will find that the wait was worth it, becase today I am going to show you how to use a very powerful tool : Virtual Screens. | Howdy all! Welcome to the fourth part of this trainer series! It's a little late, but I am sure you will find that the wait was worth it, becase today I am going to show you how to use a very powerful tool : Virtual Screens. | ||
Ligne 152: | Ligne 152: | ||
Denthor | Denthor | ||
+ | |||
+ | ==== Code Source ==== | ||
+ | |||
+ | === PASCAL === | ||
+ | |||
+ | <code pascal> | ||
+ | {$X+} (* This is a handy little trick to know. If you put this at the top | ||
+ | of your program, you do not have to set a variable when calling | ||
+ | a function, i.e. you may just say ' | ||
+ | ' | ||
+ | |||
+ | USES Crt; (* This has a few nice functions in it, such as the | ||
+ | | ||
+ | |||
+ | CONST VGA = $a000; | ||
+ | VGA screen. | ||
+ | |||
+ | Type Virtual = Array [1..64000] of byte; { The size of our Virtual Screen } | ||
+ | | ||
+ | |||
+ | VAR Virscr : VirtPtr; | ||
+ | Vaddr : word; { The segment of our virtual screen} | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure SetMCGA; | ||
+ | BEGIN | ||
+ | asm | ||
+ | | ||
+ | | ||
+ | end; | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure SetText; | ||
+ | BEGIN | ||
+ | asm | ||
+ | | ||
+ | | ||
+ | end; | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure Cls (Col : Byte; Where: | ||
+ | { This clears the screen to the specified color, on the VGA or on the | ||
+ | virtual screen } | ||
+ | BEGIN | ||
+ | Fillchar (Mem [where: | ||
+ | END; | ||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | procedure WaitRetrace; | ||
+ | { This waits until you are in a Verticle Retrace ... this means that all | ||
+ | screen manipulation you do only appears on screen in the next verticle | ||
+ | retrace ... this removes most of the " | ||
+ | when changing the pallette. It unfortunately slows down your program | ||
+ | by " | ||
+ | that the program will run at almost the same speed on different | ||
+ | speeds of computers which have similar monitors. In our SilkyDemo, | ||
+ | we used a WaitRetrace, | ||
+ | fast) speed when Turbo is on or off. } | ||
+ | |||
+ | 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 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 PutPixel (X,Y : Integer; Col : Byte; Where : Word); | ||
+ | { This puts a pixel at X,Y using color col, on VGA or the Virtual Screen} | ||
+ | BEGIN | ||
+ | Mem [Where: | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure Flip; | ||
+ | { This flips the virtual screen to the VGA screen. } | ||
+ | BEGIN | ||
+ | Move (Virscr^, | ||
+ | END; | ||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure BlockMove; | ||
+ | { This tests various ways of moving a block around the screen } | ||
+ | VAR loop1, | ||
+ | BEGIN | ||
+ | For loop1:=1 to 50 do BEGIN { This draw a block } | ||
+ | for loop2:=1 to 50 do | ||
+ | for loop3:=1 to 50 do | ||
+ | putpixel (loop1+loop2, | ||
+ | cls (0,VGA); | ||
+ | END; | ||
+ | |||
+ | For loop1:=1 to 50 do BEGIN { This draws a block } | ||
+ | for loop2:=1 to 50 do { to the virtual screen, } | ||
+ | for loop3:=1 to 50 do { then flips it to VGA } | ||
+ | putpixel (loop1+loop2, | ||
+ | flip; | ||
+ | cls (0,Vaddr); | ||
+ | END; | ||
+ | |||
+ | For loop1:=1 to 50 do BEGIN { This draws a block } | ||
+ | for loop2:=1 to 50 do { to the virtual screen, } | ||
+ | for loop3:=1 to 50 do { waits for a retrace, | ||
+ | putpixel (loop1+loop2, | ||
+ | waitretrace; | ||
+ | flip; | ||
+ | cls (0,Vaddr); | ||
+ | END; | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure PatternDraw; | ||
+ | { This test the speed of flipping by drawing two patterns and flipping | ||
+ | them } | ||
+ | VAR loop1, | ||
+ | BEGIN | ||
+ | for loop1:=1 to 100 do { This draws pattern one } | ||
+ | for loop2:=1 to 100 do { to the virtual screen | ||
+ | putpixel (loop1, | ||
+ | flip; | ||
+ | |||
+ | for loop1:=1 to 100 do { This draws pattern two } | ||
+ | for loop2:=1 to 100 do { to the virtual screen | ||
+ | putpixel (loop1, | ||
+ | flip; | ||
+ | END; | ||
+ | |||
+ | |||
+ | BEGIN | ||
+ | ClrScr; | ||
+ | Writeln ('This program will demonstrate the power of virtual screens.' | ||
+ | Writeln ('A block will firstly move across the screen, being drawn and'); | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln ('to the VGA screen without a retrace (see part 2). The the'); | ||
+ | Writeln (' | ||
+ | Writeln; | ||
+ | Writeln ('I will then draw a pattern, flip it to VGA, draw another' | ||
+ | Writeln (' | ||
+ | Writeln ('This will demonstrate that even when I put down 10000 pixels,' | ||
+ | Writeln ('then flip them to the VGA, it is still relatively fast. '); | ||
+ | Writeln; Writeln; | ||
+ | Writeln ('Hit any key to continue ...'); | ||
+ | readkey; | ||
+ | setmcga; | ||
+ | setupvirtual; | ||
+ | cls (0, | ||
+ | it is usually filled with random garbage. It is always | ||
+ | wise to clear the virtual screen directly afterwards } | ||
+ | BlockMove; | ||
+ | |||
+ | Repeat | ||
+ | PatternDraw; | ||
+ | Until keypressed; | ||
+ | |||
+ | Readkey; | ||
+ | settext; | ||
+ | shutdown; | ||
+ | Writeln ('All done. This concludes the fourth sample program in the ASPHYXIA' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln ('I hope to hear from you soon!' | ||
+ | Writeln; Writeln; | ||
+ | Write | ||
+ | Readkey; | ||
+ | END. | ||
+ | </ | ||
+ | |||
+ | === C === | ||
+ | <code c> | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // TUTPROG4.CPP - VGA Trainer Program 4 (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 implements virtual screens, a great way // | ||
+ | // to update your screen. | ||
+ | // // | ||
+ | // For this particular program, I have found the compiler | ||
+ | // | ||
+ | // -ml (Large memory model). | ||
+ | // | ||
+ | // Also, you might want to go under " | ||
+ | // and increase your programs Heap size to > | ||
+ | // know if <64k will lock your system, but I had problems. // | ||
+ | // // | ||
+ | // Author | ||
+ | // Translator | ||
+ | // // | ||
+ | // Last Modified : December 23, 1994 // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | // // | ||
+ | // INCLUDE FILES // | ||
+ | // // | ||
+ | |||
+ | #include < | ||
+ | // clrscr(), getch(), kbhit() | ||
+ | #include < | ||
+ | // MK_FP, geninterrupt() | ||
+ | #include < | ||
+ | // _fmemset(), cout, memset(), _fmemcpy() | ||
+ | #include < | ||
+ | // calloc(), exit(), free() | ||
+ | |||
+ | // // | ||
+ | // FUNCTION PROTOTYPES // | ||
+ | // // | ||
+ | |||
+ | // MODE SETTING FUNCTIONS | ||
+ | void SetMCGA(); | ||
+ | void SetText(); | ||
+ | |||
+ | // VIRTUAL SCREEN FUNCTIONS | ||
+ | void SetUpVirtual(); | ||
+ | void ShutDown(); | ||
+ | void Flip(); | ||
+ | |||
+ | // UTILITY FUNCTIONS | ||
+ | void Cls(unsigned char Col, unsigned char *Where); | ||
+ | void Putpixel (int x, int y, unsigned char Col, unsigned int Where); | ||
+ | void WaitRetrace(); | ||
+ | |||
+ | // MID-LEVEL FUNCTIONS | ||
+ | void BlockMove(); | ||
+ | void PatternDraw(); | ||
+ | |||
+ | // // | ||
+ | // GLOBAL VARIABLE DECLARATIONS // | ||
+ | // // | ||
+ | |||
+ | // declare a pointer to the offset of the Virtual Screen | ||
+ | unsigned char *vaddr = NULL; | ||
+ | |||
+ | // declare a pointer to the offset of the VGA memory | ||
+ | unsigned char *vga = (unsigned char *) MK_FP(0xA000, | ||
+ | |||
+ | /////////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // MAIN FUNCTION | ||
+ | // // | ||
+ | /////////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void main() { | ||
+ | |||
+ | clrscr(); | ||
+ | cout | ||
+ | << "This program will demonstrate the power of virtual screens.\n" | ||
+ | << "A block will firstly move across the screen, being drawn and\n" | ||
+ | << " | ||
+ | << " | ||
+ | << "to the VGA screen without a retrace (see part 2). The the\n" | ||
+ | << "block will go again, with flipping and a retrace.\n\n" | ||
+ | << "I will then draw a pattern, flip it to VGA, draw another\n" | ||
+ | << " | ||
+ | << "This will demonstrate that even when I put down 10000 pixels, | ||
+ | << "then flip them to the VGA, it is still relatively fast.\n\n"; | ||
+ | cout << "Hit any key to continue ..."; | ||
+ | getch(); | ||
+ | SetMCGA(); | ||
+ | SetUpVirtual(); | ||
+ | Cls(0, | ||
+ | // it is usually filled with random garbage. It is always | ||
+ | // wise to clear the virtual screen directly afterwards | ||
+ | BlockMove(); | ||
+ | |||
+ | do PatternDraw(); | ||
+ | while (!kbhit()); | ||
+ | getch(); | ||
+ | |||
+ | SetText(); | ||
+ | ShutDown(); | ||
+ | cout | ||
+ | << "All done. This concludes the fourth sample program in the ASPHYXIA\n" | ||
+ | << " | ||
+ | << "SMITH on the MailBox BBS, or leave a message to ASPHYXIA on the\n" | ||
+ | << " | ||
+ | << " | ||
+ | << " | ||
+ | << " | ||
+ | << " | ||
+ | << "I hope to hear from you soon!\n\n"; | ||
+ | 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); | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Cls() - This clears the screen to the specified color, on the VGA or on // | ||
+ | // the Virtual screen. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Cls(unsigned char Col, unsigned char *Where) { | ||
+ | _fmemset(Where, | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // 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; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // SetUpVirtual() - This sets up the memory needed for the virtual screen. // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void SetUpVirtual() { | ||
+ | |||
+ | vaddr = (unsigned char *) calloc(64000, | ||
+ | if (vaddr == NULL) { | ||
+ | SetText(); | ||
+ | cout << "Not enough memory available, exiting program..."; | ||
+ | exit(1); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // ShutDown() - This frees the memory used by the virtual screen. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void ShutDown() { | ||
+ | free(vaddr); | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Putpixel() - This puts a pixel at X,Y using color Col, on VGA or the // | ||
+ | // Virtual Screen; | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Putpixel (int x, int y, unsigned char Col, unsigned char *Where) { | ||
+ | memset(Where+(x+(y*320)), | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Flip() - This flips the virtual screen to the VGA screen. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Flip() { | ||
+ | _fmemcpy(vga, | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // BlockMove() - This tests various ways of moving a block around the // | ||
+ | // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void BlockMove() { | ||
+ | |||
+ | int loop1, loop2, loop3; | ||
+ | |||
+ | // This draws a block directly to the VGA with no flipping | ||
+ | for (loop1=1; loop1< | ||
+ | for (loop2=1; loop2< | ||
+ | for (loop3=1; loop3< | ||
+ | Putpixel (loop1+loop2, | ||
+ | Cls(0,vga); | ||
+ | } | ||
+ | |||
+ | // This draws a block to the virtual screen, then flips it to the VGA | ||
+ | for (loop1=1; loop1< | ||
+ | for (loop2=1; loop2< | ||
+ | for (loop3=1; loop3< | ||
+ | Putpixel (loop1+loop2, | ||
+ | Flip(); | ||
+ | Cls(0, | ||
+ | } | ||
+ | |||
+ | // This draws to the virtual screen, waits for retrace, then flips to VGA | ||
+ | for (loop1=1; loop1< | ||
+ | for (loop2=1; loop2< | ||
+ | for (loop3=1; loop3< | ||
+ | Putpixel (loop1+loop2, | ||
+ | WaitRetrace(); | ||
+ | Flip(); | ||
+ | Cls(0, | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // PatternDraw() - This tests the speed of flipping by drawing two // | ||
+ | // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void PatternDraw() { | ||
+ | |||
+ | int loop1, loop2; | ||
+ | |||
+ | // This draws pattern #1 to the virtual screen, then flips it to VGA | ||
+ | for(loop1=1; | ||
+ | for(loop2=1; | ||
+ | Putpixel (loop1, | ||
+ | Flip(); | ||
+ | |||
+ | // This draws pattern #2 to the virtual screen, then flips it to VGA | ||
+ | for(loop1=1; | ||
+ | for(loop2=1; | ||
+ | Putpixel (loop1, | ||
+ | Flip(); | ||
+ | |||
+ | } | ||
+ | </ | ||
<nspages back2root/ | <nspages back2root/ |