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.