Last month we carried a program allowing images to be wrapped around a sphere. This was accomplished in Basic, and a sequence of sprites was created, permitting subsequent animation. This month we feature two image wrapping programs which run in real time. Both will wrap any mode 12 or 13 image. The first wraps the image around a sphere, which spins at a speed determined by the position of the mouse. The second wraps the image around a horizontal cylinder, whose speed of rotation is again mouse-controlled. The cylinder is open ended, and you can see the image wrapped onto its inner as well as its outer surface.
Both programs are relatively short, considering the work which they perform, and both use fully legal screen addressing code. Before running either of them, you will need an appropriate screen called "Screen" (previously saved using *ScreenSave Screen) in the current directory of your disc. The only thing to watch is that you will need 240K of screen RAM (use *Configure ScreenSize 30 on a 300 series machine). The reason for this is that three 80K screen banks are needed: one to hold the loaded screen, and two for bank switching to achieve smooth animation.
When you run the cylinder program, you can use the mouse to determine the width of the displayed cylinder. You will see two vertical bars on the screen. These represent the left and right edges of the cylinder. Moving the mouse will alter the left hand bar, while the right hand bar may be moved by pressing Select or Adjust. When you are happy with the size, press Menu, and the cylinder will appear.
Notes
1. Both programs use a look-up table created in Basic to calculate the pixel positions of the wrapped image. In the case of the first program the table contains two words for every pixel that makes up the globe. The first specifies where to get the pixel from, and the second where to put the pixel. The table is a massive 170K in size, and takes some 10 seconds to generate before the image wrap can proceed. There is no noticeable delay with the cylinder program.
2. For an interesting effect, try altering line 600 of the first program to:
H%=320*(offset%>>3 AND 255)+X% DIV 4
3. The appearance of the tube in the second program can be altered by adjusting the values of the two variables in line 500. They determine the horizontal (H%) and vertical (V%) radius (in pixels) of the mouth of the tube. If H% is negative, then the mouth of the tube appears at the left instead of the right. Note also that you should keep V% to 43 or less.
10 REM >Global
10 REM >Tubular
20 REM Program Rotating screen
30 REM Version A 1.00
40 REM Author Mike Ironmonger
50 REM RISC User April 1989
60 REM Program Subject To Copyright
70 :
80 ON ERROR MODE0:PRINT REPORT$;" at line ";ERL:END
90 MODE0:DIM code% 2000,addr%(3)
100 :
110 FORA%=0TO1:P%=code%
120 [OPT A%*2
130 ADR R8,table
140 MOV R9,#256
150 .next_line
160 LDR R0,[R8],#4
170 TEQ R0,#0
180 BEQ no_line
190 ADD R10,R7,R5
200 ADD R11,R0,R6
210 MOV R3,R4
220 .next_byte
230 LDRB R0,[R10],#1
240 STRB R0,[R11],#1
250 SUBS R3,R3,#2
260 LDRNEB R0,[R10],#1
270 STRNEB R0,[R11],#1
280 BPL next_byte
290 .no_line
300 SUBS R5,R5,#320
310 ADDMI R5,R5,#81920
320 SUBS R9,R9,#1
330 BNE next_line
340 MOV PC,R14
350 :
360 .list EQUD150:EQUD-1:EQUD0
370 .table
380 ]:NEXT
390 :
400 SYS "OS_ReadVduVariables",list,list+8
410 IF list!8<240*1024 PRINT"240K of screen memory required":END
420 *ScreenLoad Screen
430 OFF:IF MODE<>12 AND MODE<>13 PRINT"MODE 10,12,13 only":END
440 :
450 !list=148:FOR A%=3 TO 1 STEP-1
460 SYS "OS_Byte",112,A%:IF A%>1 CLS
470 SYS "OS_ReadVduVariables",list,list+8
480 addr%(A%)=list!8:NEXT
490 :
500 H%=32:V%=43
510 FOR A=0 TO PI*2 STEP PI/128
520 OA%=A%:X%=H%*SIN(A)+.5:Y%=V%*COS(A)+.5
530 A%=Y%*320-X%:!P%=A%*(A%<>OA%)
540 P%+=4:NEXT
550 :
560 GCOL 3,1:MOUSE TO 480,0
570 OX%=480:OW%=316:PROCrec
580 REPEAT
590 W%=OW%+4*(B%=4 AND OW%>4)-4*(B%=1
AND OW%<1280-8*ABS(H%))
600 MOUSE RECTANGLE 0,0,1276-W%,0
610 MOUSE X%,Y%,B%
620 WAIT:PROCrec:OX%=X%:OW%=W%:PROCrec
630 UNTIL B%=2:PROCrec
640 :
650 *Pointer
660 MOUSE TO 640,512
670 E%=OW%/4:H%=addr%(1)+OX%/4
680 addr%()+=(159-OW%/8+320*127)
690 offset%=0:bank%=2:*FX 113,3
700 REPEAT
710 MOUSE X%,Y%,B%
720 offset%+=Y%DIV4-128
730 F%=320*(offset%>>3 AND 255)
740 G%=addr%(bank%):CALL code%
750 WAIT:SYS "OS_Byte",113,bank% TO ,bank%
760 UNTIL FALSE
770 :
780 DEFPROCrec
790 RECTANGLE OX%,-4,OW%,1028
800 ENDPROC
20 REM Program Spinning globe
30 REM Version A 2.00
40 REM Author Mike Ironmonger
50 REM RISC User April 1989
60 REM Program Subject to copyright
70 :
80 ON ERROR MODE0:REPORT:PRINT" at line " ;ERL:END
90 :
100 DIM screen%(3),sin(128)
110 DIM code% 1000,table% 21736*8
120 :
130 FOR A%=0 TO 1:P%=code%
140 [OPT A%*2
150 LDR R8,pixs
160 ADR R9,table%
170 .next_block
180 ]
190 FOR B%=1 TO 19
200 [OPT A%*2
210 LDMIA R9!,{R1-R4}
220 SUBS R1,R1,R7
230 ADDMI R1,R1,#81920
240 LDRB R0,[R5,R1]
250 STRB R0,[R6,R2]
260 SUBS R3,R3,R7
270 ADDMI R3,R3,#81920
280 LDRB R0,[R5,R3]
290 STRB R0,[R6,R4]
300 ]:NEXT
310 :
320 [OPT A%*2
330 SUBS R8,R8,#38
340 BNE next_block
350 MOV PC,R14
360 .pixs EQUD 21736
370 .in EQUD 150:EQUD -1
380 .out EQUD 0
390 ]:NEXT
400 :
410 SYS "OS_ReadVduVariables",in,out
420 IF !out<&3C000 PRINT"Program requires 240K of screen memory":END
430 *ScreenLoad Screen
440 IF MODE<>12 AND MODE<>13 PRINT"MODE 12 or 13 only":END
450 !in=148:FOR A%=1 TO 3
460 SYS "OS_Byte",112,A%:IF A%>1 CLS
470 SYS "OS_ReadVduVariables",in,out
480 screen%(A%)=!out
490 NEXT:OFF
500 :
510 PROCcreate_table
520 *FX 113,3
530 *Pointer
540 MOUSE TO 640,512
550 F%=screen%(1):offset%=0:bank%=2
560 REPEAT
570 MOUSE X%,Y%,B%
580 offset%+=128-Y%DIV4
590 G%=screen%(bank%)
600 H%=320*(offset%>>3 AND 255)
610 CALL code%
620 WAIT:SYS "OS_Byte",113,bank% TO ,bank%
630 UNTIL FALSE
640 :
650 DEFPROCcreate_table
660 A%=0:FOR A=0 TO PI/2 STEP PI/256
670 sin(A%)=SINA:A%+=1:NEXT
680 R%=83:OX%=1:x%=0:T%=table%
690 FORX=0 TO PI/2 STEP PI/320
700 X%=.5+R%*SINX:IF X%<>OX% PROCline
710 x%+=1:NEXT
720 ENDPROC
730 :
740 DEFPROCline
750 H%=R%*COSX:OX%=X%:OY%=1
760 FOR A%=0 TO 127:Y%=H%*sin(A%)
770 IF Y%<>OY% PROCpix
780 NEXT:ENDPROC
790 :
800 DEFPROCpix
810 T%!0=41120+A%*320+x%
820 T%!4=41120+Y%*320+X%
830 T%!8=41119+A%*320-x%
840 T%!12=41119+Y%*320-X%
850 T%!16=40800-A%*320+x%
860 T%!20=40800-Y%*320+X%
870 T%!24=40799-A%*320-x%
880 T%!28=40799-Y%*320-X%
890 OY%=Y%:T%+=32
900 ENDPROC