Created
March 10, 2026 00:34
-
-
Save scruss/3edb4236feda48ddcc697d6caeaeff44 to your computer and use it in GitHub Desktop.
RLE graphics decoding in ZX81 basic
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 10 LET A$="J27AO279Q269Q277S267S27661M2657G72746G73737F84726G75717F77616F87DF79BF7ABE8B9F7C9E7E7E8E8D7E9C7FAA8EBA7FC88ED78F61767F71758E73738F73737F75718F7571L267R277R269P279P26BN27B5" | |
| 20 LET P=1 | |
| 22 LET X=0 | |
| 24 LET Y=43 | |
| 30 FOR I=1 TO LEN A$ | |
| 50 LET N=(CODE A$(I)) - 28 | |
| 60 FOR K=1 TO N | |
| 70 IF P=1 THEN PLOT X,Y | |
| 80 LET X=X+1 | |
| 90 IF X<43 THEN GOTO 120 | |
| 100 LET Y=Y-1 | |
| 110 LET X=0 | |
| 120 NEXT K | |
| 130 LET P=NOT P | |
| 140 IF P=1 THEN SLOW | |
| 150 IF P=0 THEN FAST | |
| 160 NEXT I |
Author
Author
Assuming zx.pbm is a NetPBM file of the appropriate dimensions, this is how I RLE-converted the image:
pnmnoraw zx.pbm | tail +3 | tr -d '\n' | sed 's/$/\n/;' | perl -nle 'while (m/(.)(\1*)/g) {print length($2)+1," ",$1;}' | awk 'BEGIN {OFS=" "} NR==1 && $2==0 {print 0,1} $1<=35 {print $1,$2} $1>35 {rem=$1%35;inv=!$2;for (i=1;i<=int($1/35);i++) {print 35,$2; print 0,inv;} print rem, $2;}'| awk '{printf("%1s",substr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",1+$1,1));} END{print "";}'
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The hard part was making an image simple enough that the whole source would fit on one screen. It's also only 43 px wide, where the ZX81 can have a whole 64 px wide display — woo!
The ZX81 doesn't use ASCII. This code relies on the fact that the code point for
0is at 28, and the following characters are encoded contiguously from there:0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ. It was strongly inspired by the old Compuserve RLE graphics format