!0.......^.........^.........^..

!B

\H11\H07\H10\H00        SCREEN SCRUNGER         



!2.......^.........^.........^.........^.........^.........^....

 Calling all those of you who are contemplating adding graphics

 to your adventure programs. Chris Wood has devised a couple of

 screen compressor programs that'll "scrunge" those screens and

                   save those precious bytes.

!1.......^.........^.........^.........^........



What  we're  talking about here is a  two-in-one

"screen scrunger" - or screen compressor, if you

prefer  -  that's  fast,  relocatable and  short

(less  than  50  bytes  each!). Using either  of

these  routines,  or a combination of both,  you

can "scrunge" most screens down to at least half

their  original size and, with a built-in  relo-

catable screen scrunger saved as a standard with

each  picture,  you  can have between 10 and  15

screens stored in memory at any one time!

  Adventure  writers only require the top  third

or  so  of  each screen saved, which is why  the

program included does this ... and even lets you

move   bits  of  the  screen  around.  The  only

restriction  on  saving  parts of the screen  is

that  attributes  have  to be compressed  separ-

ately;  this  is  because  the program can  only

handle continuous chunks of memory.



!0.......^.........^.........^..

!B

ON-SCREEN STORAGE

!1.......^.........^.........^.........^........

At  this  stage, there's no need to go into  too

much  detail about how the Spectrum's screen  is

laid  out  - but if you've got a couple of  days

spare sometime ... Suffice to say that what  you

see on-screen is no more than an area of  memory

that  we  can see and, as far as the  Spectrum's

concerned,  it's nothing but a jumble of  binary

figures.

  In  the  meantime, here's some information  on

how  the scrunger routines work ... and why  you

need  two of them! Take a look at a few  SCREEN$

pictures  and  you'll see there are quite a  few

large  areas  of  the  same colour - from  which

you'd surmise that the same value is popping  up

in memory quite often. You'd be right!

  Thus,  our  first  routine  dives through  the

screen  memory  counting  the number of times  a

particular value pops up until a different value

is found. Once another value has been found, the

Spectrum resets its internal counter, stores the

data



!0.......^.........^.........^..

!B

  10 POKE 23658,8

!2.......^.........^.........^.........^.........^.........^....

Line 10          Turns the Caps Lock feature on

!0.......^.........^.........^..



  20 PAPER 7: INK 0: CLS

  30 PRINT "  HOW MUCH DO YOU WA

NT SAVED?"

  40 PRINT ''" 1. PART OF SCREEN

$ "''" 2. ALL OF SCREEN$ "

  50 IF INKEY$="2" THEN  POKE 30

009,64: POKE 30048,91: POKE 3005

6,64: POKE 30065,91: POKE 40010,

64: POKE 40046,91: POKE 40054,64

: POKE 40063,91: GO TO 500

  60 IF INKEY$<>"1" THEN  GO TO 

50

  70 CLS : PRINT ''"  INPUT LIMI

TS"

  80 PRINT ''"64.TOP OF INK"''"7

2.MIDDLE OF INK"''"80.BOTTOM OF

INK"''"88.TOP OF ATTRIBUTES"''"8

9.MIDDLE OF ATTRIBUTES"''"90.BOT

TOM OF ATTRIBUTES"''"91.END OF S

CREEN"

  90 INPUT "FROM? ";start: INPUT

 "END? ";end

  95 POKE 30009,start: POKE 4001

0,start: POKE 30048,end: POKE 40

046,end

 100 INPUT "PARTS TO GO TO SAME

PLACE?";a$: IF CODE a$=CODE "Y"

THEN  GO TO 110

 105 INPUT "TO GO TO? ";dest

 106 LET diff=dest-start: LET en

d=end+diff: LET start=start+diff

 110 POKE 30056,start: POKE 4005

4,start: POKE 30065,end: POKE 40

063,end

!2.......^.........^.........^.........^.........^.........^....

