Climbing Man illusion (BBC BASIC)

discussion of beeb/electron applications, languages, utils and educational s/w
lurkio
Posts: 2069
Joined: Tue Apr 09, 2013 11:30 pm
Location: Doomawangara
Contact:

Climbing Man illusion (BBC BASIC)

From the April 1985 issue of Practical Computing magazine:
Two illusions, one visual [the Penrose stairs] and one audible [the Shepard scale], are combined in James Allwright's cunning program. A man walks up a closed uphill staircase to the sound of notes which appear to be constantly rising in pitch.

The staircase was originally drawn by M C Escher. It is a three-dimensional projection drawing for which some parameters are:

D -- distance of observer from screen
SF -- scale factor
VY and SF -- constants which can be chosen fairly arbitrarily
SS -- step size
VX -- constant which must be adjusted to make the illusion work.

The UD at line 180 is the delay time. If you cannot tell what is going on you may reduce this but the author suggests that you do so only as a last resort.

Run the program in JSBeeb:

Here's the listing:

Code: Select all

``````  10 REM
20 REM   "Climbing Man"
30 REM
40 REM   by James Allwright
50 REM
60 REM
70 REM   With Acknowledgements to
80 REM
90 REM   The Royal Institution
100 REM
110 REM   Christmas Lectures for the
120 REM
130 REM   original demonstration.
140 REM
150ONERRORVDU4:ONERROROFF:END
160DIMMX(35),MY(35),MN(35)
170DISP=40:D=3000:SF=130:VX=D+6*SF:VY=4000
180SS=VY*2*SF/(16*D+70*SF):UD=30
190VDU23,224,0,0,6,&F,&1F,&1F,&1F,&C
200VDU23,225,4,&C,&1E,&3E,&7F,&DF,&9F,&BF
210VDU23,226,&FF,&FE,&7E,&7E,&7E,&F8,&F0,&E0
220VDU23,227,0,0,0,1,3,3,7,&F
230VDU23,228,&FF,&FF,&C1,&C0,&80,0,0,0
240VDU23,229,0,&80,&80,&C0,&66,&3E,&1C,&18
250VDU23,230,&E,&1C,&18,&30,&60,&C0,&F0,&F0
260VDU23,231,&F8,&FC,&CE,&C7,&C3,&C1,&C0,&C1
270VDU23,232,0,0,0,0,&80,&C0,&C0,&C0
280VDU23,233,&C7,&CC,&CC,&CE,&C6,&C0,&F0,&F0
290VDU23,234,0,0,0,&18,&3C,&7E,&3C,&18
300VDU23,235,0,0,0,1,3,7,6,6
310VDU23,236,&7E,&FF,&FF,&FF,&7E,&7E,&7E,&7E
320VDU23,237,0,0,0,&80,&C0,&E0,&60,&60
330VDU23,238,4,4,6,2,2,0,0,0
340VDU23,239,&7E,&7E,&7E,&7E,&7E,&7E,&7E,&7E
350VDU23,241,&7E,&66,&66,&66,&66,&C6,&C6,&66
360VDU23,242,6,6,6,6,6,6,6,6
370VDU23,243,&7E,&66,&66,&66,&66,&63,&63,&66
380VDU23,244,&60,&60,&60,&60,&60,&60,&60,&60
390VDU23,245,0,0,&60,&F0,&F8,&F8,&F8,&30
400VDU23,246,&20,&30,&78,&7C,&FE,&FB,&F9,&FD
410VDU23,247,&FF,&7F,&7E,&7E,&7E,&1F,&F,7
420VDU23,248,0,0,0,&80,&C0,&C0,&E0,&F0
430VDU23,249,&FF,&FF,&83,3,1,0,0,0
440VDU23,250,0,1,1,3,&66,&7C,&38,&18
450VDU23,251,&70,&38,&18,&C,6,3,&F,&F
460VDU23,252,&1F,&3F,&77,&E3,&C3,&83,3,&83
470VDU23,253,0,0,0,0,1,3,3,3
480VDU23,254,&E3,&33,&33,&73,&63,3,&F,&F
490MODE1
500MOVEDISP,0:DRAWDISP,DISP
510PROCMV(SF,0,5*SF):PROCMV(SF,0,SF)
520PLOT85,FNX(SF,5*SF),FNY(0,SF)
530MOVEFNX(6*SF,4*SF),0:MOVEFNX(6*SF,0),0
540PROCTRI(6*SF,8*SS,4*SF):PROCTRI(6*SF,8*SS,0)
550X=5*SF
560FORA=0TO2:Z=A*SF:Y=(5+A)*SS
590NEXT
600Z=3*SF
610FORA=0TO2:X=(5-A)*SF:Y=(8+A)*SS
640NEXT
650X=0
660FORA=5TO1STEP-1:Y=-A*SS:Z=A*SF
680IFA<>5PROCMV(X+SF,Y,Z):PROCMV(X+SF,Y,Z+SF):PROCTRI(X+SF,Y-SS,Z+SF)
690NEXT
700Z=0
710FORA=0TO5:X=SF*A:Y=A*SS
730IFA<>5PROCMV(X+SF,Y+SS,Z):PROCMV(X+SF,Y,Z):GCOL0,0:PROCTRI(X+2*SF,Y+SS,Z):GCOL0,3:PROCMV(X+SF,Y+SS,Z):PROCDW(X+SF,Y,Z)
740NEXT
750FORA=0TO10:MN(A)=A MOD2
760MX(A)=FNX((A DIV2+0.5)*SF,SF/2)
770MY(A)=FNY((A DIV2)*SS,SF/2)
780NEXT
790FORA=11TO17:MN(A)=2+A MOD2
800MX(A)=FNX(5.5*SF,SF*(A-10)/2)
810MY(A)=FNY(((A-1)DIV2)*SS,SF*(A-10)/2)
820NEXT
830FORA=18TO24:MN(A)=4+A MOD2
840MX(A)=FNX((29-A)DIV2*SF+SF/2,3.5*SF)
850MY(A)=FNY(((A-2)DIV2)*SS,3.5*SF)
860NEXT
870FORA=25TO35:MN(A)=2+A MOD2
880MX(A)=FNX(SF/2,((35-A)/2)*SF+SF/2)
890MY(A)=FNY(-((35-A)DIV2)*SS,((35-A)/2)*SF+SF/2)
900NEXT
910GCOL3,1:VDU19,1,2,0,0,0:VDU19,2,2,0,0,0:VDU5
920A%=0:N%=0
930REPEAT
940PROCMAN(MN(A%),MX(A%),MY(A%))
950IF(A%MOD2)<>0SOUND0,0,0,UD/2:GOTO1000
960SOUND&300,0,0,UD/2:N%=(N%+1)MOD36
970SOUND&301,INT(ABS(18-N%)*5/6)-15,53+4*N%,UD
980T%=(N%+12)MOD36:SOUND&302,INT(ABS(18-T%)*5/6)-15,53+4*T%,UD
990T%=(N%+24)MOD36:SOUND&303,INT(ABS(18-T%)*5/6)-15,53+4*T%,UD
1000PROCMAN(MN(A%),MX(A%),MY(A%)):A%=(A%+1)MOD36
1010UNTIL0
1020END
1040X4=X1+X2-X3:Y4=Y1+Y3-Y2:Z4=Z1+Z3-Z2
1050GCOL0,C
1060PROCMV(X2,Y2,Z2):PROCMV(X1,Y1,Z1)
1070PROCTRI(X3,Y3,Z3):PROCTRI(X4,Y4,Z4)
1080GCOL0,3-C
1090PROCMV(X1,Y1,Z1):PROCDW(X2,Y2,Z2)
1100PROCDW(X3,Y3,Z3):PROCDW(X4,Y4,Z4)
1110PROCDW(X1,Y1,Z1)
1120ENDPROC
1130DEFPROCMV(X,Y,Z):MOVEFNX(X,Z),FNY(Y,Z)
1140ENDPROC
1150DEFPROCDW(X,Y,Z):DRAWFNX(X,Z),FNY(Y,Z)
1160ENDPROC
1170DEFPROCTRI(X,Y,Z):PLOT85,FNX(X,Z),FNY(Y,Z)
1180ENDPROC
1190DEFFNX(X,Z)=DISP+VX+D*(X-VX)/(D+Z)
1200DEFFNY(Y,Z)=DISP+VY+D*(Y-VY)/(D+Z)
1210DEFPROCMAN(A,X,Y)
1220ON A+1 GOSUB1240,1270,1300,1330,1360,1390
1230ENDPROC
1240MOVEX,Y+5*32
1250VDU224,10,8,225,8,10,226,8,10,231,232,8,8,10,233
1260RETURN
1270MOVEX+4,Y+5*32
1280VDU9,224,10,8,225,8,10,226,8,8,10,227,228,229,8,8,8,10,230
1290RETURN
1300MOVEX-4*4,Y+5*32
1310VDU234,10,8,8,235,236,237,8,8,8,10,238,239,240,8,8,10,241,8,10,242
1320RETURN
1330MOVEX-7*4,Y+5*32
1340VDU234,10,8,8,235,236,237,8,8,8,10,238,239,240,8,8,10,243,8,10,244
1350RETURN
1360MOVEX,Y+5*32
1370VDU245,10,8,246,10,8,247,10,8,8,253,252,8,10,254
1380RETURN
1390MOVEX-9*4,Y+5*32
1400VDU245,10,8,246,10,8,247,10,8,8,250,249,248,10,8,251
1410RETURN
``````

