FAQ  •  Register  •  Login

aplib decompressor for ZX Basic.

<<

na_th_an

Posts: 73

Joined: Fri May 07, 2010 7:34 am

Post Thu Aug 02, 2012 11:18 am

aplib decompressor for ZX Basic.

1. Download the compressor -> http://www.mojontwins.com/warehouse/apack.zip
2. Pack your binaries using it:
  Code:
> apack.exe input.bin output.bin

3. Include your packed binaries in your program
  Code:
packed:
Asm
   Binary "output.bin"
End Asm

4. Include the aplib decompressor (by dwedit/metalbrain/utopian) in your program
  Code:
#include once "aplib.bas"

5. Call the depacker to decompress your binary to somewhere else (source, destination):
  Code:
aplibUnpack (@packed, 16384)


Here's aplib.bas:
  Code:
'' aplib.bas

Sub aplibDummyContainer
   asm
   
   ; aPPack decompressor
   ; original source by dwedit
   ; very slightly adapted by utopian
   ; optimized by Metalbrain
   ; Adapted for ZX Basic by na_th_an
   
   ;hl = source
   ;de = dest

   depack:   
         ld   ixl,128
   apbranch1:   
         ldi
   aploop0:   
         ld   ixh,1      ;LWM = 0
   aploop:      
         call    ap_getbit
         jr    nc,apbranch1
         call    ap_getbit
         jr    nc,apbranch2
         ld    b,0
         call    ap_getbit
         jr    nc,apbranch3
         ld   c,16      ;get an offset
   apget4bits:   
         call    ap_getbit
         rl    c
         jr   nc,apget4bits
         jr    nz,apbranch4
         ld    a,b
   apwritebyte:
         ld    (de),a      ;write a 0
         inc    de
         jr   aploop0
   apbranch4:
         and   a
         ex    de,hl       ;write a previous byte (1-15 away from dest)
         sbc    hl,bc
         ld    a,(hl)
         add   hl,bc
         ex    de,hl
         jr   apwritebyte
   apbranch3:
         ld    c,(hl)      ;use 7 bit offset, length = 2 or 3
         inc    hl
         rr    c
         ret    z      ;if a zero is encountered here, it is EOF
         ld   a,2
         adc   a,b
         push    hl
         ld   iyh,b
         ld   iyl,c
         ld    h,d
         ld    l,e
         sbc    hl,bc
         ld    c,a
         jr   ap_finishup2
   apbranch2:
         call    ap_getgamma   ;use a gamma code * 256 for offset, another gamma code for length
         dec    c
         ld   a,c
         sub   ixh
         jr    z,ap_r0_gamma      ;if gamma code is 2, use old r0 offset,
         dec    a
         ;do I even need this code?
         ;bc=bc*256+(hl), lazy 16bit way
         ld    b,a
         ld    c,(hl)
         inc    hl
         ld   iyh,b
         ld   iyl,c
   
         push    bc
         
         call    ap_getgamma
   
         ex    (sp),hl      ;bc = len, hl=offs
         push    de
         ex    de,hl
   
         ld   a,4
         cp   d
         jr    nc,apskip2
         inc    bc
         or   a
   apskip2:
         ld    hl,127
         sbc    hl,de
         jr    c,apskip3
         inc    bc
         inc    bc
   apskip3:
         pop    hl      ;bc = len, de = offs, hl=junk
         push    hl
         or    a
   ap_finishup:
         sbc    hl,de
         pop    de      ;hl=dest-offs, bc=len, de = dest
   ap_finishup2:
         ldir
         pop    hl
         ld   ixh,b
         jr    aploop
   
   ap_r0_gamma:
         call    ap_getgamma      ;and a new gamma code for length
         push    hl
         push    de
         ex   de,hl
   
         ld   d,iyh
         ld   e,iyl
         jr    ap_finishup
   
   
   ap_getbit:
         ld   a,ixl
         add   a,a
         ld   ixl,a
         ret   nz
         ld   a,(hl)
         inc   hl
         rla
         ld   ixl,a
         ret
   
   ap_getgamma:
         ld    bc,1
   ap_getgammaloop:
         call    ap_getbit
         rl    c
         rl    b
         call    ap_getbit
         jr    c,ap_getgammaloop
         ret
   End Asm
apDataPool:
   Asm
   ap__source:
         defw 0
   ap__destination:
         defw 0
   End Asm
End Sub

Sub aplibUnpack (source as uInteger, destination as uInteger)
   Poke uInteger @apDataPool, source
   Poke uInteger 2 + @apDataPool, destination
   Asm
      ld hl, (ap__source)
      ld de, (ap__destination)
      di
      push ix
      push iy
      call depack
      pop iy
      pop ix
      ei
   End Asm
End Sub



