News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_Fabrizio Radica

Simple RLE Encoding - Locomotive Basic

Started by Fabrizio Radica, 23:57, 28 May 19

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Fabrizio Radica

Hi :)I've made a simple RLE encoding for DATA maps (and more). It has helped me with large maps on my Castle Dungeon Game.
Hope to help you :)


5 cls:mode 2:print "Simple RLE Encoding - 2019 by Fabrizio Radica www.retroacademy.it"
10 a$="aaaaaoooooobbbppphheeegggggggeeggggguuuuuuuuu"
100 for n=0 to len(a$)
110 c$=mid$(a$,n+1,1):cnt%=cnt%+1
120 if(c$<>l$) then result$=result$+r$ : cnt%=1
150 conv$=chr$(32+cnt%)
180 l$=c$:r$=conv$+l$
200 next
210 print "----":?
220 print "Original: ":?a$:?
230 print "Compressed" :?result$:?

ervin

Quote from: Fabrizio Radica on 23:57, 28 May 19
Hi :)I've made a simple RLE encoding for DATA maps (and more). It had help me with large maps on my Castle Dungeon Game.
Hope to help you :)

5 cls:mode 2:print "Simple RLE Encoding - 2019 by Fabrizio Radica www.retroacademy.it"
10 a$="aaaaaoooooobbbppphheeegggggggeeggggguuuuuuuuu"
100 for n=0 to len(a$)
110 c$=mid$(a$,n+1,1):cnt%=cnt%+1
120 if(c$<>l$) then result$=result$+r$ : cnt%=1
150 conv$=chr$(32+cnt%)
180 l$=c$:r$=conv$+l$
200 next
210 print "----":?
220 print "Original: ":?a$:?
230 print "Compressed" :?result$:?



That's very cool.
Simple but effective.

Fabrizio Radica

#2
Quote from: ervin on 02:31, 29 May 19

That's very cool.
Simple but effective.
It seems to be a good start solution for Huffman encoding.
Why not...

ronaldo

#3
It's an interesting idea to have compression in BASIC, as memory is very limited when doing games. Personally I think that the interesting part is the decompression, which is the one you will normally do in your games. Compression can be done offline, and compressed data can be stored in binary files. Then you can simply load your binary data into a place in memory and decompress the part you want into a decompression buffer.

For the decompression part I would rather prefer not to be limited by string sizes in BASIC. Using PEEK and POKE is the way to go for me. Here it goes a decompression example. I store a compressed map into memory and decompress it to a different place in memory. Then I simply draw it to the screen. Measured times are reasonable, so it could be perfectly done in a game. The user can wait some seconds for a big map to be decompressed.


5 ' REASONABLY FAST RLE DECOMPRESSOR IN BASIC
6 ' By ronaldo/Cheesetea (@FranGallegoBR)
7 ' 29/05/2019
8 ' MIT License: https://opensource.org/licenses/MIT
9 '
10 DEFINT a-z:MODE 1:MEMORY &3FFF
20 PRINT "Loading data...";:s!=TIME
30 p=&4000:GOSUB 2100: ' Load compressed data at &4000
40 GOSUB 500:PRINT "Decompressing...";:s!=TIME
50 p=&4000:t=&4040:GOSUB 1100: ' Decompress data to &4040
60 GOSUB 500:PRINT "Showing the map":s!=TIME
70 p=&4040:h=8:w=10:GOSUB 3100: ' Print the uncompressed map
80 GOSUB 500
90 GOTO 90

490 ' Print Time Passed since last s!=TIME
500 PRINT USING "#.###";(TIME-s!)/300;:PRINT" secs":RETURN

1000 '
1010 ' DECOMPRESS RLE DATA
1020 '  Decompresses a RLE compressed data buffer that ends in 0
1030 ' INPUT
1040 '  p: Pointer to RLE data to be decompressed (ends in 0)
1050 '  t: Pointer to location where it should be decompressed
1060 '
1100 n=PEEK(p)
1110 WHILE(n):d=PEEK(p+1)
1120 FOR i=0TO n-1:POKE t+i,d:NEXT:t=t+n
1130 p=p+2:n=PEEK(p):WEND
1140 RETURN

2000 '
2010 ' LOAD DATA TO MEMORY LOCATION
2020 '  This should be done with LOAD from a binary file
2030 '  Right now, it inserts it by loading from DATAs
2030 '  p: Pointer to the location where data should be placed
2040 '
2100 READ d
2110 WHILE(d):POKE p,d:p=p+1:READ d:WEND
2120 POKE p,d:RETURN
2130 DATA 11,35,8,32,2,35,1,32,1,45,2,35,1,32,2,35,1,32,2,35
2140 DATA 1,47,1,32,2,35,1,32,2,35,1,32,2,35,8,32,2,35,2,32
2150 DATA 5,61,1,32,2,35,8,32,11,35,0

