To my considerable surprise (and after a lot of experimentation) I discovered that there is indeed a fast way of displaying the grid in RISC OS, using
. Having never written a single program for RISC OS previously, achieving this was quite a steep learning curve.
So here I present the ultimate Conway's Game of Life in pure BASIC 5 on RISC OS, using most of the tricks I was able to deploy in the BBCSDL/BB4W version (only 'byte' arrays not being available)! This does need HIMEM set at least 10 Mbytes or so above PAGE, so may need to be run in a non-GUI environment (I'm booting straight into BASIC on Red Squirrel):
Code: Select all
10 REM Conway's 'Game of Life' in pure BASIC 5 (with some cheating!)
20 REM By Richard Russell, http://www.bbcbasic.co.uk/, 17-Jan-2021
30
40 REM Set grid size and initialise screen:
50 W% = 512 : H% = 512
60 MODE 18
70 OFF
80
90 REM Define sprite and main grid:
100 DIM sparea% 15 + 12, sprite% 43, G% -1, g%(H%-1,W%-1), T% 3
110
120 sprite%!0 = T% - sprite% : REM Total size of sprite
130 $(sprite%+4) = "Game of Life"
140 sprite%!16 = W% - 1 : REM Sprite width in words, - 1
150 sprite%!20 = H% - 1 : REM Sprite height in pixels, - 1
160 sprite%!28 = 31 : REM Last bit on right edge
170 sprite%!32 = G% - sprite% + 24 : REM Offset to sprite image
180 sprite%!36 = 44 : REM Offset to sprite mask (none)
190 sprite%!40 = &B01680B5 : REM Sprite type 6, DPI = 90 x 90
200
210 sparea%!0 = T% - sparea%
220 sparea%!4 = 1
230 sparea%!8 = sprite% - sparea%
240 sparea%!12 = T% - sparea%
250
260 DIM table% 11
270 SYS "ColourTrans_GenerateTable", sparea%, sprite%, 18, -1, table%, 1, 0, 0
280
290 REM Initialise the grid to a random state:
300 FOR Y% = 0 TO H%-1
310 FOR X% = 0 TO W%-1
320 IF RND(2) = 2 g%(Y%,X%) = TRUE
330 NEXT
340 NEXT
350
360 REM Create 8 copy arrays with gaps:
370 G% = W% * 8 + 8
380 DIM K% -1, k%(H%-1,W%-1), L% G%, L% -1, l%(H%-1,W%-1), M% G%
390 DIM M% -1, m%(H%-1,W%-1), N% G%, N% -1, n%(H%-1,W%-1), O% G%
400 DIM O% -1, o%(H%-1,W%-1), P% G%, P% -1, p%(H%-1,W%-1), Q% G%
410 DIM Q% -1, q%(H%-1,W%-1), R% G%, R% -1, r%(H%-1,W%-1), S% G%
420
430 REM Do some evil descriptor hacking to offset the arrays:
440 PROCoffset(K%,W%+1) : PROCoffset(L%,W%+1) : PROCoffset(M%,W%+1) : PROCoffset(N%,W%+1)
450 PROCoffset(O%,W%+1) : PROCoffset(P%,W%+1) : PROCoffset(Q%,W%+1) : PROCoffset(R%,W%+1)
460
470 REM Repeat for each generation:
480 REPEAT
490 REM Display grid:
500 SYS "OS_SpriteOp", 52+512, sparea%, sprite%, 0, 0, 0, 0, table%
510
520 REM Make 8 copies of grid, converting -1 to 1:
530 k%() = -g%() : l%() = -g%() : m%() = -g%() : n%() = -g%()
540 o%() = -g%() : p%() = -g%() : q%() = -g%() : r%() = -g%()
550
560 REM Offset arrays:
570 PROCoffset(K%,-W%-1) : PROCoffset(L%,-W%) : PROCoffset(M%,-W%+1)
580 PROCoffset(N%,-1) : PROCoffset(O%,+1)
590 PROCoffset(P%,+W%-1) : PROCoffset(Q%,+W%) : PROCoffset(R%,+W%+1)
600
610 REM Sum the border cells:
620 k%() = k%() + l%() : m%() = m%() + n%() : o%() = o%() + p%() : q%() = q%() + r%()
630 k%() = k%() + m%() : o%() = o%() + q%() : k%() = k%() + o%()
640
650 REM Calculate next state:
660 k%() = k%() + k%() : p%() = k%() - g%() : p%() += 8 : q%() = p%() + 3
670 p%() = p%() / 16 : q%() = q%() / 16 : g%() = p%() - q%()
680
690 REM Undo the offsets:
700 PROCoffset(K%,+W%+1) : PROCoffset(L%,+W%) : PROCoffset(M%,+W%-1)
710 PROCoffset(N%,+1) : PROCoffset(O%,-1)
720 PROCoffset(P%,-W%+1) : PROCoffset(Q%,-W%) : PROCoffset(R%,-W%-1)
730
740 UNTIL FALSE
750 END
760
770 REM This is non-portable code:
780 DEF PROCoffset(A%, O%)
790 LOCAL I%, P%, W%, H%
800 P% = A%!8 : W% = P%!0 : H% = P%!4
810 IF O% < 0 FOR I% = P% + O%*4 + 16 TO P% + 12 STEP 4 : !I% = 0 : NEXT
820 IF O% > 0 FOR I% = P% + W%*H%*4 + 16 TO P% + W%*H%*4 + O%*4 + 12 STEP 4 : !I% = 0 : NEXT
830 P% += O%*4 : A%!8 = P%
840 P%!0 = W% : P%!4 = H% : P%!8 = 0 : P%!12 = W%*H%
850 ENDPROC