Happy coding!
Last edited by na_th_an on Mon Aug 06, 2012 7:02 am, edited 1 time in total.
<<

slenkar

Posts: 282

Joined: Sun Feb 13, 2011 3:33 am

Location: Kentucky US, used to be Birmingham UK

Post Thu Aug 02, 2012 4:49 pm

Re: aplib decompressor for ZX Basic.

do you have an example?

What kind of data can be packed? (bytes,ints,strings?)
<<

boriel

Site Admin

Posts: 1463

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Thu Aug 02, 2012 5:22 pm

Re: aplib decompressor for ZX Basic.

This will be in the ZX Library. May I bundle it with the compiler? :?:
If so, in the Mojon Twins directory?
<<

slenkar

Posts: 282

Joined: Sun Feb 13, 2011 3:33 am

Location: Kentucky US, used to be Birmingham UK

Post Thu Aug 02, 2012 6:32 pm

Re: aplib decompressor for ZX Basic.

how does someone know where to unpack a bin?
How do I know where there is empty space in RAM?
<<

na_th_an

Posts: 73

Joined: Fri May 07, 2010 7:34 am

Post Fri Aug 03, 2012 7:27 am

Re: aplib decompressor for ZX Basic.

You can pack whatever binary data.

how does someone know where to unpack a bin? - You unpack it where you need it to be.

For example, you can pack a .scr picture (6912 bytes usually compress to under 3 Kb, and even less if the screen is not very complex: I've gotten ~500 bytes for a logo or a frame) and then unpack it to 16384 to display it. You can pack your map data, and have several maps stored in memory, and then unpack the current level to your reserved space.

For example, say that you are using rectangular maps for 4x4 screens of 15x10 tiles each. Your map would be a 4x4x15x10=2400 bytes binary. You have to store somewhere, and have several compressed maps (depending on map complexity, you can save quite a bunch of bytes:

  Code:
Sub mapContainer ()
mapdata:
   Asm
      mymap: defs 2400, 0
   End Asm
level1:
   Asm
         binary "level1c.bin"
   End Asm
level2:
   Asm
         binary "level2c.bin"
   End Asm
level3:
   Asm
         binary "level3c.bin"
   End Asm
End Sub


To unpack level1 and use it, just...

  Code:
' unpack level 1:
aplibUnpack (@level1, @mapdata)


Then your engine reads the current level map data from @mapdata. When the player finished level 1 and level 2 is needed, you just unpack from @level2 to @mapdata and you have a brand new map.

Stuff like that. I use it all the time for almost everything.


As for examples, I have to clean up the source code of this game, which I hope to be sharing with you all very soon - and you'll have a working example (the logo and the backdrop are compressed images).

@Boriel: do as you wish - but the code is not mine, I just interfaced it. I'm releasing a 128K version soon - an easy way to use the extra RAM pages to store data - like some kind of "virtual storage". We use this for our 128K games in C: several levels, tilesets, and spritesets are stored compressed in the extra RAM. Mapdata, tileset and spriteset for the current level are decompressed from there to low ram buffers when entering a level. Afterwards, the game behaves like a 48K game. It's a good solution which works great and helps you avoid multi-loads ;)
<<

slenkar

Posts: 282

Joined: Sun Feb 13, 2011 3:33 am

Location: Kentucky US, used to be Birmingham UK

Post Sat Aug 04, 2012 2:58 am

Re: aplib decompressor for ZX Basic.

thanks for the explanation,

how is @mapdata first defined? is it an array,a memory address?

and how do you turn all those bytes into a BIN file?
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Sat Aug 04, 2012 11:18 am

Re: aplib decompressor for ZX Basic.

I've used the compressor in the zx basic library to do the same thing. ( http://www.boriel.com/wiki/en/index.php ... MegaLZ.bas ) - it works exactly the same way. I'll have to compare and see if this one squishes better, or runs faster :)

Slenkar:

What you do is compress the data outside an emulator. For example, one game I'm working on (it may even get finished one day) puts up 1/3 of the screen banner graphics by decompressing to the screen memory. 1/3 of the screen is a handy size, because 2K of data fits there neatly, so it's just like doing a full screen in effect.

How do I do that? Well, I design the screen in a graphics package, and when it's together I test it on an emulated spectrum to make sure it looks right. Then, in spin, I export the data from 16384 (the screen memory) for 2K to a file.

I then compress this file with megalz using a command prompt on my PC. Na_th_an's aplib works the same way, but obviously it's different code.

Then you can #include the compressed code inside an asm context, and add in the decompressor code, and voila - zipped up graphics.
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Sat Aug 04, 2012 1:42 pm

Re: aplib decompressor for ZX Basic.

na_th_an wrote:1. Download the compressor -> http://www.mojontwins.com/warehouse/apack.exe


I don't think this link is working, Na_th_an?
<<