EDIT: inserted the names of the illusions into the quotation, above.
Last edited by lurkio on Mon Mar 25, 2019 1:42 pm, edited 1 time in total.

flaxcottage
Posts: 3614
Joined: Thu Dec 13, 2012 8:46 pm
Location: Derbyshire
Contact:

Re: Climbing Man illusion (BBC BASIC)

Nice.
- John

Richard Russell
Posts: 784
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Climbing Man illusion (BBC BASIC)

lurkio wrote:
Sat Mar 23, 2019 9:06 pm
The staircase was originally drawn by M C Escher.
It's debateable whether it was originally "drawn" by Escher, but it wasn't devised by him. The illusion was created by Lionel Penrose and his son Roger Penrose, and is properly called the "Penrose Stairs" (or "Penrose Steps"). A version has been supplied as one of the example programs with BBC BASIC for SDL 2.0 for quite some time; here's a YouTube video of it; I think the illusion is somewhat better than the Beeb version but it lacks the animated man. Perhaps I should incorporate that.

lurkio
Posts: 2069
Joined: Tue Apr 09, 2013 11:30 pm
Location: Doomawangara
Contact:

Re: Climbing Man illusion (BBC BASIC)

Richard Russell wrote:
Sun Mar 24, 2019 10:23 am
It's debateable whether it was originally "drawn" by Escher, but it wasn't devised by him. The illusion was created by Lionel Penrose and his son Roger Penrose, and is properly called the "Penrose Stairs" (or "Penrose Steps").
Interesting background. Thanks!

