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 >
Wrap
Text File
|
1990-06-24
|
10KB
|
227 lines
Degas decompression
Save valuable disk space by storing
screens in compressed Degas Elite format
Each month cover disk submissions arrive by the sackload and poor old postman
Pat's back is under a tremendous strain. The overwhelming majority of submitted
programs are superb and if it were possible we would love to use them all.
However, the storage capacity of ST disks is limited to around 800k which
means that only quite small programs can be squeezed into the limited space
available. Unfortunately, the remaining submissions, excellent though they
often are, must be rejected simply because we haven't enough space for them. We
wish we had more, but we're stuck with the ST's 800k disks.
(It's interesting to note that a few years ago 800k disks would have seemed
increadably large, but over the years programs have steadily grown in size and
complexity and a 16k word processor or spreadsheet - such as View and Viewsheet
on the BBC Micro - seems unthinkable now!)
One of the reasons why programs take up such a lot of disk space is that
they require one or more graphic screens. These are most commonly stored as
either Neochrome or Degas screens which occupy over 32k of disk space. A
typical game may require a loading screen which is displayed while the program
is booting up and a title/menu/main screen which shows the credits, options and
prompts you to press fire to start.
Since each screen is 32k long, requiring just two of these means that 64k
of disk space is consumed, even before you start writing a line of program
code! What is needed is a way of reducing the amount of space the graphics
occupy.
We can't easily do anything about Neochrome pictures, but every Degas Elite
owner will know that their art package can save screens in a highly compressed
form. In fact, this is the default Save mode.
You can tell a compressed Degas picture from its name, to be more specific,
its file extension - the name ends in PC1, PC2 or PC3. (P for picture, C for
compressed and the three numbers indicate the screen resolution: 1 is low res
colour, 2 is medium res colour and 3 is high res monochrome.)
A degas compressed screen is typically around 12k to 16k long and that is
less than half the space required for a standard screen. So if compressed
screens could be substituted for standard ones in our programs then we would
half the disk space required by the graphics.
How are Degas compressed screens stored and how can we load and decompress
them so that they can be used in our own programs? The first 34 bytes of the
picture file makes up a header that contains two flags in the first word and
the colour palette in the next 16 words.
The first byte holds the compression flag in bit seven and the second byte
holds the screen mode (zero, one or two). The result of this is that the first
word of a compressed low res picture is $8000, medium res is $8001 and
monochrome is $8002.
From byte 34 onwards is the compressed data that we'll have to decompress
before the picture can be displayed on the screen. A fairly simple, but
effective, variation on run length encoding is used, so decoding is just as
straightforward.
Read the first byte of data and if it is 128 then ignore it and go on to
the next byte. (I'm not sure why this value is required, maybe it's for padding
out an odd length file to make it even.)
If the byte - call it N - is less than 128 then copy the next N+1 bytes
straight into the screen memory as it is raw picture data. If the byte is
greater than 128 then it is a signed single byte number and the following byte
must be copied -N+1 times (subtract the byte from 256 to get the signed
number).
Here is a quick summary of the values to expect:
Byte 0... 127 = copy next n+1 bytes
Byte -1...-127 = copy next byte -n+1 times
Byte -128 = ignore
Two complications muck up a very simple system, but they aren't too
difficult to program around. The picture data is compressed one scan line
(horizontal row of pixels) at a time and also one bit plane at a time. Let's
see what this means.
Dividing the screen into scan lines isn't a problem as we can decompress
one line at a time and copy it to the screen. Since monochrome screens only
have one bit plane we can ignore this further complication if we limit
ourselves to decompressing mono only Degas pictures.
It's time now to look at some program code and to keep the programming
simple I'll use HiSoft BASIC. Here is the main part of the code used in
SHOW_PC3.BAS in the LISTINGS folder on this month's cover disk:
OPEN "I",#1,file$ :' open the file for input
colour$ = INPUT$(34,#1) :' get colour palette - ignore it!
scrstart& = FNphysbase& :' get screen start address
FOR scan% = 0 TO 399 :' 400 scan lines (rows of pixels)
addr& = scrstart& + 80*scan% :' get address of current scan line
nextline& = addr& + 80 :' get address of next scan line
DO
b% = ASC(INPUT$(1,#1)) :' read a byte from picture file
IF b%<128 THEN
FOR i% = 0 TO b% :' copy next n+1 bytes literally
POKEB addr&,ASC(INPUT$(1,#1))
addr& = addr& + 1
NEXT
END IF
IF b%>128 THEN
byte% = ASC(INPUT$(1,#1))
FOR i% = 1 TO 256-b%+1 :' copy byte% -b%+1 times
POKEB addr&,byte%
addr& = addr& + 1
NEXT
END IF
LOOP UNTIL addr&>=nextline& :' finished scan line?
NEXT :' next scan line
CLOSE #1 :' close the file
A FOR...NEXT loop sorts out the scan line problem and the DO...LOOP
decompresses each line. The scan line start address is calculated by
multiplying the number of scan lines by 80 (because there are 80 bytes per
line) and adding on the screen start address.
Two short FOR...NEXT loops poke the decompressed data into the screen
memory. Which one is chosen depends on whether the flag byte is greater or less
than 128.
This BASIC program quite easily translates into 68000 machine code (it's
called SHOW_PC3.S in the listings folder). Here is the main loop which decodes
the 400 scan lines:
MOVE #399,D7 400 scan lines
MOVEA.L A5,A4 A5 = current scan line address
loop1 ADDA.L #80,A4 A4 = next scan line address
loop2 f_read buffer,1,in read 1 byte
MOVE.B buffer(A6),D0 D0 = byte
CMP.B #128,D0 < 128 ?
BPL skip1
MOVE D0,D6 loop counter
ANDI #$FF,D6
loop3 f_read buffer,1,in read one byte into buffer
MOVE.B buffer(A6),(A5)+ store byte in screen
DBRA D6,loop3
BRA next
skip1 CMP.B #129,D0 > 128 ?
BMI next
MOVE D0,D6 loop counter
NOT D6
ANDI #$FF,D6
ADDQ.L #1,D6
f_read buffer,1,in read one byte into buffer
loop4 MOVE.B buffer(A6),(A5)+ store byte in screen
DBRA D6,loop4
next MOVE.L A5,D0 done whole scan line?
CMP.L A4,D0
BMI loop2 back to loop2 if not done
MOVEA.L A4,A5 next scan line address
DBRA D7,loop1 done all scan lines?
Now let's take a look at how low res colour pictures can be decompressed.
There are four bit planes and each plane is compressed separately. Think of the
screen as being made up of (8,000) groups of four words. The first word in each
group belongs to the first bit plane, the second word is the second bit plane,
the third word is the third and the fourth is the fourth.
What you must do is decompress each scan line as before, but do it four
times - the first time decompressing the first word in each group, then the
second time decompressing the second word, the third time its the turn of the
third word and finally comes the fourth word.
The addition of a simple FOR...NEXT loop to our mono decompressor copes
with the extra bit planes. Each word (two bytes) is poked into the screen
memory then we skip forward over the other bit plane words in the group:
scrstart& = FNphysbase&
FOR scan%=0 TO 199
FOR plane%=0 TO 6 STEP 2
addr&=scrstart& + 160*scan% + plane%
nextline&=addr& + 160
DO
b% = ASC(INPUT$(1,#1))
IF b%<128 THEN
FOR i% = 0 TO b%
POKEB addr&,ASC(INPUT$(1,#1))
IF addr& AND 1 THEN addr&=addr&+7 ELSE addr&=addr&+1
NEXT
END IF
IF b%>128 THEN
byte% = ASC(INPUT$(1,#1))
FOR i% = 1 TO 256-b%+1
POKEB addr&,byte%
IF addr& AND 1 THEN addr&=addr&+7 ELSE addr&=addr&+1
NEXT
END IF
LOOP UNTIL addr&>=nextline&
NEXT
NEXT
CLOSE #1
Note that in low res colour each scan line occupies 160 bytes of memory and
that there are 200 lines (horizontal rows of pixels) on the screen.
What I haven't yet mentioned, is the colour palette. As this is quite
simple I have left it until last. All you need to do is read in words 1 to 16
of the header and set the 16 colours of palette according to the contents of
these words. Here's a HiSoft BASIC routine to set the palette:
OPEN "I",#1,file$
dummy$ = INPUT$(2,#1)
FOR i% = 0 TO 15
a% = 256*ASC(INPUT$(1,#1)) + ASC(INPUT$(1,#1))
dummy% = FNsetcolor%(i%,a%)
NEXT
All the programming examples are in fairly straightforward BASIC code
(apart from a little 68000) and you should be able to convert them into GFA or
Fast BASIC, or STOS.
If the decompression routine seems slow it is because of the slow ST disk
drives and it's not a result of inefficient code. To speed up the program load
the compressed picture into a buffer and decompress the data in memory.
HARDWARE: ALL STs, MONO AND COLOUR