Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
aplib decompressor for ZX Basic.
#1
1. Download the compressor -> <!-- m --><a class="postlink" href="http://www.mojontwins.com/warehouse/apack.zip">http://www.mojontwins.com/warehouse/apack.zip</a><!-- m -->
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!
Reply
#2
do you have an example?

What kind of data can be packed? (bytes,ints,strings?)
Reply
#3
This will be in the ZX Library. May I bundle it with the compiler? :?:
If so, in the Mojon Twins directory?
Reply
#4
how does someone know where to unpack a bin?
How do I know where there is empty space in RAM?
Reply
#5
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 Wink
Reply
#6
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?
Reply
#7
I've used the compressor in the zx basic library to do the same thing. ( <!-- m --><a class="postlink" href="http://www.boriel.com/wiki/en/index.php/ZX_BASIC:MegaLZ.bas">http://www.boriel.com/wiki/en/index.php ... MegaLZ.bas</a><!-- m --> ) - it works exactly the same way. I'll have to compare and see if this one squishes better, or runs faster Smile

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.
Reply
#8
na_th_an Wrote:1. Download the compressor -> <!-- m --><a class="postlink" href="http://www.mojontwins.com/warehouse/apack.exe">http://www.mojontwins.com/warehouse/apack.exe</a><!-- m -->

I don't think this link is working, Na_th_an?
Reply
#9
britlion Wrote:I've used the compressor in the zx basic library to do the same thing. ( <!-- m --><a class="postlink" href="http://www.boriel.com/wiki/en/index.php/ZX_BASIC:MegaLZ.bas">http://www.boriel.com/wiki/en/index.php ... MegaLZ.bas</a><!-- m --> ) - it works exactly the same way. I'll have to compare and see if this one squishes better, or runs faster Smile

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?
Reply
#10
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!
Reply
#11
I would probably input the numbers manually or make a tool myself
Reply
#12
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!
Reply
#13
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
Reply
#14
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!
Reply
#15
Boride gets better and better. Going to add in aplib support too? Smile

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.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)