Richard Russell wrote:
Sun Mar 24, 2019 10:23 am
A version has been supplied as one of the example programs with BBC BASIC for SDL 2.0 for quite some time; here's a YouTube video of it
Curiously, when I pasted the listing into BBC BASIC for SDL (on Mac), the program ran as expected except that the VDU23 chararcter-definitions were ignored, so the man was displayed as a jumble of (accented) letters! The program worked flawlessly in BBC BASIC For Windows though.

Richard Russell
Posts: 784
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Climbing Man illusion (BBC BASIC)

lurkio wrote:
Sun Mar 24, 2019 12:56 pm
when I pasted the listing into BBC BASIC for SDL (on Mac), the program ran as expected except that the VDU23 chararcter-definitions were ignored
It's because the VDU 23 character definitions are followed by a MODE 1 in the program; moving the MODE 1 to before the VDU 23s should fix the problem.

There needs to be a way to 'undefine' characters, restoring them to their normal representation, and in BBC BASIC for SDL 2.0 that's (currently) one of the side-effects of MODE (generally, MODE resets 'VDU parameters' back to their defaults). That feels right to me but unfortunately it's not how the Beeb works.

The issue is complicated by the mobile (Android and iOS) editions of BBCSDL, which never 'quit' as such (at least, not deliberately!). When a program exits, on those platforms, it does so simply by CHAINing the 'IDE', which of course is just another BASIC program. If user-defined characters were not restored to their defaults, a subsequently run program could well misbehave.

