home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / MOU_ROUT.ZIP / PAGEFLIP.PAS / text0000.txt < prev   
Encoding:
Text File  |  1990-05-08  |  4.2 KB  |  100 lines

  1. Some days ago, one of you asked for a solution to do fast flicker-free
  2. animation in TurboPascal. I myself had the same problem and circumvented it by
  3. a simple technique called "page-flipping": nearly every graphic card has 2
  4. independent graphic pages, so it is possible to draw at one page while showing
  5. the other. If the "background" page is finished, you just "flip" the pages:
  6. thus, at any time all actions take place in the background and you get a smooth
  7. animation!
  8. In TP, you choose the visible page with "SetVisualPage" and the working page
  9. with "SetActivePage". - Take the following program as an example: it animates a
  10. hatched square, either with or without page-flipping (adapt proc. "Initialize"
  11. if you have a Hercules instead of an EGA/VGA):
  12.  
  13. PROGRAM page_flipping_demo; {by Kai Rohrbacher, TP 5.0, 4/25/90}
  14. USES Crt,Graph;
  15. CONST seeing_page:Word=0; {number of actual seen page}
  16. VAR GraphDriver,GraphMode,x,y,xold,yold,xtemp,ytemp:Integer;
  17.     Sprite:Pointer; {pointer to sprite-data}
  18.     ch:char;
  19.     WITH_PAGE_FLIPPING:Boolean; {demonstration mode}
  20.  
  21. PROCEDURE Initialize; {set any graphic-mode with 2 pages; here EGA}
  22. BEGIN
  23.  GraphDriver:=EGA; GraphMode:=EGAHi;
  24.  InitGraph(GraphDriver,GraphMode,'');
  25.  IF GraphResult<>grOK THEN BEGIN Writeln('No EGA!'); Halt(1) END;
  26. END;
  27.  
  28. PROCEDURE initialize_flip; {clear pages; show one, work on the other}
  29. BEGIN
  30.  setactivepage(0); cleardevice;
  31.  outtextxy(100,0,'Page 0 - Use I,J,K,M, Q=Quit');
  32.  setactivepage(1); cleardevice;
  33.  outtextxy(100,0,'Page 1 - Use I,J,K,M, Q=Quit');
  34.  setactivepage(1-seeing_page); setvisualpage(seeing_page)
  35. END;
  36.  
  37. PROCEDURE flip; {exchange active & visible page}
  38. BEGIN
  39.  setactivepage(seeing_page); seeing_page:=1-seeing_page;
  40.  setvisualpage(seeing_page);
  41. END;
  42.  
  43. PROCEDURE update_sprite; {works totally on background page!}
  44. BEGIN
  45.  IF (xold<>-1) AND (yold<>-1) THEN PutImage(xold,yold,sprite^,XORput);
  46.  PutImage(x,y,sprite^,XORput)
  47. END;
  48.  
  49. BEGIN {main}
  50.  Write('With (1) or without (2) pageflipping? ');
  51.  REPEAT ch:=UpCase(readkey) UNTIL ch in ['1','2'];
  52.  WITH_PAGE_FLIPPING:=ch='1'; {set mode}
  53.  Initialize;
  54.  {generate sprite and save it on TP's stack:}
  55.  rectangle(0,0,50,50); setFillStyle(Hatchfill,white);
  56.  FloodFill(1,1,white); GetMem(sprite,ImageSize(0,0,50,50));
  57.  GetImage(0,0,50,50,sprite^); cleardevice;
  58.  outtextxy(0,0,'Use I,J,K,M, Q=Quit');
  59.  IF WITH_PAGE_FLIPPING THEN initialize_flip;
  60.  xold:=-1; yold:=-1; xtemp:=-1; ytemp:=-1; {-1=flag: 'currently not used'}
  61.  x:=100; y:=100; {starting point of animation}
  62.  REPEAT
  63.   ch:=UpCase(readkey);
  64.   CASE ch OF {what action?}
  65.    'J':dec(x); 'K':inc(x); 'I':dec(y); 'M':inc(y); 'Q':;
  66.    ELSE BEGIN sound(1200); delay(100); nosound END
  67.   END;
  68.  update_sprite; {remove old, draw new}
  69.  IF WITH_PAGE_FLIPPING
  70.   THEN BEGIN {shift through: x->xtemp->xold, y->ytemp->yoldf}
  71.         xold:=xtemp; yold:=ytemp; xtemp:=x; ytemp:=y; flip
  72.        END   {so after 2 cycles the sprite is cleared from correct page}
  73.   ELSE BEGIN xold:=x; yold:=y END; {no flipping=no such mechanism needed}
  74.  UNTIL ch='Q';
  75.  FreeMem(sprite,ImageSize(0,0,50,50)); closegraph; {end correctly}
  76. END.
  77.  
  78. The only thing to notice is that you have to store coordinates for 2 
  79. cycles to be able to erase a sprite on the correct page.
  80. There remains one last possibility of (minor) flicker: depending on your
  81. PC's BIOS, it may happen that programs flip pages while the cathode ray
  82. is in the midst of displaying data: in that case you have to bypass BIOS
  83. and synchronize switching directly with the "vertical retrace" (the 
  84. moment while the cathode ray moves back from the bottom-right to the
  85. upper-left corner). As a time-critical task (the corresponding bit at 
  86. port $3DA, Bitmask 8 (or $3BA, Bitmask 128 for HGC) toggles with 50Hz),
  87. you should do that in assembler.
  88. To all of you who hope to program an arcade game completely in TP, be 
  89. warned: TP is just to slow to do the job (try to animate -say- 30 
  90. sprites at once)! Me too, I had to discover this (3 years ago) -and came
  91. out with a self-written TP-unit, spritedesigner and a lot of integrated
  92. assembler stuff (for the animation itself, background-saving, collision
  93. detection, scrolling and that things).
  94. I am planning to release this package (as shareware) here in FRG very
  95. soon, so if you are interested, watch out!
  96. S_ROHRBACHER@IRAV1.IRA.UKA.DE    (Kai Rohrbacher)        
  97.  
  98.  
  99. 
  100.