; based on sample.library

	STRUCTURE ThxPlayBase,LIB_SIZE
	UBYTE	thx_Flags
	UBYTE	thx_pad
	ULONG	thx_SegList
	APTR	thx_OwnerTask		; task that owns THX
	STRUCT	thx_Sem,SS_SIZE		; semaphore to protect the above
	LABEL	ThxPlayBase_SIZEOF

	moveq	#-1,d0
	rts

RomTag	dc.w	RTC_MATCHWORD
	dc.l	RomTag,EndCode
	dc.b	RTF_AUTOINIT,VERSION,NT_LIBRARY,0
	dc.l	LibName,IDStr,InitTbl

LibName	dc.b	'thxplay.library',0,'$VER: '
IDStr	VSTRING
	cnop	0,4

InitTbl	dc.l	ThxPlayBase_SIZEOF,funcTbl,dataTbl,Init

funcTbl	dc.w	-1
	dc.w	Open -	funcTbl
	dc.w	Close -	funcTbl
	dc.w	Expunge - funcTbl
	dc.w	Null - funcTbl

; our functions start here
	dc.w	thxInit_library - funcTbl
	dc.w	thxFree_library - funcTbl

	dc.w	thxPlay - funcTbl
	dc.w	thxStop - funcTbl
	dc.w	thxPause - funcTbl
	dc.w	thxWind__i - funcTbl

	dc.w	thxGetVolume - funcTbl
	dc.w	thxSetVolume__i - funcTbl

	dc.w	thxGetNumSongs - funcTbl
	dc.w	thxSetSong__i - funcTbl

	dc.w	thxPlayNote__iii - funcTbl
	dc.w	thxStopNote__i - funcTbl
	dc.w	thxNoteFX__iii - funcTbl
	dc.w	Null - funcTbl		; reserved slot

	dc.w	thxSignalEnd__ii - funcTbl
	dc.w	thxSongEnded - funcTbl
	dc.w	thxSyncByte - funcTbl
	dc.w	thxPlaytime - funcTbl

	dc.w	-1


dataTbl	INITBYTE  LN_TYPE,	NT_LIBRARY
	INITLONG  LN_NAME,	LibName
	INITBYTE  LIB_FLAGS,	LIBF_SUMUSED!LIBF_CHANGED
	INITWORD  LIB_VERSION,	VERSION
	INITWORD  LIB_REVISION,	REVISION
	INITLONG  LIB_IDSTRING,	IDStr
	dc.l	0

Init	movem.l	a0/a1/d1/a5,-(sp)
	move.l	d0,a5
	move.l	a0,thx_SegList(a5)
	lea	thx_Sem(a5),a0
	jsr	_LVOInitSemaphore(a6)
	move.l	a5,d0
	movem.l	(sp)+,a0/a1/d1/a5
	rts

Open	addq.w	#1,LIB_OPENCNT(a6)
	bclr	#LIBB_DELEXP,thx_Flags(a6)
	move.l	a6,d0
	rts

Close	moveq	#0,d0
	subq.w	#1,LIB_OPENCNT(a6)
	bne.s	.noexp
	btst	#LIBB_DELEXP,thx_Flags(a6)
	beq.s	.noexp
	bsr.s	Expunge
.noexp	rts

Expunge	movem.l	d2/a5/a6,-(sp)
	move.l	a6,a5
	move.l	4.w,a6
	tst.w	LIB_OPENCNT(a5)
	beq	.close
	bset	#LIBB_DELEXP,thx_Flags(a5)
	moveq	#0,d0
	bra.s	.noexp
.close	move.l	thx_SegList(a5),d2
	move.l	a5,a1
	move.l	4.w,a6
	jsr	_LVORemove(a6)
	moveq	#0,d0
	move.l	a5,a1
	move.w	LIB_NEGSIZE(a5),d0
	sub.l	d0,a1
	add.w	LIB_POSSIZE(a5),d0
	jsr	_LVOFreeMem(a6)
	move.l	d2,d0
.noexp	movem.l	(sp)+,d2/a5/a6
	rts

Null	moveq	#0,d0
	rts

; special semaphore/owner based wrappers for thxInit() and thxFree()

thxInit_library
	movem.l	a0/a5/a6,-(sp)
	move.l	a6,a5
	move.l	4.w,a6
	lea	thx_Sem(a5),a0
	jsr	_LVOObtainSemaphore(a6)
	suba.l	a1,a1
	jsr	_LVOFindTask(a6)	; d0 = ourselves

	lea	thx_OwnerTask(a5),a0
	cmp.l	(a0),d0			; check if owner = ourselves
	beq.s	.got			; continue OK if we own THX
	tst.l	(a0)			; otherwise, see if owner = nobody
	beq.s	.take			; if noone owns THX, we take it

	lea	thx_Sem(a5),a0		; otherwise, we fail to thxInit()
	jsr	_LVOReleaseSemaphore(a6)
	movem.l	(sp)+,a0/a5/a6
	moveq	#-1,d0	; FAIL
	rts

.take	move.l	d0,(a0)			; set owner = ourselves
.got	lea	thx_Sem(a5),a0
	jsr	_LVOReleaseSemaphore(a6)
	movem.l	(sp)+,a0/a5/a6

	bsr	thxInit__i		; call the real thxInit()
	tst.l	d0
	beq.s	.exit			; if this fails, also call
	bsr	thxFree_library		; our redefined thxFree()
.exit	rts


thxFree_library
	movem.l	a5/a6,-(sp)
	move.l	a6,a5
	move.l	4.w,a6
	lea	thx_Sem(a5),a0
	jsr	_LVOObtainSemaphore(a6)
	suba.l	a1,a1
	jsr	_LVOFindTask(a6)	; d0 = ourselves

	move.l	thx_OwnerTask(a5),d1	; d1 = owner
	cmp.l	d0,d1			; do we own THX?
	bne.s	.exit			; no! don't allow freeing of THX
	bsr	thxFree			; otherwise, call the real thxFree()
	clr.l	thx_OwnerTask(a5)	; then set owner = nobody

.exit	lea	thx_Sem(a5),a0
	jsr	_LVOReleaseSemaphore(a6)
	movem.l	(sp)+,a5/a6
	rts

EndCode