If it's unacceptable, from a compatibility viewpoint, for MODE to 'undefine' the characters what should? I could, I suppose, allocate one of the spare VDU 23,n sub-codes for this functionality. How do you do it on other platforms?
Last edited by Richard Russell on Sun Mar 24, 2019 6:16 pm, edited 1 time in total.

BigEd
Posts: 2505
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Climbing Man illusion (BBC BASIC)

Would it be reasonable (and does it even make sense) to use MODE 7 only as the character-reset mode? Because it's the boot-time mode, for a real Beeb as shipped, and because it doesn't render user defined characters.

Rich Talbot-Watkins
Posts: 1463
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca
Contact:

Re: Climbing Man illusion (BBC BASIC)

Not sure how much of the BBC OS API you support, but OSBYTE 25 is the way to reset characters to their default definitions. I feel that this should just happen automatically when returning to the BASIC command prompt (i.e. on an implicit or explicit END, or an untrapped error).

Richard Russell
Posts: 784
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Climbing Man illusion (BBC BASIC)

BigEd wrote:
Sun Mar 24, 2019 2:30 pm
Would it be reasonable (and does it even make sense) to use MODE 7 only as the character-reset mode?
I suppose it's a possibility, but it's a bit inelegant don't you think? It might also cause some undesirable screen disturbance.

Richard Russell
Posts: 784
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Climbing Man illusion (BBC BASIC)

Rich Talbot-Watkins wrote:
Sun Mar 24, 2019 5:05 pm
Not sure how much of the BBC OS API you support, but OSBYTE 25 is the way to reset characters to their default definitions.
That's not mentioned in the Advanced User Guide; in which OS was it first implemented? In principle I could recognise *FX 25 but for inter-thread communication purposes (the interpreter and the VDU drivers necessarily run in separate threads) I would probably need to convert it into a VDU sequence anyway. It seems to me that, ideally, something that is 'set' using a VDU command ought also to be 'reset' using a VDU command (like VDU 26 cancelling VDU 24 & 28, VDU 20 cancelling VDU 19 etc.). VDU 23,24... is free, I think, so perhaps I could hijack that.
I feel that this should just happen automatically when returning to the BASIC command prompt (i.e. on an implicit or explicit END, or an untrapped error).
That wouldn't help the Android/iOS case (which is the problematical one) since BASIC normally never does return to the command prompt or execute an END. In a situation when it does (e.g. on an unexpected error) you usually need to 'fully close' the app and restart it, so everything gets initialised anyway.

tom_seddon
Posts: 280
Joined: Mon Aug 29, 2005 11:42 pm
Contact:

Re: Climbing Man illusion (BBC BASIC)

I assume OSBYTE 25 came as part of the Master's OS? - it's documented in the Master Reference Manual, part 1 (page D.2-28). You can reset character definitions in blocks of 32 (i.e., 256 bytes'-worth), according to the value of X:

0 = 32-255
1 = 32-63
2 = 64-95
3 = 96-127
(etc.)
7 = 224-255

According to its VDU 23 section, VDU 23,24 is indeed free, as it's in the 17-25 range described as "treated in the same way as user program calls but may be assigned in future". (Page E.3-19)

Despite the stupid page numbering, the Master Reference Manual is pretty useful, I've found. Very comprehensive, much more so than I assumed it would be, and (I figure) about as up to date an official document as you're likely to find.

--Tom

Richard Russell
Posts: 784
Joined: Sun Feb 27, 2011 10:35 am
Location: Downham Market, Norfolk
Contact:

Re: Climbing Man illusion (BBC BASIC)

Richard Russell wrote:
Sun Mar 24, 2019 2:04 pm
it's because the VDU 23 character definitions are followed by a MODE 1
I've checked my source code and I can't fix this. Because of the way SDL2 works (specifically, the way characters are cached as textures) MODE has to reset all the characters to their default representation for that mode. Also, VDU 23... needs to know what the mode is in order to set the size and scale of the character correctly.

So if a BASIC program relies on user-defined characters, and if you want it to run in BBC BASIC for SDL 2.0, it will be necessary to ensure that the VDU23s come after the MODE; fortunately most programs seem to do that anyway. I'll update the differences between BB4W and BBCSDL document to reflect this incompatibility.

sweh
Posts: 2035
Joined: Sat Mar 10, 2012 12:05 pm
Location: New York, New York
Contact:

Rgds
Stephen