Lines 20-110     Provide menu options for the screen scrunger

!0.......^.........^.........^..



 500 GO SUB 990: LET l=USR 30000

: LET m=USR 40000: LET l=l-30054

: LET m=m-40052

 510 CLS : PRINT "EXTRACTING 0 A

ND 255 TAKES "; PAPER 6;l''; PAP

ER 7;"SQUASHING ALL DATA TAKES "

; PAPER 6;m

!2.......^.........^.........^.........^.........^.........^....

Lines 500-510    Find out how much space is saved by each

                 routine, and then print up each option.

!0.......^.........^.........^..



 520 PRINT ''"SAVE FIRST OR SECO

ND?"

 530 INPUT "SAVE? (1 OR 2)?";a

 540 IF a=1 THEN  CLS : RANDOMIZ

E USR 30054: SAVE "SQUASHED SCRE

EN$ "CODE 30054,l: RUN

 550 IF a=2 THEN  CLS : RANDOMIZ

E USR 40052: SAVE "SQUASHED SCRE

EN$ "CODE 40052,m: RUN

 560 GO TO 530

!2.......^.........^.........^.........^.........^.........^....

Lines 520-560    Save the "scrunged" screen

!0.......^.........^.........^..



 990 POKE 65370,64: POKE 65373,1

96: RANDOMIZE USR 65368: RETURN

 995 POKE 65370,196: POKE 65373,

64: RANDOMIZE USR 65368: RETURN

 999 STOP

!2.......^.........^.........^.........^.........^.........^....

Lines 990-999    Contain the screen handling subroutines

!0.......^.........^.........^..



1000 RESTORE 1010: LET ch=0: FOR

 n=0 TO 81: READ a: LET ch=ch+a:

 POKE 40000+n,a: POKE 49000+n,a:

 NEXT n

1001 IF ch<>8217 THEN  PRINT "ER

ROR IN DATA IN LINE 1010": STOP

1005 LET ch=0: FOR n=0 TO 97: RE

AD a: LET ch=ch+a: POKE 30000+n,

a: POKE 39000+n,a: NEXT n

1006 IF ch<>9171 THEN  PRINT "ER

ROR IN DATA IN LINE 1020": STOP

1008 FOR n=65368 TO 65379: READ

a: POKE n,a: NEXT n: CLEAR 29999

: PRINT "LOADING": LOAD ""SCREEN

$ : GO SUB 995: GO TO 1

!2.......^.........^.........^.........^.........^.........^....

Lines 1000-1008  Provide the initialisation routines

!0.......^.........^.........^..



1009 REM SQUASH ALL CODE

1010 DATA 197,209,33,85,0,25,235

,221,33,0,64,14,1,221,126,0,221,

190,1,32,8,121,60,167,40,3,79,24

,10,221,126,0,18,19,121,18,19,14

,1,221,35,221,229,225,124,254,91

,32,220,213,193,201,17,0,64,221,

33,33,0,221,9,122,254,91,200,221

,70,1,221,126,0,18,19,16,252,221

,35,221,35,24,236,0

!2.......^.........^.........^.........^.........^.........^....

Lines 1009-1010  Contain the data for the first screen scrunger

                 routine

!0.......^.........^.........^..



1019 REM EXTRACT 0 AND 255 CODE

1020 DATA 197,209,33,100,0,25,23

5,33,0,64,14,1,126,167,40,9,254,

255,40,5,237,160,3,24,21,71,121,

60,35,40,7,126,184,32,3,12,24,24

3,120,18,19,121,18,19,14,1,124,2

54,91,32,217,213,193,201,17,0,64

,221,33,46,0,221,9,122,254,91,20

0,221,126,0,167,40,10,254,255,40

,6,18,19,221,35,24,236,221,70,1,

18,19,16,252,221,35,221,35,24,22

3,0,0

!2.......^.........^.........^.........^.........^.........^....

