Moirisc - RISC OS 256 bytes
640x480 version
Second Acorn
Archimedes / RISC OS intro with two versions :
- mode 13 320x256 256 colors for Acorn Archimedes
- mode 28 640x480 256 colors for VGA monitors which was shown at the party (running on a Raspberry PI Zero)
This is a follow-up of Acetaminophen
with buffers / precomputation and it works best on ARM3 again but
also okaish on ARM2, require ARM2 12MHz and MEMC1a at 16MHz to be
smooth.
Mainly wanted to see if a buffered version could be done at
256 bytes since it is much prettier / faster than some widened
circles (it is also more technically akin to the classic effect as
seen in many demos), the main disadvantage is RAM usage and long
precalc time. (more than 60 seconds on 1987 ARM2 !)
This use Minsky circle for the animation again (oscillation),
a 512x512 (1024x1024 for mode 28) buffer containing centered
circles is precomputed, circles are generated per pixels using a
short integer SQRT approximation, the draw loop just fetch buffer
pixels two times with different offset, the values are then mixed
with logical operators and the result is drawn onto the
frame-buffer.
There is actually 4 buffers generated, each buffers is shifted
in X by a single pixel, this is needed because of the lookup / draw
instruction alignment requirements (each fetch / write needs to be
aligned to a word boundary) otherwise graphics glitch appears, the
correct buffer is then selected prior the draw loop.
The draw loop use blocks copy instruction to lookup / copy 16
pixels per iteration so it is pretty fast, could be faster by using
more registers but this also induce more instructions.
320x256 version
Due to the buffers the program require around 1056k free RAM,
double for mode 28, this must be allocated with the RISC OS
Task manager ("Next") prior launch.
Could use a low colors mode to be smooth and not having to
allocate RAM on 1987 Acorn Archimedes (A30x) but this induce
alignment issues which must be fixed with some more instructions,
perhaps it is doable at 256 bytes without compromises.
I actually had bit of troubles to fit it all in 256 bytes, one
of the last minute cheap trick i used was to comment out the
"OS_RemoveCursors" API call so the blinking cursor is visible... it
is almost imperceptible due to what is going on screen
anyway.
CodePressor
(ARM code compressor) actually doesn't help on this one and makes
the executable binary larger.
The same algorithm could be used for checkered pseudo 3D
layers perhaps and other effects by generating different buffer
content.
the ARM code for the RPI version (i use BBC
BASIC assembler)
Roughly similar effect with JS code (prototype)
// classic interference effect done per
pixels with short integer sqrt approx.
function sqr(n) {
let b = 0
while (n >= 0) {
n -= b
b += 1
//n -= b
}
return b// - 1
}
function setup() {
createCanvas(256, 256)
}
let mx = 92
let my = 0
function draw() {
background(0)
mx += (my >> 5)
my -= (mx >> 5)
loadPixels()
for (let y = 0; y < height; y += 1) {
for (let x = 0; x < width; x += 1) {
let c = 0
for (let i = 0; i < 2; i += 1)
{
let cx = mx
let cy = my
if (i == 0) {
let ct =
cx
cx = cy
cy = ct
}
let xx = abs((x + cx) /
width - 0.5) * 2 * width / 12
let yy = abs((y + cy) /
height - 0.5) * 2 * height / 12
let sc = sqr(xx * xx +
yy * yy)
c ^= (sc & 7) * 32
}
c = 255 - c
let px = x
let py = y
if (px < 0 || px >= width ||
py < 0 || py >= height) continue
let index = (px + py * width) *
4
pixels[index + 0] += c
pixels[index + 1] += c
pixels[index + 2] += c
}
}
updatePixels()
}
JavaScript prototype
early and bit buggy (lack of alignment ?) 4
colors version
some other Moiré effects could be made without
cost by using different patterns (perhaps even fake plasma by
adjusting the
palette in real-time), here using inverted 1/4 patches of the
original image
Speed optimizations
For demos with no size limitations the pre-computation can be
done quicker by exploiting symmetry, just generate 1/4 of the image
and copy/paste the rest.
back to top