Climbing Man illusion (BBC BASIC)

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

Climbing Man illusion (BBC BASIC)

Post by lurkio » Sat Mar 23, 2019 9:06 pm

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
 570PROCQUAD(X,Y,Z,X+SF,Y,Z,X+SF,Y,Z+SF,0)
 580PROCQUAD(X,Y,Z+SF,X+SF,Y,Z+SF,X+SF,Y+SS,Z+SF,0)
 590NEXT
 600Z=3*SF
 610FORA=0TO2:X=(5-A)*SF:Y=(8+A)*SS
 620PROCQUAD(X,Y,Z,X+SF,Y,Z,X+SF,Y,Z+SF,0)
 630PROCQUAD(X,Y,Z,X,Y,Z+SF,X,Y+SS,Z+SF,3)
 640NEXT
 650X=0
 660FORA=5TO1STEP-1:Y=-A*SS:Z=A*SF
 670PROCQUAD(X,Y,Z,X+SF,Y,Z,X+SF,Y,Z+SF,0)
 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
 720PROCQUAD(X,Y,Z,X+SF,Y,Z,X+SF,Y,Z+SF,0)
 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
1030DEFPROCQUAD(X1,Y1,Z1,X2,Y2,Z2,X3,Y3,Z3,C)
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
:idea:

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.

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

Re: Climbing Man illusion (BBC BASIC)

Post by flaxcottage » Sat Mar 23, 2019 9:13 pm

Nice. =D>
- John

Image

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

Re: Climbing Man illusion (BBC BASIC)

Post by Richard Russell » Sun Mar 24, 2019 10:23 am

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.

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

Re: Climbing Man illusion (BBC BASIC)

Post by lurkio » Sun Mar 24, 2019 12:56 pm

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.

:?:

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

Re: Climbing Man illusion (BBC BASIC)

Post by Richard Russell » Sun Mar 24, 2019 2:04 pm

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.

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

Re: Climbing Man illusion (BBC BASIC)

Post by BigEd » 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? Because it's the boot-time mode, for a real Beeb as shipped, and because it doesn't render user defined characters.

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

Re: Climbing Man illusion (BBC BASIC)

Post by Rich Talbot-Watkins » 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. 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).

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

Re: Climbing Man illusion (BBC BASIC)

Post by Richard Russell » Sun Mar 24, 2019 5:22 pm

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.

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

Re: Climbing Man illusion (BBC BASIC)

Post by Richard Russell » Sun Mar 24, 2019 5:51 pm

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)

Post by tom_seddon » Sun Mar 24, 2019 10:40 pm

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

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

Re: Climbing Man illusion (BBC BASIC)

Post by Richard Russell » Sun Mar 24, 2019 10:47 pm

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.

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

Re: Climbing Man illusion (BBC BASIC)

Post by sweh » Sun Mar 24, 2019 10:52 pm

Rgds
Stephen

Post Reply