slenkar

Posts: 282

Joined: Sun Feb 13, 2011 3:33 am

Location: Kentucky US, used to be Birmingham UK

Post Sat Aug 04, 2012 6:39 pm

Re: aplib decompressor for ZX Basic.

britlion wrote:I've used the compressor in the zx basic library to do the same thing. ( http://www.boriel.com/wiki/en/index.php ... MegaLZ.bas ) - it works exactly the same way. I'll have to compare and see if this one squishes better, or runs faster :)

Slenkar:

What you do is compress the data outside an emulator. For example, one game I'm working on (it may even get finished one day) puts up 1/3 of the screen banner graphics by decompressing to the screen memory. 1/3 of the screen is a handy size, because 2K of data fits there neatly, so it's just like doing a full screen in effect.

How do I do that? Well, I design the screen in a graphics package, and when it's together I test it on an emulated spectrum to make sure it looks right. Then, in spin, I export the data from 16384 (the screen memory) for 2K to a file.

I then compress this file with megalz using a command prompt on my PC. Na_th_an's aplib works the same way, but obviously it's different code.

Then you can #include the compressed code inside an asm context, and add in the decompressor code, and voila - zipped up graphics.


yes graphics packages export to BIN thankfully, but like what about some level data like a bunch of bytes
how do I get the BIN file?
<<

LCD

Posts: 596

Joined: Fri Feb 13, 2009 3:11 pm

Location: Vienna, Austria

Post Sun Aug 05, 2012 3:27 pm

Re: aplib decompressor for ZX Basic.

slenkar wrote:yes graphics packages export to BIN thankfully, but like what about some level data like a bunch of bytes
how do I get the BIN file?

What do you use to create levels? Does it have binary export?
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
<<

slenkar

Posts: 282

Joined: Sun Feb 13, 2011 3:33 am

Location: Kentucky US, used to be Birmingham UK

Post Sun Aug 05, 2012 5:38 pm

Re: aplib decompressor for ZX Basic.

I would probably input the numbers manually or make a tool myself
<<

LCD

Posts: 596

Joined: Fri Feb 13, 2009 3:11 pm

Location: Vienna, Austria

Post Sun Aug 05, 2012 5:50 pm

Re: aplib decompressor for ZX Basic.

slenkar wrote:I would probably input the numbers manually or make a tool myself

Then you can use:
  Code:
label:
asm
  defb 0,0,0,0,0,0,0,0,0,0 ;' your binary data
  defb 1,2,4,4,5,2,0,0,0,0 ;' your further binary data
end asm

As for decompression address you can make a buffer with a label in similar fashion, and re-use it for decompressing all levels one by one. I used similar method in "U-Boot hunt" to decompress all frames of the explosion in real time (I used the MegaLZ compression, because BorIDE can compress selected DEFB's with MegaLZ).
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
<<

slenkar

Posts: 282

Joined: Sun Feb 13, 2011 3:33 am

Location: Kentucky US, used to be Birmingham UK

Post Sun Aug 05, 2012 7:45 pm

Re: aplib decompressor for ZX Basic.

If I input the number into the .bas file like this
  Code:
label:
asm
  defb 0,0,0,0,0,0,0,0,0,0 ;' your binary data
  defb 1,2,4,4,5,2,0,0,0,0 ;' your further binary data
end asm


it wont be compressed, I have to somehow make a BIN file out of these numbers to run through the compressor
<<

LCD

Posts: 596

Joined: Fri Feb 13, 2009 3:11 pm

Location: Vienna, Austria

Post Sun Aug 05, 2012 8:30 pm

Re: aplib decompressor for ZX Basic.

slenkar wrote:If I input the number into the .bas file like this
  Code:
label:
asm
  defb 0,0,0,0,0,0,0,0,0,0 ;' your binary data
  defb 1,2,4,4,5,2,0,0,0,0 ;' your further binary data
end asm


it wont be compressed, I have to somehow make a BIN file out of these numbers to run through the compressor

Not if you use the BorIDE's build in MegaLZ compressor...
After you enter these and are happy with level design, select all the DEFB Statements and select "Edit" -> "DEFB Modificaton" -> "MegaLZ Compression". This will replace all DEFB with compressed version.
I will add ApLib compression later too.
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Sun Aug 05, 2012 9:03 pm

Re: aplib decompressor for ZX Basic.

Boride gets better and better. Going to add in aplib support too? :)

Slenkar - you can still do it by hand. Compile the defb statements in, run spin, load the file, export the bin file out from the right address. You can use the debugger to find out where it is if you can't work that out. Done.
Next

Return to How-To & Tutorials

Who is online

Users browsing this forum: Bing [Bot] and 1 guest

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by Vjacheslav Trushkin for Free Forums/DivisionCore.

phpBB SEO