Bloom 612 - Dreamcast 256 bytes

A 256-byte procedural graphics program for the
Sega Dreamcast video game
console, released at Lovebyte
2025.
Tested in Redream with v1.004, v1.01c and v1.01d
BIOS, does not seem to work on v1.022 though.
This is a SH-4 port of a
processing sketch i originally made in June 2024, all integers (3x
additive integer circle
algorithm progressively scaled up), it render a blooming
flower.
My journey on the Dreamcast began in
mid-2024, mainly motivated by the RISC CPU (2-way
Superscalar,), 640x480 resolution and 24-bit color
depth.
I never owned a Dreamcast myself (i did have a Sega
Saturn though !) but i was aware of its well-designed hardware
(Sega last console
breath !), it was pretty cool that Linux could run on it back in
early 2000 !
I don't think i had much difficulty on the port
except getting grips of the SH-4, it only use integers so doesn't
really use the powerful bits of the SH-4 (such as FSCA and FSRRA
instructions) but it was a good introduction, the original idea
was to add a cursive logo signature (with the 'O' of "Orz" being a
spiral; Dreamcast logo) but this sadly didn't fit. (wouldn't fit
the anonymous compo theme anyways !)
The Dreamcast is a powerful beast and can
probably deliver much more impressive graphics, it is a neat
alternative to x86 or ARM.
Name is a reference to The
Little Prince.
Chaos Rose was a
similar albeit 3D looking flower (different
algorithm) which was very cool to watch at previous
Lovebyte.
Variants
Here are some more images produced by the same algorithm, it
can produce many spiral looking graphics, the first ones were made
in June, some of these may have been interesting to show but also
added ~10 more instructions (especially the later ones) :

fractalesque

this one looked kinda cool

spiral and blobs

a quite rough sunflower (a try at additive
blending also)

another type of flower









Dreamcast SH-4 sources
! assume r2, r3, r7 are 0
mov #19,r1
shll16 r1
mov #23,r4
shll16 r4
mov #14,r5
shll16 r5
neg r1,r6
! clear screen
mov.l VIDEO_BASE,r12
mov.l VIDEO_DRAW_OFFSET,r0
shll r0 ! ~640*480*4
clr:
mov.l r2,@(r0,r12)
add #-3,r0
dt r0
bf clr
mov #-16,r13
mov.l r2,@(r0,r12)
mov.l VIDEO_DRAW_OFFSET,r0
add r0,r12
mov #-6,r14
mov #-7,r15
main:
mov r12,r8
shlr16 r8
iter:
mov r2,r11
shad r14,r11
add r11,r1
mov r1,r11
shad r14,r11
sub r11,r2
mov #12,r9
ia:
mov r4,r11
shad r14,r11
add r11,r3
mov r3,r11
shad r14,r11
sub r11,r4
dt r9
bf ia
mov #7,r10
ib:
mov r6,r11
shad r15,r11
add r11,r5
mov r5,r11
shad r15,r11
sub r11,r6
dt r10
bf ib
! px
mov r1,r9
add r3,r9
add r5,r9
shad r13,r9
! py
mov r2,r10
add r4,r10
add r6,r10
shad r13,r10
! compute index
mov #40,r11
shll2 r11
shll2 r11
mul.l r11,r10
sts macl,r10
add r9,r10
shll2 r10
! compute color
mov r7,r11
shll2 r11
add r11,r11
sub r7,r11 ! r11 * 7
mov #-4,r0
shad r0,r11
mov r8,r9
mov #-14,r0 ! -14 for a cleaner looks
shad r0,r9
add r9,r11
add #-127,r11
cmp/pz r11
bt positive
neg r11,r11
positive:
mov #-3,r0
mul.l r0,r11
sts macl,r11 ! * -3
mov #127,r9
shll r9
add #1,r9 ! 255
add r11,r9 ! r
add r11,r11 ! * 2
mov #48,r0
shll2 r0 ! 192
add r0,r11 ! g
cmp/pz r9
subc r0,r0
and r0,r9 ! max(r9, 0)
cmp/pz r11
subc r0,r0
and r0,r11 ! max(r11, 0)
add r12,r10
mov r11,r0
shll16 r9
shll8 r11
or r9,r11 ! RG
mov.l r11,@r10
add #4,r10
or r0,r11 ! RGG
mov.l r11,@r10
dt r8
bf iter
mov r1,r0
bsr scale
nop
add r0,r1
mov r2,r0
bsr scale
mov #2,r8
shll8 r8
add #16,r8
add #1,r7
cmp/hi r8,r7
el:
bt el
add r0,r2
bra main
scale:
mov #-10,r9
shad r9,r0
mov #5,r11
mul.l r11,r0
sts macl,r0
rts
.align 2
VIDEO_BASE: .long 0xa5200000
VIDEO_DRAW_OFFSET: .long (320 + (240 * 640)) *
4
p5.js prototype sources
let x0 = 19<<16
let y0 = 0
let x1 = 0
let y1 = 23<<16
let x2 = 14<<16
let y2 = -x0
function setup() {
createCanvas(640, 480)
background(0)
}
function draw() {
if (frameCount > 512) return
loadPixels()
for (let i = 42281; i >= 0; i -= 1) {
x0 += y0 >> 6
y0 -= x0 >> 6
for (let a = 0; a < 12; a += 1) {
x1 += y1 >> 6
y1 -= x1 >> 6
}
for (let a = 0; a < 7; a += 1) {
x2 += y2 >> 7
y2 -= x2 >> 7
}
let px = (x0 + x1 + x2) >> 16
let py = (y0 + y1 + y2) >> 16
let offset = (width / 2 + height / 2 * width) *
4
let index = offset + (px + (py * width)) * 4
let m = abs((((frameCount * 7) >> 4) + (i
>> 14)) - 127) * -3
let r = 255 + m
let g = 192 + m * 2
// only needed on HW
//r = ~(r >> 31) & r
//g = ~(g >> 31) & g
pixels[index + 0] = r
pixels[index + 1] = g
pixels[index + 2] = 0
// cover gaps (smoother) + blend colors
pixels[index + 0 + 4] = r
pixels[index + 1 + 4] = g
pixels[index + 2 + 4] = g
}
x0 += 5 * (x0 >> 10)
y0 += 5 * (y0 >> 10)
updatePixels()
}
back to top


