home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 10: Diskmags / nf_archive_10.iso / MAGS / ST_USER / 1990 / USERAU90.MSA / TEXT_DEGAS.DOC < prev    next >
Text File  |  1990-06-24  |  10KB  |  227 lines

  1.                          Degas decompression
  2.  
  3.  
  4.                   Save valuable disk space by storing
  5.                 screens in compressed Degas Elite format
  6.  
  7.  
  8. Each month cover disk submissions arrive by the sackload and poor old postman
  9. Pat's back is under a tremendous strain. The overwhelming majority of submitted
  10. programs are superb and if it were possible we would love to use them all.
  11.  
  12.     However, the storage capacity of ST disks is limited to around 800k which
  13. means that only quite small programs can be squeezed into the limited space
  14. available. Unfortunately, the remaining submissions, excellent though they
  15. often are, must be rejected simply because we haven't enough space for them. We
  16. wish we had more, but we're stuck with the ST's 800k disks.
  17.  
  18.     (It's interesting to note that a few years ago 800k disks would have seemed
  19. increadably large, but over the years programs have steadily grown in size and
  20. complexity and a 16k word processor or spreadsheet - such as View and Viewsheet
  21. on the BBC Micro - seems unthinkable now!)
  22.  
  23.     One of the reasons why programs take up such a lot of disk space is that
  24. they require one or more graphic screens. These are most commonly stored as
  25. either Neochrome or Degas screens which occupy over 32k of disk space. A
  26. typical game may require a loading screen which is displayed while the program
  27. is booting up and a title/menu/main screen which shows the credits, options and
  28. prompts you to press fire to start.
  29.  
  30.     Since each screen is 32k long, requiring just two of these means that 64k
  31. of disk space is consumed, even before you start writing a line of program
  32. code! What is needed is a way of reducing the amount of space the graphics
  33. occupy.
  34.  
  35.     We can't easily do anything about Neochrome pictures, but every Degas Elite
  36. owner will know that their art package can save screens in a highly compressed
  37. form. In fact, this is the default Save mode.
  38.  
  39.     You can tell a compressed Degas picture from its name, to be more specific,
  40. its file extension - the name ends in PC1, PC2 or PC3. (P for picture, C for
  41. compressed and the three numbers indicate the screen resolution: 1 is low res
  42. colour, 2 is medium res colour and 3 is high res monochrome.)
  43.  
  44.     A degas compressed screen is typically around 12k to 16k long and that is
  45. less than half the space required for a standard screen. So if compressed
  46. screens could be substituted for standard ones in our programs then we would
  47. half the disk space required by the graphics.
  48.  
  49.     How are Degas compressed screens stored and how can we load and decompress
  50. them so that they can be used in our own programs? The first 34 bytes of the
  51. picture file makes up a header that contains two flags in the first word and
  52. the colour palette in the next 16 words.
  53.  
  54.     The first byte holds the compression flag in bit seven and the second byte
  55. holds the screen mode (zero, one or two). The result of this is that the first
  56. word of a compressed low res picture is $8000, medium res is $8001 and
  57. monochrome is $8002.
  58.  
  59.     From byte 34 onwards is the compressed data that we'll have to decompress
  60. before the picture can be displayed on the screen. A fairly simple, but
  61. effective, variation on run length encoding is used, so decoding is just as
  62. straightforward.
  63.  
  64.     Read the first byte of data and if it is 128 then ignore it and go on to
  65. the next byte. (I'm not sure why this value is required, maybe it's for padding
  66. out an odd length file to make it even.)
  67.  
  68.     If the byte - call it N - is less than 128 then copy the next N+1 bytes
  69. straight into the screen memory as it is raw picture data. If the byte is
  70. greater than 128 then it is a signed single byte number and the following byte
  71. must be copied -N+1 times (subtract the byte from 256 to get the signed
  72. number).
  73.  
  74.     Here is a quick summary of the values to expect:
  75.  
  76. Byte  0... 127 = copy next n+1 bytes
  77. Byte -1...-127 = copy next byte -n+1 times
  78. Byte      -128 = ignore
  79.  
  80.     Two complications muck up a very simple system, but they aren't too
  81. difficult to program around. The picture data is compressed one scan line
  82. (horizontal row of pixels) at a time and also one bit plane at a time. Let's
  83. see what this means.
  84.  
  85.     Dividing the screen into scan lines isn't a problem as we can decompress
  86. one line at a time and copy it to the screen. Since monochrome screens only
  87. have one bit plane we can ignore this further complication if we limit
  88. ourselves to decompressing mono only Degas pictures.
  89.  
  90.     It's time now to look at some program code and to keep the programming
  91. simple I'll use HiSoft BASIC. Here is the main part of the code used in
  92. SHOW_PC3.BAS in the LISTINGS folder on this month's cover disk:
  93.  
  94. OPEN "I",#1,file$                      :' open the file for input
  95. colour$ = INPUT$(34,#1)                :' get colour palette - ignore it!
  96. scrstart& = FNphysbase&                :' get screen start address
  97. FOR scan% = 0 TO 399                   :' 400 scan lines (rows of pixels)
  98.   addr& = scrstart& + 80*scan%         :' get address of current scan line
  99.   nextline& = addr& + 80               :' get address of next scan line
  100.   DO
  101.     b% = ASC(INPUT$(1,#1))             :' read a byte from picture file
  102.     IF b%<128 THEN
  103.       FOR i% = 0 TO b%                 :' copy next n+1 bytes literally
  104.         POKEB addr&,ASC(INPUT$(1,#1))
  105.         addr& = addr& + 1
  106.       NEXT
  107.     END IF
  108.     IF b%>128 THEN
  109.       byte% = ASC(INPUT$(1,#1))
  110.       FOR i% = 1 TO 256-b%+1           :' copy byte% -b%+1 times
  111.         POKEB addr&,byte%
  112.         addr& = addr& + 1
  113.       NEXT
  114.     END IF
  115.   LOOP UNTIL addr&>=nextline&          :' finished scan line?
  116. NEXT                                   :' next scan line
  117. CLOSE #1                               :' close the file
  118.  
  119.     A FOR...NEXT loop sorts out the scan line problem and the DO...LOOP
  120. decompresses each line. The scan line start address is calculated by
  121. multiplying the number of scan lines by 80 (because there are 80 bytes per
  122. line) and adding on the screen start address.
  123.  
  124.     Two short FOR...NEXT loops poke the decompressed data into the screen
  125. memory. Which one is chosen depends on whether the flag byte is greater or less
  126. than 128.
  127.  
  128.     This BASIC program quite easily translates into 68000 machine code (it's
  129. called SHOW_PC3.S in the listings folder). Here is the main loop which decodes
  130. the 400 scan lines:
  131.  
  132.         MOVE #399,D7            400 scan lines
  133.         MOVEA.L A5,A4           A5 = current scan line address
  134. loop1   ADDA.L #80,A4           A4 = next scan line address
  135. loop2   f_read buffer,1,in      read 1 byte
  136.         MOVE.B buffer(A6),D0    D0 = byte
  137.         CMP.B #128,D0           < 128 ?
  138.         BPL skip1
  139.         MOVE D0,D6              loop counter
  140.         ANDI #$FF,D6
  141. loop3   f_read buffer,1,in      read one byte into buffer
  142.         MOVE.B buffer(A6),(A5)+ store byte in screen
  143.         DBRA D6,loop3
  144.         BRA next
  145. skip1   CMP.B #129,D0           > 128 ?
  146.         BMI next
  147.         MOVE D0,D6              loop counter
  148.         NOT D6
  149.         ANDI #$FF,D6
  150.         ADDQ.L #1,D6
  151.         f_read buffer,1,in      read one byte into buffer
  152. loop4   MOVE.B buffer(A6),(A5)+ store byte in screen
  153.         DBRA D6,loop4
  154. next    MOVE.L A5,D0            done whole scan line?
  155.         CMP.L A4,D0
  156.         BMI loop2               back to loop2 if not done
  157.         MOVEA.L A4,A5           next scan line address
  158.         DBRA D7,loop1           done all scan lines?
  159.  
  160.     Now let's take a look at how low res colour pictures can be decompressed.
  161. There are four bit planes and each plane is compressed separately. Think of the
  162. screen as being made up of (8,000) groups of four words. The first word in each
  163. group belongs to the first bit plane, the second word is the second bit plane,
  164. the third word is the third and the fourth is the fourth.
  165.  
  166.     What you must do is decompress each scan line as before, but do it four
  167. times - the first time decompressing the first word in each group, then the
  168. second time decompressing the second word, the third time its the turn of the
  169. third word and finally comes the fourth word.
  170.  
  171.     The addition of a simple FOR...NEXT loop to our mono decompressor copes
  172. with the extra bit planes. Each word (two bytes) is poked into the screen
  173. memory then we skip forward over the other bit plane words in the group:
  174.  
  175. scrstart& = FNphysbase&
  176. FOR scan%=0 TO 199
  177.   FOR plane%=0 TO 6 STEP 2
  178.     addr&=scrstart& + 160*scan% + plane%
  179.     nextline&=addr& + 160
  180.     DO
  181.       b% = ASC(INPUT$(1,#1))
  182.       IF b%<128 THEN
  183.         FOR i% = 0 TO b%
  184.           POKEB addr&,ASC(INPUT$(1,#1))
  185.           IF addr& AND 1 THEN addr&=addr&+7 ELSE addr&=addr&+1
  186.         NEXT
  187.       END IF
  188.       IF b%>128 THEN
  189.         byte% = ASC(INPUT$(1,#1))
  190.         FOR i% = 1 TO 256-b%+1
  191.           POKEB addr&,byte%
  192.           IF addr& AND 1 THEN addr&=addr&+7 ELSE addr&=addr&+1
  193.         NEXT
  194.       END IF
  195.     LOOP UNTIL addr&>=nextline&
  196.   NEXT
  197. NEXT
  198. CLOSE #1
  199.  
  200.     Note that in low res colour each scan line occupies 160 bytes of memory and
  201. that there are 200 lines (horizontal rows of pixels) on the screen.
  202.  
  203.     What I haven't yet mentioned, is the colour palette. As this is quite
  204. simple I have left it until last. All you need to do is read in words 1 to 16
  205. of the header and set the 16 colours of palette according to the contents of
  206. these words. Here's a HiSoft BASIC routine to set the palette:
  207.  
  208. OPEN "I",#1,file$
  209. dummy$ = INPUT$(2,#1)
  210. FOR i% = 0 TO 15
  211.   a% = 256*ASC(INPUT$(1,#1)) + ASC(INPUT$(1,#1))
  212.   dummy% = FNsetcolor%(i%,a%)
  213. NEXT
  214.  
  215.     All the programming examples are in fairly straightforward BASIC code
  216. (apart from a little 68000) and you should be able to convert them into GFA or
  217. Fast BASIC, or STOS.
  218.  
  219.     If the decompression routine seems slow it is because of the slow ST disk
  220. drives and it's not a result of inefficient code. To speed up the program load
  221. the compressed picture into a buffer and decompress the data in memory.
  222.  
  223.  
  224. HARDWARE: ALL STs, MONO AND COLOUR
  225.  
  226.  
  227.