Rotozoom with tilt and experimental music in a valid 480bytes Atari bootsector.
This entry for Outline 2007 was really hard to pull, and I missed the deadline by one or two hours. On the other hand the result was beyond my expectations and the feedback was really positive.
Source code
;
; ##
; # # #######
; # # ## #
; ###### ### #
; ### # # #### #
; # ### # ### ##
; #### ## ## # #
; # # # # #
; #### # ####
; ## # ## #
; ## ### ## ####
; # #### # # #
; # #### ## # ###
; # ### # # # # #
; # # # ## # ##
; ####### ######
;
; Ooma 2 bootsector
;
; Mathieu 'P01' HENRI
; http://www.p01.org/
;
; released at
; Outline 2oo7
;
;
;
; Commented source code for Alive.
;
; Ooma2 was originally written in JavaScript.
; Therefore some parts, especially the precalc,
; could use more comments. Don't worry, the
; formulas are given in the C-like syntax.
;
; Technical trivia: X+Z rotozoom with "sample" replay
;
; Charly is still 16x16 2bpl => 16*4+4*2 = 72b
; The render area is 24x45 in 4x4 "chunky" = 96x180
; The channel A of YM21496 is updated 45 times per VBL
;
;
;___init______________________________________________
;
; clear interruptions
;
move.w #$2700,sr
;
; set the palette
;
lea sprite(pc),a2
move.w #$8240,a3
move.l (a2)+,(a3)+
move.l (a2)+,(a3)
not.w 26(a3)
;
; data start address
; = v_bas_ad
; - extendedSprite ( 16x16x16 )
; - sinusLut ( 1536*2 )
; - precalcUVdUdV ( 1024*45*2*4 )
;
move.l $44e.w,a1
suba.l #16*16*16+1536*2+1024*45*2*4,a1
;
; extend sprite
;
move.l a1,a6
moveq #16-1,d0
move.l d0,a5
extend_sprite:
move.l (a2)+,d2 ; pop a slice of Charly
moveq #16-1,d1
extend_sprite_process:
move.l d2,d3
andi.l #$10001,d3 ; grab the pixel in the LSB
move.l d3,d4 ; extend 4x
lsl.l #4,d3
sub.l d4,d3
move.l d3,(a1) ; push the 4x extended pixel
adda.w #16,a1
lsr.l #1,d2 ; right shift the slice
dbf d1,extend_sprite_process
dbf d0,extend_sprite
;
; generate sinusLut ( kudos to Ray/TSCC )
;
move.w #$4000,a5
move.w #512-1,d0
;
gen_loop:
move.w d0,d1
sub.w #256,d1
muls.w d1,d1
lsr.w #2,d1
sub.w a5,d1
move.w d1,512*2(a1)
neg.w d1
move.w d1,1024*2(a1)
move.w d1,(a1)+
dbf d0,gen_loop
;
; display the title
;
pea title(pc)
move.w #9,-(sp)
trap #1
addq.l #6,sp
;
; precalc UV & dUdV
;
move.l a1,a0
adda.w #1024*2,a0
move.l a0,a4
suba.w #512*2-128*2,a1
move.w #1024-1,d0
precalc_main:
;
; a0 = precalcUVdUdV
; a1 = sinusLut
;
not.w 26(a3)
moveq #45-1,d1
precalc_inner:
;
; the formula used for the U,V,dV,dV, with:
; w = 24
; h = 45
; x in the range [ 0, w-1 ]
; y in the range [ 0, h-1 ]
;
; p = h*(1-cos(an))/4/(h+y*cos(an+PI/4))
; dU = p*cos(an)
; dV = p*sin(an)
; U = -w/2*dU+(y-h/2)*dV-.5
; V = -w/2*dV-(y-h/2)*dU-.5
;
move.w 256(a1),d7
move.l a5,d2
sub.w d7,d2
moveq #45,d3
sub.w d1,d3
muls.w 768(a1),d3
lsl.l #2,d3
swap d3
ext d3
addi.w #45,d3
divs.w d3,d2
muls.w d2,d7 ; d7 = dV
move.l d7,d4
swap d4
move.l d2,d5
muls.w (a1),d5 ; d5 = dU
swap d5
move.w d5,d7
move.l d7,(a0)+ ; push dUdV
moveq #22,d2
sub.l d1,d2
moveq #11,d3
muls.w d4,d3
move.l d2,d6
muls.w d5,d6
sub.l d3,d6 ; d6 = U
swap d6
moveq #11,d7
muls.w d5,d7
muls.w d4,d2
sub.w d2,d7 ; d7 = V
move.w d7,d6
addi.l #$7f807f80,d6
move.l d6,(a0)+ ; push UV
dbf d1,precalc_inner
addq.l #2,a1
dbf d0,precalc_main
move.l a4,d7
;
; YM2149 init
;
move.w #$8800,a1
;
;__main_______________________________________________
ooma2_main:
;
; a0 = precalcUVdUdV
; a1 = YM2149
; a2 = screen
; a6 = extendedSprite
;
; stabilize low enough for the render loop to
; not cross the beam
;
cmp.b #$d0,$ffff8207.w
bne.s *-6
;
move.l $44e.w,a2
;
; effect loop ?
;
cmpa.l d7,a0
bne.s *+4
move.l a2,a0
;
; render!
;
moveq #45-1,d0
render_y:
; a5 = this row's UV
; a4 = this row's dUdV
move.l -(a0),a5
move.l -(a0),a4
moveq #6-1,d1
render_x:
; music
; Channel A rough|volume
move.w a5,d3
andi.w #$90d,d3
movep.w d3,(a1)
moveq #0,d3
moveq #4-1,d2
render_process_16px:
;
; mangle UV to point correctly in the
; extended sprite
;
move.l a5,d5
move.w d5,d4
andi.w #$0f00,d4
swap d5
lsr.w #4,d5
andi.b #$f0,d5
move.b d5,d4
;
; shift the 16px and push Charly's UV
; extended pixel
;
asl.l #4,d3
add.l (a6,d4),d3
; UV += dUdV
add.l a4,a5
dbf d2,render_process_16px
;
; output 16x4 pixels to the screen
;
move.l d3,160*10+80+160*0(a2)
move.l d3,160*10+80+160*1(a2)
move.l d3,160*10+80+160*2(a2)
move.l d3,160*10+80+160*3(a2)
addq.w #8,a2
dbf d1,render_x
adda.w #160*4-96/2,a2
dbf d0,render_y
;
; press [space] ?
;
cmpi.b #57,$fffffc02.w
bne ooma2_main
;__exit_______________________________________________
;
; mute all YM2149 channels
;
move.w #$7ff,d5
movep d5,(a1)
;
; reset the 4 first and the 15th colors and spare
; your retina by replacing the burning green by a
; gentle blue
;
clr.w 26(a3)
move.l #$03450770,-(a3)
move.l #$07770700,(a3)
;
; restore interruptions
;
move.w #$2300,sr
rts
;
;__data_______________________________________________
sprite
; Charly's sexy skin tones
dc.l $01010420,$06410762
;
; Hello Charly! long time no see
dc.l %00001000100001111110000001111000
dc.l %11011110100010100000000001110100
dc.l %00101000110101000110000000100100
dc.l %10001011011101010000001000000100
dc.l %11111001000010010000001001000100
dc.l %11111000100000110000000000011000
dc.l %11111111110101110000000000010000
dc.l %11101011111011110101110000000000
dc.l %11111111111111110101010000000000
dc.l %11101111111111110111010000000000
dc.l %11111111111110010000000000000001
dc.l %11011111001101010010000000000100
dc.l %01110010010101100000000011000010
dc.l %10110100000010110000010000000001
dc.l %11010001111000101100011101110001
dc.l %01010110100011100100000111110011
;
title
; title text + VT52 codes to position it
dc.b 27,"Y",32,52,"Ooma 2 p01"
dc.b 27,"Y",56,52,"Outline 2oo7",0
even
Feeback
Of course you can find Ooma 2 on Pouet
Other recent experiments
There are many experiments and projects like OOMA 2 to discover other here.
FRONTFEST MOSCOW It was an honour to be invited to Fronfest Moscow 2017 with the little family to give my first workshop; implementing a Twin-stick shooter using ES6 and Canvas, and to continue my CODE🎙ART series of talks + live coding aiming to inspire new web developer artists. on November 18th, 2017
VOLTRA VOLTRA: Grinding the Universe, a gritty JavaScript demo, winner of the 1024 bytes demo competition at the Assembly 2017. on August 6th, 2017
BREATHING EARTH Another take on Nadieh Bremer mesmerizing Breathing Earth visualisation, running at 60fps on a 2D Canvas without libraries or frameworks. on June 26th, 2017
DWITTER SON1K DWITTER—SON1K, the winning entry of JS1k 2017 is a social AudioVisual LIVE coding environment for the Twitter generation. on February 27th, 2017
LRNZ SNGLRT LRNZ SNGLRT is a minimalist and energetic entry for JS1k 2016 showing twisted Lorenz attractors with ambient occlusion, soft shadows, ... a strong beat & clean design. on March 13th, 2016
TINY AUDIO-VISUAL DEMOS AT JSCONF ASIA I had the honor to open the second day of JSConf Asia 2015 in Singapore with a talk and LIVE programming session about Tiny Audio-Visual Demos on November 20th, 2015
3D TOMB II 3D TOMB II: The tomb of the 4096 mummies is a first person shooter in a fully textured environment done in less than 4KB of JavaScript. on July 1st, 2007
STARFIELD A simple 3D starfield with title and fog in 256 bytes of Javascript on February 25th, 2007
Let's talk
Don't be shy; get in touch by mail, twitter, github, linkedin or pouet if you have any questions, feedback, speaking, workshop or performance opportunity.