pouët.net

Go to bottom

Polar Beat by Řrřola [web]

;             o       .
; o888. .o8o. 8     .88   88o.
; 8K  8 8"  8 8    .8 8  .8 "8
; "8o8" 8.  8 8   .8__8  88oK"
;  "8.  "8o8" 888 8"""8 o8 "8
;   "8                      8
;      88o.         ..oo88
;     .8 "8 oooo 88."""8
;     88oK".8__  8 8.  8.
;    o8 "o 8"""  8__8. "8
;     "8o" 8oooo 8"""8  8
;
;  a 256-byte intro by Řrřola
;      <rrrola@gmail.com>
;      Greets to everyone
;    who likes polar bears!

org 100h ; assume ax=bx=0 ch=0 si=0x100 sp=di=-2 cs<=0x2f54

;execute a few harmless floats
C5div6 equ $-2
  db 0x54,0x3f  ; 5/6           ; push sp; aas
C3_5 equ $-2 ;=[si]
  db 0x5f,0x40  ; 3.5           ; pop di; inc ax
C4_5 equ $-2
  db 0x90,0x40  ; 4.5           ; nop; inc ax
C2PIdiv6 equ $-2
  db 0x85,0x3f  ; 2π/6 ≈ 1.047  ; test [bx],di

;init
  xchg ax,cx  ; cx=2: tick (goes up), miss first beat
  mov fs,[si] ; backbuffer for postprocessing = 0x3f54
  mov al,13h
  int 10h     ; 320x200 mode, default palette
  mov bp,0xa000-70-6
  mov es,bp   ; aligned screen

;main loop = pixel loop
X mov ax,0xcccd
  mul di  ;)
  add dx,bp
  push dx ; +2 bytes: X with full precision
  pusha   ; stack: [... -6-5-4]
          ;         cx  ax  dx
          ;         TTTT    YYYY
          ;               XXXX

;polar coordinates the hacky way
;assume cos(angle) isn't 0 anywhere on screen
  fild word[bx-4]
  fild word[bx-5]
  fld st1        ; y x y
  fpatan         ; a=atan(x/y) y  ; -π..π, 0=vertical
  fld st0        ; a a y
  fcos           ; cos(a) a y
  fimul word[byte si-100h+C295]
  fdivp st2,st0  ; a r=y/(-295*cos(a))  ; r=√(x²+y²)

;base color: 24 = 3*8 rainbow shades
  ;mov ax,7*256 + 32+24+24+24+24+19
  ;and ah,ch
  ;aad 3 ; al += 3*ah  ; aad is slow to emulate
  mov al,ch  ; +2 bytes: faster
  and al,7
  lea ax,[byte eax + 2*eax + 32+24+24+24+24+19]

;pick one of 8 formulas based on tick/256
  shl ch,6  ; 00000uvw -> flags: cf=u sf=v pf=v^w
  jnc A     ; fpu instructions don't touch flags

;Clover: 3.5 / (3.5 - cos(4.5 sin(2a)));
C jnp G
  fadd st0        ; 2a r
  jns D
C295:
  fsin

;Flower / Butterfly: 3.5 / (3.5 + f(cos(4.5 a)))
G fmul dword[byte si-100h+C4_5]
  fcos
  fchs   ; Butterfly (4.5 points): f(x) = -x
  js I
  fabs   ; Flower (9 points): f(x) = |x|
  jmp I

;Gear: 3.5 / (3.5 + sin(cos(7a) + π/4))  ; 7 mod 2π ≈ π/4
B fmul dword[si]  ; Gear (7 points)
  jns F           ; Sun (22 points)  ; π ≈ 22/7
  fadd st0
  fcos
  fadd dword[si]  ; "fabs" will be a no-op

;Heart: 3.5 / (3.5 + sin(|2a| + 3.5))
D fabs            ; |2a| r
  fadd dword[si]
  fsin            ; s=sin(|2a|+3.5) r
I fadd dword[si]
  fdivr dword[si] ; 3.5/(3.5+s) r
  jmp J

;Hexagon / Star / Sun (or circular saw)
A jnp B           ; a/h r  ; h = 2π/6
  fdiv dword[byte si-100h+C2PIdiv6]
  jns F           ; Star: 5 points instead of 6
  fmul dword[byte si-100h+C5div6]
F fist word[bp+si]; Sun
  fisub word[bp+si]; fract(a/h)-0.5 r
  jns E
  fadd st0        ; Star or sun: more pointy
E fmul dword[byte si-100h+C2PIdiv6]
  fcos            ; cos(h*(fract(a/h)-0.5)) r

J fmulp           ; modulate radius
P fistp word[bp+si]
  xor cl,16       ; 16 ticks: jump to the beat
  add cl,[bp+si]
  shr cl,6        ; cf = (tick + round(modded radius)) >> 5
  jnc Q
  add al,72       ; background color

;shading: top/left bevel
Q mov bh,-5       ; -1280 = -320*4: 4px tall, 5px wide
  mov [fs:di],al
Y cmp al,[fs:di+bx]
  jae Z           ; compare with top or left pixel
  sub al,48       ; bevel color (-48 or -96)
Z sar bx,8        ; -1280/256 = -5
  jnp Y

;draw pixel, loop
  stosb
  popa
  pop dx
  inc di
M jnz X  ; trampoline to make a jump shorter

;vsync
  mov dx,0x3da
V in al,dx
  test al,8
  jz V

;music
  pusha
  mov ah,ch     ; for melody
  mov bl,cl     ; for bass  ; bh=0
  and cx,7
  jnz S         ; play every 8 ticks

  mov si,MIDI   ; assume UART mode
  mov dl,0x30   ; send to MIDI data port: dx=0x330
  mov cl,9  ; ch=0 from "and"
  xor byte[si+6],36^42  ; flip bass drum <-> closed hi-hat
  rep outsb

;bass: pick from a table, flip ±32 (bass or low drone)
  shr bx,5
  xor byte[bx+si+5],32
  mov al,[bx+si+5]
  out dx,al
  outsb

;melody: loop the same 8 notes, gradually make louder
  ror dword[si],4
  lodsb
  and al,0xf
  add al,32+24
  out dx,al
  shr ax,4
  out dx,al

S popa
  inc cx    ; tick++
  
  in al,60h ; esc check
  cmp al,1
  jnz M

MIDI:
  ret ; 0xc3 = ch4 instrument change

  db       81       ; ch4: change to saw wave
  db 0xb3, 123, 0   ; ch4: all notes off
  db 0x99, 36, 0x7f ; play bass drum or closed hi-hat
  db 0x93,     0x7f ; play notes; bass velocity

  dd 0x8507587F     ; 4-bit melody
  db 0x20,0x21,0x21,0x21,0x25,0x25,0x23,0x23  ; bass
Go to top