https://bbcmic.ro/#%7B%22v%22%3A1%2C%22program%22%3A%22MODE1...
It would look even better with bidirectional error diffusion, but that requires reading back memory which I don't know how to do.
https://chat.openai.com/share/6e754fa1-531d-432e-a767-8c8132...
> VDU5: Sets the output to graphics.
Send a command to the visual display unit to turn off the flashing cursor.
> B=0: Initializes variable B to 0. This variable will be used for brightness calculations.
B is used to propagate quantization error from one pixel to the next - specifically, if we wanted one pixel to be orange, but the closest color we could use was red, then B contains "more yellow needed". In the next pixel, this will be added in to give this pixel more chance of being yellow.
> recursion
There is no recursion here. It's an infinite loop that exits when the raytraced ray fails to hit the floor or a sphere.
> The 4M and 4N are for scaling the coordinates to the screen resolution.
No - this is because early computers didn't have enough memory to store the whole screen image. Therefore there were 'device pixels' and 'logical pixels'. In this mode, each row of pixels is output 4 times into the screen, making each pixel into a group of 16 pixels (4x4).
Drawing commands in BBC basic are done in device pixels, but there is no point in figuring out a color for every device pixel if you can only store 1 in 16 of them..
Didn't check the inner loop since I didn't write that code - but I suspect it has similar accuracy issues.
Also tried having it generate a JavaScript version, but the output doesn't look right: https://chat.openai.com/share/5d76e32b-81a1-4b4a-a808-7682a8... I'd be inclined to suspect the lack of line numbers, as a first guess towards the problem.
Intel's optimization manual has suggestions for fast versions at 15.12.3 (recommended by @James https://stackoverflow.com/a/2637823/10981777) Don't look especially long to implement for 22-bit approximation.
https://software.intel.com/content/www/us/en/develop/downloa...
Also, what's the SQRD? Not finding that referred to anywhere.
Do enjoy the insane things ppl managed to cram into tweets to the bbcmicrobot over the years. Anyone who's followed any part of the demoscene especially the classic smaller payload demos.. 4k etc.....this kinda thing is mindblowing and totally in the same spirit.
IF V < 0 then P = (Y + 2)/V : V = -V*((INT(X - U*P) + INT(Z - W*P) AND 1)/2 + .3) + .2
then the (palette index of?) the color of the sky is computed from the square root of the y-coordinate of the direction vector as GCOL 0, 3 - (48*SQR V) DIV 16
plus a fixed dithering tableE.g. see:
W=1/SQR(U*U+V*V+1)
This makes a sphere. It gets multiplied by two coordinates to make spheres at different places, U and V.if you change the initialization of i from sgn u to 1.2 * sgn u you will get an image with the spheres a little further apart
i'm running this on a ryzen 5 3500u at 2400 megahertz. the acorn electron which supposedly takes 8 hours and 40 minutes is a 1 megahertz 6502 when running from ram, roughly, 262144 instructions per second. at 2 ipc one core of the ryzen should be about 4800 mips. if the emulation slowdown is 10× (10 host instructions to emulate one guest instruction), which is typical for naïve interpretation, it should be about 1000× faster on this laptop as on the original hardware
(possibly the basic is in rom and so it's closer to 524288 instructions per second)
emulation through qemu-like dynamic code generation should cut the 10× slowdown to 3×, so it should be 3000× faster than the original hardware
where did that factor of 1000 go? not the javascript engine, surely?
incidentally there is a rocket-ship button underneath the output screen image labeled 'send to beebjit' which runs the program in about a second
Consider that each chip of a home computer system (CPU, 1..2 IO/timer chips, audio, video, ...) needs to do 'emulation work' for each 1 or 2 MHz clock cycle which can add up to quite a number of host computer instructions (dozens to hundreds).
If each chip emulator just takes around 10..20 host system clock cycles to emulate one emulator clock cycle, then you are already looking at around 100 host system clock cycles per emulated clock cycle for the entire home computer (in reality it's probably worse).
Such 'vertically sliced' emulation code is also full of conditional branches which put a heavy burden on the host CPU branch predictor.
...and that's how a theoretical 1000x speedup suddenly becomes a 10x speedup, it's not the CPU emulation (this is usually cheap) but the rest of the emulated system which can be expensive.
Different emulators use all sorts of tricks and shortcuts, but usually with tradeoffs like less precise emulation, or less 'compartmentalized' code.
PS: case in point this is just the top-level per-cycle function in my C64 emulator, which in turn calls per-cycle-functions in each of the chip emulators (which may each be just as much code):
https://github.com/floooh/chips/blob/9a7f6d659b5d1bbf72bc8d0...
I'm trying to strike a balance between 'purity' (e.g. an entire emulated system can be 'plugged together' by wiring together chip emulators, just like one would build a real 8-bit computer on a breadboard), while still being fast enough to comfortably run in realtime even in browsers (https://floooh.github.io/tiny8bit/c64.html).
It's definitely possible to implement a faster cycle-correct C64 emulator with a less 'pure' architecture, but it's quite hard to do meaningful optimizations while keeping that same 'virtual breadboard' architecture.
...considering all the code that runs per cycle it's actually amazing how fast modern CPUs are :)
The Firefox profiler suggests it's spending most of its time doing nothing, waiting for the next Window.requestAnimationFrame.
Incredible raytraced demo in 256 bytes.
https://www.youtube.com/watch?v=36BPql6Nl_U
Incredible raytraced demo in 128 bytes. (An underwater journey through a Menger-sponge fractal)
then i looked and rrrola's 4is256 https://www.pouet.net/prod.php?which=29286 is a working tetris in under 256 bytes, and it's better than mine because it has colors and scoring. i could blame a little bit of inflation on arm being 32-bit rather than 16-bit, but not 4×
10 REMĀĘĆĞ$Č*Ēĉ!ăě-ĕ'ď
rem dithering table in comment above consulted by GCOL line?
rem raytracer from https://bbcmic.ro/?t=9ctpk by https://mastodon.me.uk/@coprolite9000
rem deobfuscated and possibly broken by kragen javier sitaker (untested)
20 MODE 1
VDU 5
30 FOR N = 8 TO 247 : rem loop over rows (n) and columns (m) of pixels
FOR M = 0 TO 319
40 X = 0 : rem three-dimensional vector
Y = -.1
Z = 3
U = (M - 159.5)/160 : rem xform screen coords to direction vector
V = (N - 127.5)/160
W = 1/SQR(U*U + V*V + 1) : rem normalize direction vector
U = U * W
V = V * W
I = SGN U : rem derive coordinate of sphere center (i, i, 1)?
G = 1
50 E = X - I : rem beginning of do-while loop
F = Y - I
P = U*E + V*F - W*Z
D = P*P - E*E - F*F - Z*Z + 1
IF D <= 0 then goto 60
T = -P - SQR D
IF T <= 0 then goto 60
X = X + T*U
Y = Y + T*V
Z = Z - T*W
E = X - I
F = Y - I
G = Z
P = 2*(U*E + V*F - W*G)
U = U - P*E
V = V - P*F
W = W + P*G
I = -I : rem if we are reflecting then check other sphere now
GOTO 50 : rem end of do-while loop, we have our escape from the scene geometry
rem color according to y-component of direction vector to get sky gradient
rem if instead y component is negative, make a checkerboard of pieces of sky
60 IF V < 0 then P = (Y + 2)/V : V = -V*((INT(X - U*P) + INT(Z - W*P) AND 1)/2 + .3) + .2
70 GCOL 0, 3 - (48*SQR V + ?(PAGE + 5 + M MOD 4 + N MOD 4*4)/3) DIV 16
80 PLOT 69, 4*M, 4*N
NEXT,
i'm interested to hear what i got wrongsee also https://news.ycombinator.com/item?id=39026517 and https://news.ycombinator.com/item?id=39026495
I'd maybe phrase this a bit differently – in both cases it uses the v coordinate to calculate the shade but whereas the sky is a simple gradient, the plane has a "ground fog" type effect that can be adjusted with those +.3 and +.2 magic constants.
In something like python, an analogous thing is turtle graphics. Is there something more similar (but still very basic) in python for something like this? A mini graphical language?
This is a small set of primitives around a tkinter canvas. I suppose one could expose a small set of primitives around a pygame too.
I have to think hard about what exactly I would want.
You don’t have a lot of memory to play with though as you only have 32k to start with and the frame buffer will use 20k of that, so I’m not sure how good a look up table you could make for SQR.
https://www.rustexplorer.com/b#Zm4gbWFpbigpIHsKICAgIC8vIHJvd...
If you just want to see the result, type MODE 1 and then press return, then type *LOAD SCREEN and press return again.