home *** CD-ROM | disk | FTP | other *** search
/ World of Graphics / WOGRAPH.BIN / 569.UNCRUNCH.PAS < prev    next >
Pascal/Delphi Source File  |  1993-03-21  |  8KB  |  161 lines

  1. procedure UNCRUNCH (var Addr1,Addr2; BlkLen:Integer);
  2.  
  3. (*
  4.  This is the routine for displaying crunched TheDraw image files.  The
  5.  crunched data format is a simple custom protocol for reproducing any image.
  6.  The control codes below decimal 32 are reserved for this function.
  7.  Characters 32 and above are written directly to the destination address.
  8.  
  9.  The following shows the format of a control code sequence.  Please note that
  10.  not all functions use the optional bytes <x> or <y>.
  11.  
  12.  Data Structure:  <current byte>[<x>[<y>]]
  13.  
  14.     0..15 = New Foreground Color
  15.    16..23 = New Background Color
  16.        24 = Go down to next line, return to same horizontal position as when
  17.             routine was started (akin to a c/r).
  18.        25 = Displays <x> number of spaces.
  19.        26 = Displays <x> number of <y>.  Also used to display ANY characters
  20.             below #32.  This function is the only way to do this although it
  21.             uses three bytes.  Otherwise the code would be interpreted as
  22.             another command.
  23.        27 = Toggles on/off the foreground attribute blink flag.
  24.    28..31 = reserved
  25.  
  26.  ----------------------------------------------------------------------------
  27.  
  28.  To use this routine, call the procedure with the crunched image data as the
  29.  first parameter, the display address as the second parameter, and the length
  30.  of the crunched image data as the third parameter.
  31.  
  32.  Assume we have an ImageData file of a 40 character by 10 line block.  Also
  33.  the following defintions.  ie:
  34.  
  35.    { TheDraw Pascal Crunched Screen Image }
  36.    const                                           <- This CONST area is
  37.      IMAGEDATA_WIDTH = 40;                            generated by TheDraw
  38.      IMAGEDATA_DEPTH = 10;
  39.      IMAGEDATA_LENGTH = 467;
  40.      IMAGEDATA : array [1..467] of Char =
  41.        (...list of image bytes here...);
  42.  
  43.    type ScreenType = array [0..3999] of Byte;
  44.    var ScreenAddr : ScreenType absolute $B800:$0000;
  45.  
  46.    begin
  47.      UnCrunch (IMAGEDATA,ScreenAddr[ (34*2) + (5*160) -162],IMAGEDATA_LENGTH);
  48.    end;
  49.  
  50.  
  51.  SCREENADDR is a variable mapped to the same location as the physical video
  52.  addresses (via Turbo's absolute addressing).   The rather messy array offset
  53.  tells UnCrunch where to start displaying the ImageData block.  The 34*2
  54.  indicates the horizontal position number 34 with the 5*160 indicating line
  55.  number 5.  This is similar to a Turbo GOTOXY (34,5) statement.
  56.  
  57.  The original horizontal starting offset is remembered by the uncrunch routine.
  58.  The offset is restored upon moving down to the next line.  This permits a
  59.  block to be displayed correctly anywhere on the screen.  ie:
  60.  
  61.                ┌─ horizontal starting offset
  62.                V
  63.    +-------------------------------------------------+
  64.    |                                                 |
  65.    |                                                 | <- Assume this
  66.    |                                                 |    is the video
  67.    |           ┌─────────────────────┐               |    display.
  68.    |           │█████████████████████│               |
  69.    |           │█████████████████████│               |
  70.    |           │██ ImageData block ██│               |
  71.    |           │█████████████████████│               |
  72.    |           │█████████████████████│               |
  73.    |           │█████████████████████│               |
  74.    |           └─────────────────────┘               |
  75.    |                                                 |
  76.    |                                                 |
  77.    |                                                 |
  78.    +-------------------------------------------------+
  79.  
  80.  
  81.  The ImageData block could just as well have been display in the upper-left
  82.  corner of the screen with:
  83.     UNCRUNCH (IMAGEDATA,ScreenAddr[ (1*2) + (1*160) -162],IMAGEDATA_LENGTH);
  84.  
  85.  Notice the array address changed to the equivilant of GOTOXY (1,1);
  86.  
  87.  To display the block in the lower-right corner you would use:
  88.     UNCRUNCH (IMAGEDATA,ScreenAddr[ (40*2) + (15*160) -162],IMAGEDATA_LENGTH);
  89.  
  90.  In this example, the block is 40 characters wide by 10 lines deep.  Thus,
  91.  to display such a large block, we must display the block at GOTOXY (40,15);
  92.  
  93.  That's it!  The routine was designed for easy use and understanding; however,
  94.  for some people the best way is to experiment.  Create a program using the
  95.  above examples, perhaps with a 40x10 block (or any size).  Good luck!
  96. *)
  97.  
  98. begin
  99.   inline (
  100.     $1E/               {       PUSH    DS             ;Save data segment.}
  101.     $C5/$B6/ADDR1/     {       LDS     SI,[BP+Addr1]  ;Source Address}
  102.     $C4/$BE/ADDR2/     {       LES     DI,[BP+Addr2]  ;Destination Addr}
  103.     $8B/$8E/BLKLEN/    {       MOV     CX,[BP+BlkLen] ;Length of block}
  104.     $E3/$5B/           {       JCXZ    Done}
  105.     $8B/$D7/           {       MOV     DX,DI          ;Save X coordinate for later.}
  106.     $33/$C0/           {       XOR     AX,AX          ;Set Current attributes.}
  107.     $FC/               {       CLD}
  108.     $AC/               {LOOPA: LODSB                  ;Get next character.}
  109.     $3C/$20/           {       CMP     AL,32          ;If a control character, jump.}
  110.     $72/$05/           {       JC      ForeGround}
  111.     $AB/               {       STOSW                  ;Save letter on screen.}
  112.     $E2/$F8/           {Next:  LOOP    LOOPA}
  113.     $EB/$4C/           {       JMP     Short Done}
  114.                        {ForeGround:}
  115.     $3C/$10/           {       CMP     AL,16          ;If less than 16, then change the}
  116.     $73/$07/           {       JNC     BackGround     ;foreground color.  Otherwise jump.}
  117.     $80/$E4/$F0/       {       AND     AH,0F0H        ;Strip off old foreground.}
  118.     $0A/$E0/           {       OR      AH,AL}
  119.     $EB/$F1/           {       JMP     Next}
  120.                        {BackGround:}
  121.     $3C/$18/           {       CMP     AL,24          ;If less than 24, then change the}
  122.     $74/$13/           {       JZ      NextLine       ;background color.  If exactly 24,}
  123.     $73/$19/           {       JNC     FlashBitToggle ;then jump down to next line.}
  124.     $2C/$10/           {       SUB     AL,16          ;Otherwise jump to multiple output}
  125.     $02/$C0/           {       ADD     AL,AL          ;routines.}
  126.     $02/$C0/           {       ADD     AL,AL}
  127.     $02/$C0/           {       ADD     AL,AL}
  128.     $02/$C0/           {       ADD     AL,AL}
  129.     $80/$E4/$8F/       {       AND     AH,8FH         ;Strip off old background.}
  130.     $0A/$E0/           {       OR      AH,AL}
  131.     $EB/$DA/           {       JMP     Next}
  132.                        {NextLine:}
  133.     $81/$C2/$A0/$00/   {       ADD     DX,160         ;If equal to 24,}
  134.     $8B/$FA/           {       MOV     DI,DX          ;then jump down to}
  135.     $EB/$D2/           {       JMP     Next           ;the next line.}
  136.                        {FlashBitToggle:}
  137.     $3C/$1B/           {       CMP     AL,27          ;Does user want to toggle the blink}
  138.     $72/$07/           {       JC      MultiOutput    ;attribute?}
  139.     $75/$CC/           {       JNZ     Next}
  140.     $80/$F4/$80/       {       XOR     AH,128         ;Done.}
  141.     $EB/$C7/           {       JMP     Next}
  142.                        {MultiOutput:}
  143.     $3C/$19/           {       CMP     AL,25          ;Set Z flag if multi-space output.}
  144.     $8B/$D9/           {       MOV     BX,CX          ;Save main counter.}
  145.     $AC/               {       LODSB                  ;Get count of number of times}
  146.     $8A/$C8/           {       MOV     CL,AL          ;to display character.}
  147.     $B0/$20/           {       MOV     AL,32}
  148.     $74/$02/           {       JZ      StartOutput    ;Jump here if displaying spaces.}
  149.     $AC/               {       LODSB                  ;Otherwise get character to use.}
  150.     $4B/               {       DEC     BX             ;Adjust main counter.}
  151.                        {StartOutput:}
  152.     $32/$ED/           {       XOR     CH,CH}
  153.     $41/               {       INC     CX}
  154.     $F3/$AB/           {       REP STOSW}
  155.     $8B/$CB/           {       MOV     CX,BX}
  156.     $49/               {       DEC     CX             ;Adjust main counter.}
  157.     $E0/$AA/           {       LOOPNZ  LOOPA          ;Loop if anything else to do...}
  158.     $1F);              {Done:  POP     DS             ;Restore data segment.}
  159. end; {UNCRUNCH}
  160.  
  161.