'##########
'#        #
'# -## ## #
'#/ ## ## #
'#        #
'#  ===== #
'#        #
'##########

3000 '
3010 ' PRINT ASCII MAP
3020 '  Prints an ascii map that is stored in memory as 1 byte
3030 '  per character, like strings, but with unlimited size.
3040 '  p: Pointer to the start of the MAP in memory
3050 '  w: Width of the map in characters
3060 '  h: heignt of the map in characters
3100 FOR h=h TO 1 STEP -1
3110 FOR p=p TO p+w-1:PRINT CHR$(PEEK(p));:NEXT
3120 PRINT:NEXT
3130 RETURN


Fabrizio Radica

Quote from: ronaldo on 20:43, 29 May 19
It's an interesting idea to have compression in BASIC, as memory is very limited when doing games. Personally I think that the interesting part is the decompression, which is the one you will normally do in your games. Compression can be done offline, and compressed data can be stored in binary files. Then you can simply load your binary data into a place in memory and decompress the part you want into a decompression buffer.

For the decompression part I would rather prefer not to be limited by string sizes in BASIC. Using PEEK and POKE is the way to go for me. Here it goes a decompression example. I store a compressed map into memory and decompress it to a different place in memory. Then I simply draw it to the screen. Measured times are reasonable, so it could be perfectly done in a game. The user can wait some seconds for a big map to be decompressed.


5 ' REASONABLY FAST RLE DECOMPRESSOR IN BASIC
6 ' By ronaldo/Cheesetea (@FranGallegoBR)
7 ' 29/05/2019
8 ' MIT License: https://opensource.org/licenses/MIT
9 '
10 DEFINT a-z:MODE 1:MEMORY &3FFF
20 PRINT "Loading data...";:s!=TIME
30 p=&4000:GOSUB 2100: ' Load compressed data at &4000
40 GOSUB 500:PRINT "Decompressing...";:s!=TIME
50 p=&4000:t=&4040:GOSUB 1100: ' Decompress data to &4040
60 GOSUB 500:PRINT "Showing the map":s!=TIME
70 p=&4040:h=8:w=10:GOSUB 3100: ' Print the uncompressed map
80 GOSUB 500
90 GOTO 90

490 ' Print Time Passed since last s!=TIME
500 PRINT USING "#.###";(TIME-s!)/300;:PRINT" secs":RETURN

1000 '
1010 ' DECOMPRESS RLE DATA
1020 '  Decompresses a RLE compressed data buffer that ends in 0
1030 ' INPUT
1040 '  p: Pointer to RLE data to be decompressed (ends in 0)
1050 '  t: Pointer to location where it should be decompressed
1060 '
1100 n=PEEK(p)
1110 WHILE(n):d=PEEK(p+1)
1120 FOR i=0TO n-1:POKE t+i,d:NEXT:t=t+n
1130 p=p+2:n=PEEK(p):WEND
1140 RETURN

2000 '
2010 ' LOAD DATA TO MEMORY LOCATION
2020 '  This should be done with LOAD from a binary file
2030 '  Right now, it inserts it by loading from DATAs
2030 '  p: Pointer to the location where data should be placed
2040 '
2100 READ d
2110 WHILE(d):POKE p,d:p=p+1:READ d:WEND
2120 POKE p,d:RETURN
2130 DATA 11,35,8,32,2,35,1,32,1,45,2,35,1,32,2,35,1,32,2,35
2140 DATA 1,47,1,32,2,35,1,32,2,35,1,32,2,35,8,32,2,35,2,32
2150 DATA 5,61,1,32,2,35,8,32,11,35,0

'##########
'#        #
'# -## ## #
'#/ ## ## #
'#        #
'#  ===== #
'#        #
'##########

3000 '
3010 ' PRINT ASCII MAP
3020 '  Prints an ascii map that is stored in memory as 1 byte
3030 '  per character, like strings, but with unlimited size.
3040 '  p: Pointer to the start of the MAP in memory
3050 '  w: Width of the map in characters
3060 '  h: heignt of the map in characters
3100 FOR h=h TO 1 STEP -1
3110 FOR p=p TO p+w-1:PRINT CHR$(PEEK(p));:NEXT
3120 PRINT:NEXT
3130 RETURN


WoooWW!

It's possible to makes RSX commands from Basic?It whould be really interesting encode or decode directly from your code similar to: |encode,"map.rle" or |decode,"map.rle"I'm very interested in write RSX commands.

Powered by SMFPacks Menu Editor Mod