Lines 1019-1020  Contain the data for the second screen scrunger

                 routine

!0.......^.........^.........^..



1030 DATA 17,0,176,33,0,64,1,0,2

7,237,176,201

!2.......^.........^.........^.........^.........^.........^....

Line 1030        Provides the save routine for the SCREEN$



The  "screen  scrunger" program should be initialised with  "RUN

1000" to set up the data lines 1009-1030. Once the data has been

initialised, the program flow is directed to the menu of options

offered by the scrunger.

!1.......^.........^.........^.........^........



!B

and  carries on looking through the rest of  the

screen  memory. For example, the following  data

"1,1,1,1,1,1,2,2,2,2,3,3,3,3"  in screen  memory

would be scrunged and stored as "1*6,2*4,3*4".

  As  the  routine  allocates  a single byte  to

store the internal counter, if there's more than

256  occurrences  of the same value the  counter

resets  itself  and  the  next value is  treated

anew.  For  example,  a row of 400 twos  becomes

"2*0,2*144" (where a zero value denotes '256').



!0.......^.........^.........^..

FOR MY NEXT TRICK ...

!1.......^.........^.........^.........^........

The   first   routine  will  suit  most  screen-

scrunging requirements, but very complex screens

with  a  few  repeated  values  can trip up  the

routine.  For  example,  a block of memory  that

originally    looks    like   "1,2,3,4"  becomes

"1*1,2*1,3*1,4*1", and four bytes is transformed

into eight - not a good method if complex illus-

trations,  such as the start-up screen in  Lunar

Jetman,  can grow to around 7.5K instead of  the

usual 6.5K!

  And this is where the second routine comes in.

Complex  visual  screens,  such  as  Ultimate's,

require  a routine that just takes all the  free

bytes (that is, all the zeros in the background)

and  just squashes up all the rest of the  data.

Using  this  method,  you can't help but make  a

saving.

  However, to make the second routine even  more

clever,  it's  also programmed to take out  255s

that  occur  in  solidly-filled  blocks  of  the

screen.  You'll  be glad to know that the  Lunar

Jetman  screen  mentioned  earlier  is  scrunged

happily down to around 4.5K!

  But don't start worrying which routines you're

going  to  have to use with each screen, as  the

Basic program (the two routines are provided  in

the data statements) tells you which  "scrunger"

is the most efficient for each case.

  To make use of the "scrunged" screens saved by

the program, call the machine code from the same

address at which you load the code; each picture

saved  is  accompanied by a screen  decompressor

routine  at its start. For example, if you  want

to put your "scrunged" screen at address  40000,

you'd   get   it  back  on-screen  by  executing

"RANDOMIZE   USR  40000".  Happy  scrunging,  my

dearios!



!0.......^.........^.........^..

!B

\H11\H07\H10\H00SQUEEZE ME!                     

!2.......^.........^.........^.........^.........^.........^....

First of all, load up the "Screen Scrunger" and type RUN 1000.

Now, load the SCREEN$ - in this case, a view from Quicksilva's

Zombie Zombie - and it'll be stored in a high location in

memory. The program will then move on to the options screen ...



!Szombi1



!2.......^.........^.........^.........^.........^.........^....

The options screen allows you to choose whether you want to

scrunge the whole SCREEN$ or just a portion of it. In this case,

the middle section was scrunged - by typing in '72' and '80' as

the parameters for the compression.



!Szombi2



!2.......^.........^.........^.........^.........^.........^....

The program offers you the option of saving the compressed

SCREEN$ code - displaying the relevant section on-screen whilst

saving takes place. The "Screen Scrunger" itself will advise you

as to which routine is the most efficient for the SCREEN$ you're

scrunging.



!Szombi3



!0.......^.........^.........^..

CARTOON



!Scartoon



!1.......^.........^.........^.........^........



!B

--

from Your Spectrum #13 (Apr.1985)

--

!$

