Outils pour utilisateurs

Outils du site


back2root:archives:denthor:part-04

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
back2root:archives:denthor:part-04 [2021/08/26 22:21] – [In closing] fraterback2root: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 'READKEY' instead of
 +           'CH:=READKEY'                                                *)
 +
 +USES Crt;           (* This has a few nice functions in it, such as the
 +                       READKEY command.                                 *)
 +
 +CONST VGA = $a000;  (* This sets the constant VGA to the segment of the
 +                       VGA screen.                                      *)
 +
 +Type Virtual = Array [1..64000] of byte;  { The size of our Virtual Screen }
 +     VirtPtr = ^Virtual;                  { Pointer to the virtual screen }
 +
 +VAR Virscr : VirtPtr;                      { Our first Virtual screen }
 +    Vaddr  : word;                        { The segment of our virtual screen}
 +
 +
 +{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
 +Procedure SetMCGA;  { This procedure gets you into 320x200x256 mode. }
 +BEGIN
 +  asm
 +     mov        ax,0013h
 +     int        10h
 +  end;
 +END;
 +
 +
 +{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
 +Procedure SetText;  { This procedure returns you to text mode.  }
 +BEGIN
 +  asm
 +     mov        ax,0003h
 +     int        10h
 +  end;
 +END;
 +
 +
 +{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
 +Procedure Cls (Col : Byte; Where:Word);
 +   { This clears the screen to the specified color, on the VGA or on the
 +        virtual screen }
 +BEGIN
 +  Fillchar (Mem [where:0],64000,col);
 +END;
 +
 +{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
 +procedure WaitRetrace; assembler;
 +  { 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 "fuzz" that you see on the screen
 +    when changing the pallette. It unfortunately slows down your program
 +    by "synching" your program with your monitor card ... it does mean
 +    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, and it therefore runs at the same (fairly
 +    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,64000);
 +  vaddr := seg (virscr^);
 +END;
 +
 +
 +{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
 +Procedure ShutDown;
 +   { This frees the memory used by the virtual screen }
 +BEGIN
 +  FreeMem (VirScr,64000);
 +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:X+(Y*320)]:=col;
 +END;
 +
 +
 +{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
 +Procedure Flip;
 +   { This flips the virtual screen to the VGA screen. }
 +BEGIN
 +  Move (Virscr^,mem [VGA:0],64000);
 +END;
 +
 +{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
 +Procedure BlockMove;
 +   { This tests various ways of moving a block around the screen }
 +VAR loop1,loop2,loop3:Integer;
 +BEGIN
 +  For loop1:=1 to 50 do BEGIN                     { This draw a block    }
 +    for loop2:=1 to 50 do                          directly to VGA, no }
 +      for loop3:=1 to 50 do                        flipping            }
 +        putpixel (loop1+loop2,loop3,32,VGA);
 +    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,loop3,32,Vaddr);
 +    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,loop3,32,Vaddr);    { then flips it to VGA   }
 +    waitretrace;
 +    flip;
 +    cls (0,Vaddr);
 +  END;
 +END;
 +
 +
 +{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
 +Procedure PatternDraw;
 +   { This test the speed of flipping by drawing two patterns and flipping
 +     them }
 +VAR loop1,loop2:integer;
 +BEGIN
 +  for loop1:=1 to 100 do                        { This draws pattern one }
 +    for loop2:=1 to 100 do                      { to the virtual screen  }
 +      putpixel (loop1,loop2,loop1,Vaddr);       { then flips it to VGA   }
 +  flip;
 +
 +  for loop1:=1 to 100 do                        { This draws pattern two }
 +    for loop2:=1 to 100 do                      { to the virtual screen  }
 +      putpixel (loop1,loop2,loop2,Vaddr);       { then flips it to VGA   }
 +  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 ('erased totally on the VGA. Then the same block will move');
 +  Writeln ('across, but will be drawn on the virtual screen and flipped');
 +  Writeln ('to the VGA screen without a retrace (see part 2). The the');
 +  Writeln ('block will go again, with flipping and a retrace.');
 +  Writeln;
 +  Writeln ('I will then draw a pattern, flip it to VGA, draw another');
 +  Writeln ('pattern, flip it to VGA, and repeat that until a key is pressed.');
 +  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,vaddr);    { After you have got the memory for the virtual screen,
 +                      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 ('Training series. You may reach DENTHOR under the name of GRANT');
 +  Writeln ('SMITH on the MailBox BBS, or leave a message to ASPHYXIA on the');
 +  Writeln ('ASPHYXIA BBS. Get the numbers from Roblist, or write to :');
 +  Writeln ('             Grant Smith');
 +  Writeln ('             P.O. Box 270');
 +  Writeln ('             Kloof');
 +  Writeln ('             3640');
 +  Writeln ('I hope to hear from you soon!');
 +  Writeln; Writeln;
 +  Write   ('Hit any key to exit ...');
 +  Readkey;
 +END.
 +</code>
 +
 +=== C ===
 +<code c>
 +/////////////////////////////////////////////////////////////////////////////
 +//                                                                         //
 +// TUTPROG4.CPP - VGA Trainer Program 4 (in Turbo C++ 3.0)                 //
 +//                                                                         //
 +// "The VGA Trainer Program" is written by Denthor of Asphyxia. However it //
 +// 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  //
 +//                 option -mc (Compact memory model) to work better than   //
 +//                 -ml (Large memory model).  However, you must use -mc or //
 +//                 greater.                                                //
 +//                 Also, you might want to go under "Options...Debugger"   //
 +//                 and increase your programs Heap size to >64k.  I don' //
 +//                 know if <64k will lock your system, but I had problems. //
 +//                                                                         //
 +// Author        : Grant Smith (Denthor) - denthor@beastie.cs.und.ac.za    //
 +// Translator    : Christopher G. Mann   - r3cgm@dax.cc.uakron.edu         //
 +//                                                                         //
 +// Last Modified : December 23, 1994                                       //
 +//                                                                         //
 +/////////////////////////////////////////////////////////////////////////////
 +
 +//               //
 +// INCLUDE FILES //
 +//               //
 +
 +  #include <conio.h>
 +    // clrscr(), getch(), kbhit()
 +  #include <dos.h>
 +    // MK_FP, geninterrupt()
 +  #include <iostream.h>
 +    // _fmemset(), cout, memset(), _fmemcpy()
 +  #include <stdlib.h>
 +    // 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, 0);
 +
 +///////////////////////////////////////////////////////////////////////////////
 +//                                                                           //
 +//                                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"
 +    << "erased totally on the VGA. Then the same block will move\n"
 +    << "across, but will be drawn on the virtual screen and flipped\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"
 +    << "pattern, flip it to VGA, and repeat that until a key is pressed.\n"
 +    << "This will demonstrate that even when I put down 10000 pixels,\n"
 +    << "then flip them to the VGA, it is still relatively fast.\n\n";
 +  cout << "Hit any key to continue ...";
 +  getch();
 +  SetMCGA();
 +  SetUpVirtual();
 +  Cls(0,vaddr);    // After you have got the memory for the virtual screen,
 +    // it is usually filled with random garbage. It is always
 +    // wise to clear the virtual screen directly afterwards
 +  BlockMove();
 +
 +  do    PatternDraw();
 +  while (!kbhit());
 +  getch();         // getch() = clear keyboard buffer from kbhit()
 +
 +  SetText();
 +  ShutDown();
 +  cout
 +    << "All done. This concludes the fourth sample program in the ASPHYXIA\n"
 +    << "Training series. You may reach DENTHOR under the name of GRANT\n"
 +    << "SMITH on the MailBox BBS, or leave a message to ASPHYXIA on the\n"
 +    << "ASPHYXIA BBS. Get the numbers from Roblist, or write to :\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 ...";
 +  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, Col, 64000);
 +}
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
 +//                                                                         //
 +// 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,1);
 +  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)),Col,1);
 +}
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
 +//                                                                         //
 +// Flip() - This flips the virtual screen to the VGA screen.               //
 +//                                                                         //
 +/////////////////////////////////////////////////////////////////////////////
 +
 +void Flip() {
 +  _fmemcpy(vga,vaddr,64000);
 +}
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
 +//                                                                         //
 +// BlockMove() - This tests various ways of moving a block around the      //
 +//               screen.                                                   //
 +//                                                                         //
 +/////////////////////////////////////////////////////////////////////////////
 +
 +void BlockMove() {
 +
 +  int loop1, loop2, loop3;
 +
 +  // This draws a block directly to the VGA with no flipping
 +  for (loop1=1; loop1<51; loop1++) {
 +    for (loop2=1; loop2<51; loop2++)
 +      for (loop3=1; loop3<51; loop3++)
 + Putpixel (loop1+loop2,loop3,32, vga);
 +    Cls(0,vga);
 +  }
 +
 +  // This draws a block to the virtual screen, then flips it to the VGA
 +  for (loop1=1; loop1<51; loop1++) {
 +    for (loop2=1; loop2<51; loop2++)
 +      for (loop3=1; loop3<51; loop3++)
 + Putpixel (loop1+loop2,loop3,32, vaddr);
 +    Flip();
 +    Cls(0,vaddr);
 +  }
 +
 +  // This draws to the virtual screen, waits for retrace, then flips to VGA
 +  for (loop1=1; loop1<51; loop1++) {
 +    for (loop2=1; loop2<51; loop2++)
 +      for (loop3=1; loop3<51; loop3++)
 + Putpixel (loop1+loop2,loop3,32, vaddr);
 +    WaitRetrace();
 +    Flip();
 +    Cls(0,vaddr);
 +  }
 +
 +}
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
 +//                                                                         //
 +// PatternDraw() - This tests the speed of flipping by drawing two         //
 +//                 patterns and flipping them.                             //
 +//                                                                         //
 +/////////////////////////////////////////////////////////////////////////////
 +
 +void PatternDraw() {
 +
 +  int loop1, loop2;
 +
 +  // This draws pattern #1 to the virtual screen, then flips it to VGA
 +  for(loop1=1; loop1<101; loop1++)
 +    for(loop2=1; loop2<101; loop2++)
 + Putpixel (loop1,loop2,loop1,vaddr);
 +  Flip();
 +
 +  // This draws pattern #2 to the virtual screen, then flips it to VGA
 +  for(loop1=1; loop1<101; loop1++)
 +    for(loop2=1; loop2<101; loop2++)
 + Putpixel (loop1,loop2,loop2,vaddr);
 +  Flip();
 +
 +}
 +</code>
  
 <nspages back2root/archives/denthor -simpleList -title -h1 -exclude:start -textPages="Denthor VGA Trainer"> <nspages back2root/archives/denthor -simpleList -title -h1 -exclude:start -textPages="Denthor VGA Trainer">
back2root/archives/denthor/part-04.1630009293.txt.gz · Dernière modification : 2021/08/26 22:21 de frater