home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / GRAPHICS / PLOT / SURFUTI3.ZIP / PLAYBACK.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1991-11-29  |  16.9 KB  |  540 lines

  1. {$I DEFINES.INC}
  2. program playback;
  3.  
  4. { KVC 09/14/91 Made SURFbgi use conditional }
  5. uses crt,
  6.   XMS,
  7.   surfGRAF,
  8.   SHAREDEC,
  9. {$IFDEF EXTERNAL}
  10.   SURFbgi;
  11. {$ELSE}
  12.   Graph;
  13. {$ENDIF}
  14.  
  15. {plays back a graphic image stored with Surfmodl}
  16.  
  17. type
  18.   picptr = ^pic;
  19.  
  20.   pic = record
  21.           speed       : integer;        { delay between screens }
  22.           next        : picptr;         { next in linked list }
  23.           prev        : picptr;         { prev for doubly-linked list }
  24.           image       : picbuf;         { screen buffers }
  25.           xms_image   : xmsbuf;         { screen buffers in XMS }
  26.           nbuf        : integer;        { # screen buffers used }
  27.           nlines_buf  : nlpic;          { # screen lines in each buffer }
  28.           xms_bufsize : xmsbuf;         { # bytes stored in XMS buffer }
  29.           buftype     : buffertype;     { buffer type (1=std mem, 2=xms mem) }
  30.           grsys       : integer;        { graphic system type }
  31.           grmode      : integer;        { graphic mode }
  32.           dispmode    : word;           { display option (reg,XOR,etc.) }
  33.           vgapalette  : SurfPalette;    { pallette, if grsys = VGA256 }
  34.         end;
  35.  
  36. CONST
  37.   VERSNUM = '2.00c';
  38.   VERSDATE = '29 November, 1991';
  39.  
  40. var
  41.   header,position,lastpos : picptr;
  42.   filename : string;
  43.   infile : text;
  44.   oldgrsys, oldgrmode : integer;
  45.   done : boolean;
  46.   advance_pos : boolean;
  47.   goforward : boolean;
  48.   buf : integer;
  49.   y1 : integer;
  50.   membuffer : pointer;      { buffer for copying to/from XMS }
  51.   buf_avail : boolean;      { is membuffer available? }
  52.   pbuf : pointer;
  53.   ch : char;
  54.   cnv_memused : longint;    { kbytes of conventional memory used in run }
  55.   xms_memused : longint;    { kbytes of xms memory used in run }
  56.   xms_hdlused : integer;    { # xms handles used in run }
  57.  
  58. label ABORTGRPH;
  59.  
  60.  
  61. procedure waitforkey;
  62. {beeps, then waits for a key to be pressed}
  63. var ch: char;
  64.  
  65. begin {waitforkey}
  66.   write (chr(7));
  67.   repeat until keypressed;
  68.   while keypressed do
  69.     ch := readkey;
  70.  
  71. end; {waitforkey}
  72.  
  73. { KVC Moved readscrn into PLAYBACK.PAS (from SURFGRAF.PAS) so SURFMODL
  74.   doesn't have to have all the extra baggage associated with XMS support.
  75. }
  76. function readscrn (filename : string; var grsys,grmode : integer;
  77.     var image : picbuf; var xms_image: xmsbuf; var buftype: buffertype;
  78.     var xms_bufsize: xmsbuf; var nbuf : integer; var nlines_buf : nlpic;
  79.     var vgapalette : SurfPalette; oldgrsys, oldgrmode : integer) : boolean;
  80. var
  81.   imagefile   : file;
  82.   success     : boolean;
  83.   nbytes      : longint;
  84.   tmp         : real;
  85.   xmax        : integer;
  86.   ymax        : integer;
  87.   nbytes_line : longint;
  88.   y1, y2      : integer;
  89.   grtmp       : integer;
  90.   grmtmp      : integer;
  91.  
  92. begin
  93.   success := true;
  94.   {$I-}
  95.   assign (imagefile,filename);
  96.  
  97.   if ioresult <> 0 then begin
  98.     success := false;
  99.     restorecrtmode;
  100.     writeln ('File "',filename,'" not found');
  101.   end;
  102.  
  103.   reset (imagefile,1);
  104.   if ioresult <> 0 then begin
  105.     success := false;
  106.     restorecrtmode;
  107.     writeln ('File "',filename,'" not found');
  108.   end;
  109.  
  110.   blockread (imagefile,grsys,sizeof(grsys));
  111.   if ioresult <> 0 then begin
  112.     success := false;
  113.     restorecrtmode;
  114.     writeln ('Could not read grsys');
  115.   end;
  116.  
  117.   blockread (imagefile,grmode,sizeof(grmode));
  118.   if ioresult <> 0 then begin
  119.     success := false;
  120.     restorecrtmode;
  121.     writeln ('Could not read grmode');
  122.   end;
  123.  
  124.   if (grsys = VGA256) then begin
  125.     { Have to restore the VGA palette too }
  126.     blockread (imagefile, vgapalette, sizeof(vgapalette));
  127.     if ioresult <> 0 then begin
  128.       success := false;
  129.       restorecrtmode;
  130.       writeln ('Could not read VGA palette');
  131.     end;
  132.   end;
  133.  
  134.   {$I+}
  135.  
  136.  
  137.   if success then begin
  138.     { Have to go into graphics mode to read line size }
  139.     if (grsys <> oldgrsys) then begin
  140.       if (oldgrsys <> -1) then
  141.         { Not the first time, exit graphics mode first }
  142.         closegraph;
  143. {$IFNDEF EXTERNAL}
  144.       { KVC 04/20/91 Make Turbo recognize the SVGA256.BGI file }
  145.       grtmp := InstallUserDriver('SVGA256', @DetectVGA256);
  146. {$ENDIF}
  147.       { KVC 09/11/91 This call to detect shouldn't be necessary, but otherwise
  148.           Turbo does not seem to be using the SVGA256.BGI file.
  149.       }
  150.       grtmp := detect;
  151.       grmtmp := 0;
  152.       if (grsys <> VGA256) then
  153.           grtmp := grsys;
  154.       initgraph (grtmp,grmtmp,BGIDIR);
  155.       if (graphresult < 0) then
  156.         success := false
  157.       else begin
  158.         setgraphmode(grmode);
  159.         if (graphresult < 0) then
  160.           success := false
  161.         else begin
  162.           if (grsys = VGA256) then
  163.             { Set the palette }
  164.             VGASetAllPalette (vgapalette);
  165.         end;
  166.       end;
  167.     end else if (grmode <> oldgrmode) then
  168.       setgraphmode (grmode);
  169.  
  170.     if success then begin
  171.       xmax := GetMaxX;
  172.       ymax := GetMaxY;
  173.       if (Grsys = VGA256) then
  174.         { Bug in SVGA256 doesn't set imagesize correctly }
  175.         nbytes_line := xmax + 5
  176.       else
  177.         nbytes_line := imagesize (0, 0, xmax, 0);
  178.  
  179.       { Find out how many lines we can fit in a 64K buffer }
  180.       if (nbytes_line * (ymax+1) > MAXALLOC) then
  181.         nlines_buf[1] := MAXALLOC div nbytes_line
  182.       else
  183.         nlines_buf[1] := ymax + 1;
  184.     end;
  185.  
  186.     y1 := 0;
  187.     y2 := nlines_buf[1] - 1;
  188.     nbuf := 0;
  189.  
  190.     { The following loop is done once per buffer }
  191.     while (success) and (y1 <= y2) do begin
  192.  
  193.       { Make sure we don't allocate more than we need }
  194.       nbuf := nbuf + 1;
  195.       if (nbuf > MAXPICBUF) then begin
  196.         restorecrtmode;
  197.         writeln ('ERROR: More than ', MAXPICBUF,
  198.             ' buffers required for bitmap!');
  199.         writeln ('  (Grsys=', grsys, ' Grmode=', grmode, ')');
  200.         writeln ('Please report this problem to Ken Van Camp.');
  201.         halt;
  202.       end;
  203.       nlines_buf[nbuf] := y2 - y1 + 1;
  204.       buftype[nbuf] := 1;
  205.       if (Grsys = VGA256) then
  206.         { Bug in SVGA256 doesn't set imagesize correctly }
  207.         { KVC added longint() per suggestion from Gisbert Selke 11/19/91 }
  208.         nbytes := longint (xmax+1) * (y2-y1+1) + 4
  209.       else
  210.         nbytes := imagesize (0, y1, xmax, y2);
  211.  
  212.       { KVC 11/09/91 No longer need to check for available memory before
  213.         the getmem() call, since HeapErrorTrap now stops the Error 203's.
  214.       }
  215.       getmem (image[nbuf], nbytes);
  216.  
  217.       if (image[nbuf] = nil) then begin
  218.         { Not enough conventional memory available, try XMS }
  219.         if (buf_avail) then begin
  220.           xms_bufsize[nbuf] := nbytes;
  221.           xms_image[nbuf] := EMBGetMem (nbytes div 1024 + 1);
  222.           if (XMSError <> 0) then begin
  223.             restorecrtmode;
  224.             writeln ('XMS Error getting mem: ', XMSErrorString (XMSError));
  225.             success := false;
  226.           end else begin
  227.             xms_memused := xms_memused + nbytes div 1024 + 1;
  228.             xms_hdlused := xms_hdlused + 1;
  229.             buftype[nbuf] := 2;
  230.           end;
  231.           pbuf := membuffer;
  232.         end else
  233.           { XMS not available }
  234.           success := false;
  235.         if (not success) then begin
  236.           restorecrtmode;
  237.           writeln ('Could not allocate memory for bitmap');
  238.         end;
  239.       end else begin
  240.         pbuf := image[nbuf];
  241.         cnv_memused := cnv_memused + nbytes div 1024 + 1;
  242.       end; { if image[nbuf] }
  243.  
  244.       if (success) then begin
  245.         {memory successfully allocated}
  246.         {$I-}
  247.         blockread (imagefile, pbuf^, nbytes);
  248.         if ioresult <> 0 then begin
  249.           success := false;
  250.           restorecrtmode;
  251.           writeln ('Could not read image');
  252.         end;
  253.         {$I+}
  254.         { Move to XMS, if used }
  255.         if (buftype[nbuf] = 2) then begin
  256.           MoveToEMB (pbuf^, xms_image[nbuf], nbytes);
  257.           if (XMSError <> 0) then begin
  258.             restorecrtmode;
  259.             writeln ('XMS Error moving to EMB: ', XMSErrorString (XMSError));
  260.             success := false;
  261.           end;
  262.         end;
  263.       end; {Memory allocated}
  264.  
  265.       y1 := y1 + nlines_buf[nbuf];
  266.       y2 := y2 + nlines_buf[nbuf];
  267.       if (y2 > ymax) then
  268.         y2 := ymax;
  269.  
  270.     end; { while }
  271.  
  272.   end; { Image successfully read }
  273.  
  274.   {$I-}
  275.   close (imagefile);
  276.   {$I+}
  277.   if ioresult <> 0 then
  278.     success := false;
  279.  
  280.   readscrn := success;
  281. end; {readscrn}
  282.  
  283.  
  284. procedure xms_shutdown;
  285. { Release all allocated extended memory }
  286. begin
  287.   position := header;
  288.   while (position <> nil) do begin
  289.     for buf := 1 to position^.nbuf do begin
  290.       if (position^.buftype[buf] = 2) then begin
  291.         EMBFreeMem (position^.xms_image[buf]);
  292.         if (XMSError <> 0) then begin
  293.           restorecrtmode;
  294.           writeln ('XMS Error releasing handle: ', XMSErrorString (XMSError));
  295.         end;
  296.       end;
  297.     end;
  298.     position := position^.next;
  299.   end;
  300. end; { xms_shutdown }
  301.  
  302.  
  303. begin { main }
  304.   if paramcount <> 1 then begin {usage}
  305.     writeln ('Program PLAYBACK, Version',VERSNUM,', ',VERSDATE);
  306.     writeln ('Written by Kevin Lowey (LOWEY@SASK.BITNET)');
  307.     writeln ('Version 2.0 by Ken Van Camp');
  308.     writeln ('USAGE: PLAYBACK playfile');
  309.     writeln;
  310.     writeln ('Description:');
  311.     writeln ('This program replays files saved by SURFMODL using the');
  312.     writeln ('"F" option while the picture is being displayed.');
  313.     writeln ('Files created on one graphics device CANNOT be played back');
  314.     writeln ('on another, for example files in the AT&T hires mode cannot');
  315.     writeln ('be played back on a hercules system.');
  316.     writeln;
  317.     writeln ('Press a key to continue');
  318.     repeat until keypressed;
  319.     while keypressed do
  320.       ch := readkey;
  321.     writeln;
  322.     writeln ('The data file parameter contains a file consisting of lines');
  323.     writeln ('of the following format:');
  324.     writeln;
  325.     writeln ('  DELAY  DISPLAYMODE  FILENAME');
  326.     writeln;
  327.     writeln ('DELAY is the number of milliseconds (1/1000 sec) to');
  328.     writeln ('show the file.  Special values are:');
  329.     writeln ('  0 : No delay');
  330.     writeln (' -1 : Wait until a key is pressed');
  331.     writeln (' -2 : Rewind to first image and start again');
  332.     writeln (' -3 : Start playing backwards, until first image is reached.');
  333.     writeln ('(Both modes -2 and -3 will start an infinite loop, which is');
  334.     writeln ('terminated when the first key is pressed.');
  335.     writeln;
  336.     writeln ('DISPLAYMODE is the mode the image should be displayed in.');
  337.     writeln ('  0 : Normal mode, image replaces image on screen.');
  338.     writeln ('  1 : XOR mode, Shows image EXCEPT where it matches screen.');
  339.     writeln ('  2 : OR mode,  Shows both image and screen.');
  340.     writeln ('  3 : AND mode, Shows only where image and screen intersect.');
  341.     writeln ('  4 : NOT mode, Shows the inverse of the image.');
  342.     writeln;
  343.     writeln ('The filename is the file containing the image to display.');
  344.   end
  345.   else begin
  346.     {$I-}
  347.     assign (infile,paramstr(1));
  348.     {$I+}
  349.     if ioresult <> 0 then begin
  350.       writeln ('The file "',paramstr(1),'" does not exist.');
  351.       halt(1);
  352.     end;
  353.     {$I-}
  354.     reset (infile);
  355.     {$I+}
  356.     if ioresult <> 0 then begin
  357.       writeln ('The file "',paramstr(1),'" does not exist.');
  358.       halt(1);
  359.     end;
  360.  
  361.     writeln ('Reading data files . . .');
  362.  
  363.     { Check for XMS memory manager.  If installed, allocate one 64K
  364.       buffer to use in case we need it.  Have to allocate it here,
  365.       because if we wait till we need it then it's too late.
  366.     }
  367.     cnv_memused := 0;
  368.     xms_memused := 0;
  369.     xms_hdlused := 0;
  370.     if (XMMPresent) then begin
  371.       getmem (membuffer, MAXALLOC);
  372.       if (membuffer = nil) then begin
  373.         writeln ('Out of memory getting a buffer.');
  374.         halt;
  375.       end;
  376.       cnv_memused := cnv_memused + MAXALLOC div 1024 + 1;
  377.       buf_avail := TRUE;
  378.     end else
  379.       buf_avail := FALSE;
  380.  
  381.     header := nil;
  382.     lastpos := nil;
  383.  
  384.     done := false;
  385.     oldgrsys := -1;
  386.     oldgrmode := -1;
  387.  
  388.     while ((not eof(infile)) and (not done)) do begin
  389.       new (position);
  390.       if (position = nil) then
  391.         done := true
  392.       else begin
  393.         position^.next := nil;
  394.         position^.prev := lastpos;
  395.         position^.speed := 0;
  396.         position^.grsys := 0;
  397.         position^.grmode := 0;
  398.         position^.dispmode := 0;
  399.         position^.image[1] := nil;
  400.         position^.xms_image[1] := 0;
  401.         position^.nlines_buf[1] := 0;
  402.         position^.buftype[1] := 0;
  403.         position^.nbuf := 0;
  404.         if (lastpos <> nil) then
  405.           lastpos^.next := position;
  406.         if (header = nil) then
  407.           { head of list }
  408.           header := position;
  409.         lastpos := position;
  410.  
  411.         read (infile,position^.speed);
  412.         read (infile, position^.dispmode);
  413.         readln (infile, filename);
  414.  
  415.         { Remove leading blanks and tabs from file name }
  416.         while filename[1] in [' ',^I] do
  417.           delete(filename,1,1);
  418.  
  419.         if readscrn(filename,position^.grsys, position^.grmode,
  420.             position^.image, position^.xms_image, position^.buftype,
  421.             position^.xms_bufsize, position^.nbuf, position^.nlines_buf,
  422.             position^.vgapalette, oldgrsys, oldgrmode) then begin
  423.  
  424.           oldgrsys := position^.grsys;
  425.           oldgrmode := position^.grmode;
  426.         end else
  427.           done := true;
  428.       end; { if position = nil }
  429.     end; {while}
  430.  
  431.     close (infile);
  432.  
  433.     if ((oldgrsys <> header^.grsys) or (oldgrmode <> header^.grmode))
  434.         and (not done) then begin
  435.       { readscrn left us in graphics mode, but not the right one }
  436.       oldgrsys := header^.grsys;
  437.       oldgrmode := header^.grmode;
  438.  
  439.       closegraph;
  440.       initgraph (header^.grsys,header^.grmode,BGIDIR);
  441.       if (grsys = VGA256) then
  442.         { Set the palette }
  443.         VGASetAllPalette (header^.vgapalette);
  444.     end;
  445.  
  446.     position := header;
  447.     goforward := true;
  448.  
  449.     while (not done) and (position <> nil) do begin
  450.       if oldgrsys <> position^.grsys then begin
  451.         closegraph;
  452.         oldgrsys := position^.grsys;
  453.         oldgrmode := position^.grmode;
  454.         initgraph (position^.grsys,position^.grmode,BGIDIR);;
  455.         if (grsys = VGA256) then
  456.           { Set the palette }
  457.           VGASetAllPalette (position^.vgapalette);
  458.       end
  459.       else if position^.grmode <> oldgrmode then begin
  460.         setgraphmode(position^.grmode);
  461.         oldgrmode := position^.grmode;
  462.       end;
  463.  
  464.       { graph.putimage (0,0,position^.image^,position^.dispmode); }
  465.       y1 := 0;
  466.       for buf := 1 to position^.nbuf do begin
  467.         { Read from XMS memory, if it's there }
  468.         if (position^.buftype[buf] = 2) then begin
  469.           pbuf := membuffer;
  470.           MoveFromEMB (position^.xms_image[buf], pbuf^,
  471.               position^.xms_bufsize[buf]);
  472.           if (XMSError <> 0) then begin
  473.             restorecrtmode;
  474.             writeln ('XMS Error moving from EMB: ', XMSErrorString (XMSError));
  475.             xms_shutdown;
  476.             halt;
  477.           end;
  478.         end else
  479.           pbuf := position^.image[buf];
  480.  
  481.         graph.putimage (0,y1,pbuf^,position^.dispmode);
  482.         y1 := y1 + position^.nlines_buf[buf];
  483.       end;
  484.  
  485.       advance_pos := true;
  486.       if position^.speed = -1 then
  487.         waitforkey
  488.       else if position^.speed = -2 then begin
  489.         { rewind to first picture }
  490.         position := header;
  491.         advance_pos := false;
  492.         { first keypress aborts }
  493.         if keypressed then
  494.           goto ABORTGRPH;
  495.       end else if position^.speed = -3 then begin
  496.         { start playing in reverse }
  497.         goforward := false;
  498.         { first keypress aborts }
  499.         if keypressed then
  500.           goto ABORTGRPH;
  501.       end else
  502.         delay (position^.speed);
  503.  
  504.       if advance_pos then begin
  505.         if goforward then
  506.           position := position^.next
  507.         else begin
  508.           position := position^.prev;
  509.           if position = nil then begin
  510.             position := header;
  511.             goforward := true;
  512.           end;
  513.         end;
  514.       end; { if advance_pos }
  515.     end; { while position }
  516.  
  517. ABORTGRPH:
  518.     if (not done) then
  519.       exgraphic;
  520.     { Empty the keyboard buffer }
  521.     while keypressed do
  522.       ch := readkey;
  523.     xms_shutdown;
  524.     writeln ('Playback complete: ', MemAvail div 1024,
  525.         ' KBytes of conventional memory still available.');
  526.     writeln ('  ', cnv_memused,
  527.         ' KBytes of dynamically-allocated conventional memory were used.');
  528.     if (xms_memused > 0) or (xms_hdlused > 0) then begin
  529.       writeln ('  XMS Memory Manager v.', GetXMSVersion, ' was used.');
  530.       writeln ('  ', xms_memused,
  531.           ' KBytes of dynamically-allocated XMS memory were used out of');
  532.       writeln ('      ', XMSMemAvail, ' KBytes available and ', XMSMaxAvail,
  533.           ' KBytes max available.');
  534.       writeln ('  ', xms_hdlused, ' XMS handles used out of ',
  535.           GetAvailEMBHandles, ' available.');
  536.     end else
  537.       writeln ('NO XMS memory was used.');
  538.   end; {not usage}
  539. end.
  540.