
*****************************************************************************
*
*  ROMBO Productions -- Vidi-Amiga Double-Buffered Grab in Assembler
*
*****************************************************************************
*
*  Details:
*
*	Vidi-Amiga:Vidi/Examples/DBuffer.asm
*	written using HiSoft Devpac Amiga assembler v2.13
*	version 1.13, as of Thursday 18th January 1990
*	by Keith Wilson, Rombo
*
*****************************************************************************

* you'll need to specify your own directories for these...

	INCDIR	INCLUDE:
	INCDIR	Vidi-Amiga/Vidi/Include/

	INCLUDE	exec/exec_lib.i
	INCLUDE	intuition/intuition_lib.i
	INCLUDE	intuition/intuition.i

	INCLUDE	vidi_lib.i
	INCLUDE	vidibase.i



* Call library without the _LVO, optionally loading A6 with base pointer
* (I prefer using this to any of the standard Commodore macros)

CALLSYS	macro	* library routine [,base pointer]
	iif	NARG=2 move.l \2,a6
	jsr	_LVO\1(a6)
	endm



* Setup libraries, BitMaps, etc.

_main
	lea	vidiName,a1		; vidi.library
	CALLSYS	OldOpenLibrary,_SysBase	; open it
	move.l	d0,_VidiBase		; and store base addr
	beq	FailedVidi		; bail out if error
	move.l	d0,a6			; copy library base
	move.l	vb_IntBase(a6),_IntBase	; steal intuition base

	move.w	#VIDI_PAL,d0		; change to 0 for non-PAL
	CALLSYS	OwnVidi			; claim Vidi resource
	tst.l	d0			; error?
	bne	FailedOpen		; exit if so
	CALLSYS	SyncTest		; test sync type


	moveq	#0,d0			; no flags
	move.w	#320,d1			; lo-res width
	move.w	#256,d2			; PAL height
	moveq	#4,d3			; 16-colour BitMap
	CALLSYS	AllocBitMap		; then allocate frame
	move.l	d0,bitMap2		; and store address
	beq	FailedBitMap2		; exit if error

	moveq	#0,d0			; same again...
	move.w	#320,d1
	move.w	#256,d2
	moveq	#4,d3
	CALLSYS	AllocBitMap
	move.l	d0,bitMap1
	beq	FailedBitMap1


	move.l	d0,a0			; copy bitmap addr
	moveq	#0,d0			; normal viewModes
	move.l	d0,a1			; no title
	move.l	d0,a2			; default font
	moveq	#14,d1			; detail pen 14
	moveq	#6,d2			; block pen 6
	CALLSYS	EasyScreen		; open screen
	move.l	d0,screen		; and store handle
	beq	FailedScreen		; exit if error

	lea	newWindow,a0		; new window structure
	CALLSYS	OpenWindow,_IntBase	; open it
	move.l	d0,window		; and store handle
	beq	FailedWindow		; exit if error


* main loop

	movem.l	bitMap1,a4/a5		; A4/A5 point to BitMaps
	bsr	GrabLoop		; grab frames until halted


* close everything down again

	move.l	window,a0		; close window
	CALLSYS	CloseWindow,_IntBase
FailedWindow
	move.l	screen,a0		; close screen
	CALLSYS	CloseScreen,_IntBase
FailedScreen
	move.l	bitMap1,a0		; free BitMap1
	CALLSYS	FreeBitMap,_VidiBase
FailedBitMap1
	move.l	bitMap2,a0		; then BitMap2
	CALLSYS	FreeBitMap,_VidiBase
FailedBitMap2
	CALLSYS	DisownVidi,_VidiBase	; free Vidi
FailedOpen
	move.l	_VidiBase,a1		; close vidi.library
	CALLSYS	CloseLibrary,_SysBase
FailedVidi
	rts				; and exit



* GrabLoop	grabs the frames whilst checking for keypresses
*		inputs-	A4 points to current BitMap
*			A5 is a pointer to the alternate BitMap
*		result-	A4/A5 updated accordingly
*		corrupts D0-D3/A0-A1

