Amiga Works  <  AlienSCApe  (2024-06-06)

Joystick Port 2:
Cursor-keys to move, Shift to fire
Name: AlienSCApe
Type: 256 Byte Demo
Date: 2024-06-06
Coder: Saturnus the Invincible
Disk: disks/AlienSCApe.adf
Source: AlienSCApe.asm
Info: A musical journey to the stars, inspired by the iconic 1977 movie "Close encounters of the Third Kind". Plays the Five Tones in various pitches and speeds.
Instructions: Click the speaker icon to enable sound, set your volume to 11 and close your eyes.
Youtube: https://www.youtube.com/watch?v=wZj7gUIO-2k
Note: The strange vibrato and background noise is because of the crappy audio rendering of this Javascript Amiga emulator, sorry!

********************************************************************************
* AlienSCApe: A musical journey in 256 bytes. Coded by Saturnus the Invincible *
* The Mega-Mighty Swiss Cracking Association - reaching out to you! 2024-06-06 *
********************************************************************************

		SECTION	text,CODE_C			; wave needs CHIP mem

                include "hardware/custom.i"
                include "hardware/intbits.i"
                include "hardware/dmabits.i"

_custom		equ	$dff000				; no audio.device ;-)


; these regs hold one byte per voice (conveniently, 4 bytes for 4 voices):
; D7: volume (63..0)
; D6: fadeout timer, d6 and d5 implement a logarithmicish fadeout curve
; D5: fadeout timer decrement timer initial value
;
; these regs are used normally:
; D4: note timer
; D3: speed of current 5-tone-sequence (global)
; D2: voice counter (3..0)
; D1: octave (0..3)
; A1: points to current position within melody

_main:		lea	_custom+aud,a5			; aud saves 2 bytes

		move.w	#INTF_INTEN,intena-aud(a5)	; disable()
		move.w	dmaconr-aud(a5),-(SP)		; save dmacon for later
		move.w	#$7fff,dmacon-aud(a5)		; turn all dma off

		moveq	#3,d2				; 4 voices
		movea.l	a5,a0				; 1st voice
		lea	wave(pc),a2
.initloop:	move.l	a2,(a0)+			; ac_ptr
		move.w	#(wave_end-wave)/2,(a0)		; ac_len (words)
		lea	ac_SIZEOF-4(a0),a0		; next channel
		dbf	d2,.initloop

		move.w	#DMAF_SETCLR|DMAF_MASTER|DMAF_AUDIO,dmacon-aud(a5)

		movea.l	a5,a0				; 1st voice
		moveq	#3,d2				; 4 voices
		moveq	#1,d4				; reset note timer
	;;;	moveq	#0,d7				; not needed, save space

	; start the song from the beginning

.initsong:	lea	five_tones(pc),a1
		lsl.w	#3,d4				; 8x delay after last note
		moveq	#64,d3				; minimal speed: 64
		or.b	vhposr-aud(a5),d3		; rand(64..255)
		move.b	d3,d1
		neg.b	d1				; neg to get long low notes
		lsr.b	#6,d1				; use bits 7 and 5 (6 is always set)
		bcc.b	.1				; bit 5 is now in carry
		addq.b	#1,d1				; bit 5 was set: set bit 0 in d1
.1:		bra.b	.noplay				; keep last note playing

	; envelope generator

.loop:		movea.l	a5,a0				; 1st voice
		moveq	#3,d2				; 4 voices

.voiceloop:	moveq	#0,d0
		move.b 	d7,d0				; current volume
		move.w	d0,ac_vol(a0)
		beq.b	.nofade				; silent --> done
		subq.b	#1,d6				; decrement fadeout timer
		bne.b	.nofade				; not time yet --> done
		subq.b	#1,d7				; fade volume down
		move.b	d5,d6				; restart fadeout timer
		lsr.b	#3,d6				; convert fixed to int
		addq.b	#1,d5				; inc timer start for smooth fadeout
.nofade:
		subq.w	#1,d4				; decrement note timer
		bne.b	.noplay				; not time yet -->

		move.w	d3,d4				; restart note timer
		move.w	(a1)+,d0			; next note from five_tones
		beq.b	.initsong			; five_tones done -->

		lsr.w	d1,d0				; calculate octave shift
		move.w	d0,ac_per(a0)
		move.b	#15,d5				; init fade timer timer (5.3 fixed)
		move.b	#1,d6				; init fade timer
		move.b	#63,d7				; set initial volume
.noplay:
		lea	ac_SIZEOF(a0),a0
		ror.l	#8,d7				; next voice's volume
		ror.l	#8,d6				; next voice's fade timer
		ror.l	#8,d5				; next voice'a fade timer timer
		dbf	d2,.voiceloop

		move.l	d7,d0
		lsr.l	#2,d0				; volume 63..0 --> brightness 15..0
		lsl.b	#4,d0				; 000r0gb0
		lsl.w	#4,d0				; 000rgb00
		lsr.l	#8,d0				; 00000rgb
		move.w	d0,color-aud(a5)		; volumes of 3 voices as r/g/b

	; delay for 5 ms so a full speed volume fade takes 5*64 = 320 ms

		moveq	#4800/64,d0			; number of lines to wait
.delay:		move.b	vhposr-aud(a5),d2		; vpos
.waitline:	cmp.b	vhposr-aud(a5),d2
		beq.b	.waitline
		dbf	d0,.delay

	; so many bytes left, might as well nicely exit to OS after left mouse button press

		btst	#6,$bfe001
		bne.b	.loop

.done:		move.w	#DMAF_AUDIO,dmacon-aud(a5)	; turn off audio DMA
		bset	#7,(SP)				; set DMAF_SETCLR
		move.w	(SP)+,dmacon-aud(a5)		; restore dmacon

		moveq	#0,d0				; CLI return code
		rts
		
wave:		dc.b	127,-127			; our patented wave with lots of harmonics
wave_end:

five_tones:	dc.w	15043,13401,16885,33769,22538,0	; ®ipped from movie by STI\SCA !!!

		END