GrabLoop
	moveq	#SYNC_LACED,d0		; even frame if possible
	move.b	bright,d1		; brightness
	lsl.b	#5,d1			; multiply by 32
	moveq	#32,d2			; frame offset
	CALLSYS	GrabFrame,_VidiBase	; wait for sync and grab frame

	move.l	a5,a0			; read into other bitmap
	moveq	#0,d0			; no flags
	moveq	#4,d1			; all planes
	CALLSYS	ReadBitMap		; read frame
	move.l	a5,a0			; and show it
	move.l	screen,a1		; on screen
	moveq	#-1,d0			; no change to ViewModes
	CALLSYS	ShowBitMap		; while reading next
	exg	a4,a5			; into other buffer

	bsr	GetIDCMP		; test for message
	tst.l	d2			; one waiting?
	beq	GrabLoop		; keep grabbing if not
	move.w	d3,d0			; else copy key code
	lea	grabkeyCase,a0		; use case table
	bra	Case			; to figure out correct routine

grabRight
	cmp.b	#7,bright		; already 7?
	beq	exitRight		; don't touch if so
	addq.b	#1,bright		; else increment brightness
exitRight
	bra	GrabLoop

grabLeft
	tst.b	bright			; already zero?
	beq	exitLeft		; don't touch if so
	subq.b	#1,bright		; else decrement brightness
exitLeft
	bra	GrabLoop

grabPause
	bsr	GetIDCMP		; wait for keypress
	tst.l	d2			; got one?
	beq	grabPause		; loop until yes
	bra	GrabLoop		; and continue



* GetIDCMP	return information about any Intuition message
*		result-	D2.L is message Class or 0 if no message
*			D3.W contains message code field
*		corrupts D0-D1/A0-A1

GetIDCMP
	move.l	window,a0		window pointer
	move.l	wd_UserPort(a0),a0	get user port addr
	CALLSYS	GetMsg,_SysBase		get message
	move.l	d0,d2			test if no message
	beq	exitIDCMP		return zero if none
	move.l	d0,a1			else copy into A reg
	move.l	im_Class(a1),d2		get IDCMP Class
	move.w	im_Code(a1),d3		and Code
	CALLSYS	ReplyMsg		say 'OK, got it'
exitIDCMP
	rts



* Case		standard case statement executor
*		inputs-	D0.W contains desired match value
*			A0.L points to case table of following format;
*				dc.w	<number of options>
*				dc.w	<match value1>
*				dc.l	<case routine 1>...
*				dc.l	<default (no match) routine>
*				a case arm addr of zero will simple RTS
*		corrupts D1/A0-A1

Case
	move.w	(a0)+,d1		get case value count
	bra	firstCase		find correct case
nextCase
	cmp.w	(a0)+,d0		check for match
	beq	foundCase		execute if found
	addq.l	#4,a0			step past useless arm
firstCase
	dbra	d1,nextCase		try again
foundCase
	move.l	(a0),d1			get arm addr (or default)
	beq	exitCase		merely return if zero
	move.l	d1,a0			else jump to routine
	jmp	(a0)
exitCase
	rts



* Data and variables

newWindow	dc.w	0,0		; LeftEdge TopEdge
		dc.w	320,256		; Width Height
		dc.b	0,12		; DetailPen BlockPen
		dc.l	VANILLAKEY	; IDCMPFlags
		dc.l	BACKDROP|BORDERLESS|ACTIVATE
					; Flags
		dc.l	0		; FirstGadget
		dc.l	0		; CheckMark
		dc.l	0		; Title
screen		dc.l	0		; Screen
		dc.l	0		; BitMap
		dc.w	0,0		; MinWidth MinHeight
		dc.w	0,0		; MaxWidth MaxHeight
		dc.w	CUSTOMSCREEN	; Type


grabkeyCase	dc.w	3		; case table for grab keys
		dc.w	'.'
		dc.l	grabRight
		dc.w	','
		dc.l	grabLeft
		dc.w	' '
		dc.l	grabPause
		dc.l	0


_VidiBase	ds.l	1		; library base addrs
_IntBase	ds.l	1

window		ds.l	1		; window and BitMap pointers
bitMap1		ds.l	1
bitMap2		ds.l	1

bright		dc.b	4
vidiName	VIDINAME

