;****** thxplay.library/thxPlaytime ******************************************
;
;   NAME
;       thxPlaytime -- get current playtime of song.
;
;   SYNOPSIS
;       seconds [, ticks, tickspd] = thxPlaytime()
;       D0         D1     D2
;
;       ULONG thxGetSyncByte(void);
;
;       seconds, ticks, tickspd := thxPlaytime()
;
;   FUNCTION
;       Gets the current playtime into the play of a currently playing song.
;
;   RESULT
;       seconds - the number of seconds elapsed since the start of the song.
;                 it is calculated from the following two results
;       ticks   - number of internal clock ticks.
;       tickspd - the speed of internal clock ticks in Hz.
;
;  BUGS
;       Will wrap at 65536 seconds. Also, due to a bug in the replayer,
;       will wrap at 65536 _ticks_ first. This will hopefully be fixed,
;       but the seconds limit probably will not be.
;
;  NOTE
;       Most C compilers will be unable to get the ticks and tickspd
;       results. Too bad. They're not that important.
;
;****************************************************************************
;
;
	cnop	0,4
	xdef	thxPlaytime
thxPlaytime
	move.l	THX+thxBSS_P(pc),d0
	beq.s	.exit
	move.l	d0,a0

; WARNING: THX REPLAYER IS BUGGED
; correct code:
;	move.l	thx_pPlayingTime(a0),d1		; d1 = numticks
; bug workaround:
	moveq	#0,d1
	move.w	thx_pPlayingTime(a0),d1		; d1 = numticks
; end of bug problem 

	move.l	d1,d0
	moveq	#0,d2
	move.w	thx_pMultiSpeed(a0),d2
	addq.w	#1,d2
	mulu.w	#50,d2				; d2 = ticks per sec
	divu	d2,d0				; d0 = numticks / ticks per sec
	ext.l	d0
.exit	rts




;****** thxplay.library/thxSyncByte ******************************************
;
;   NAME
;       thxSyncByte -- get sync byte value.
;
;   SYNOPSIS
;       syncvalue = thxGetSyncByte()
;       D0
;
;       UBYTE thxGetSyncByte(void);
;
;       syncvalue := thxGetSyncByte()
;
;   FUNCTION
;       Gets the current setting of the 'external timing' byte, which can be
;       set  to any byte value at any moment in time during play of the song
;       BY  the  song  itself,  using  the '8' command  in the tracker. This
;       function  is  here to allow you to mark specific events in the music
;       with   the  '8'  command  and  a  value,  then  wait  until  calling
;       thxSyncByte()  returns that value. The returned value doesn't change
;       until another '8' command in the song changes it.
;
;   NOTE
;       Be  very  careful  not  to  busy-wait on a new value if there is the
;       possibility the song is paused or not playing.
;
;   RESULT
;       syncvalue - current value of the sync byte.
;
;****************************************************************************
;
;
	cnop	0,4
	xdef	thxSyncByte
thxSyncByte
	move.l	THX+thxBSS_P(pc),d0
	beq.s	.exit
	move.l	d0,a0
	moveq	#0,d0
	move.b	(a0),d0	; thx_pExternalTiming(a0),d0
.exit	rts




;****** thxplay.library/thxSongEnded ******************************************
;
;       thxSongEnded -- detect if song has ended.
;
;   SYNOPSIS
;       songended = thxSongEnded()
;       D0
;
;       BOOL thxSongEnded(void);
;
;       songended := thxSongEnded()
;
;   FUNCTION
;       Returns  nonzero  value if the player has detected the end of a song
;       and is now looping.
;
;   NOTE
;       The detection of songend is crap (sorry Dexter :^)
;
;   RESULT
;       songended - nonzero if song is now looping, zero otherwise.
;
;   SEE ALSO
;       thxSignalEnd()
;
;****************************************************************************
;
;
	cnop	0,4
	xdef	thxSongEnded
thxSongEnded
	move.l	THX+thxBSS_P(pc),d0
	beq.s	.exit
	move.l	d0,a0
	moveq	#0,d0
	move.b	thx_pSongEnd(a0),d0
	beq.s	.exit
	moveq	#-1,d0
.exit	rts




;****** thxplay.library/thxSignalEnd ******************************************
;
;   NAME
;       thxSignalEnd -- Signal() when song ends.
;
;   SYNOPSIS
;       thxSignalEnd(task, signalset)
;                    A0    D0
;
;       void thxSignalEnd(struct Task *, ULONG);
;
;       thxSignalEnd(task, signalset)
;
;   FUNCTION
;       Asks  THX  to send the signalset to the specified task when the song
;       ends.  If songend occurs and the signal is sent, it will not be sent
;       again  unless  you  call thxSignalEnd() again to reload the trigger.
;       The signal will also be cancelled if you call thxStop() directly, or
;       indirectly through thxSetSong() or thxFree().
;
;   NOTE
;       The detection of songend is crap (sorry Dexter :^)
;
;   INPUTS
;       task       - pointer  to  a  task  or  process structure, simply use
;                    FindTask(NIL) to send to yourself.
;       signalset  - a 32bit set of signals, to be sent to task when songend
;                    occurs.
;
;   EXAMPLE
;       thxSignalEnd(FindTask(NIL), SIGBREAKF_CTRL_C) will send you a CTRL-C
;       when the song ends.
;
;   SEE ALSO
;       thxSongEnded(), exec.library/Signal()
;
;****************************************************************************
;
;
	cnop	0,4
	xdef	thxSignalEnd__ii
thxSignalEnd__ii
	move.b	mod_OK(pc),d1
	beq.s	.nosong
	lea	task(pc),a1

	ifd	_LIBRARY_
	move.l	a0,(a1)+	; store task
	move.l	d0,(a1)+	; store signalset
	else
	move.l	8(sp),(a1)+	; store task
	move.l	4(sp),(a1)+	; store signalset
	endc
	st.w	(a1)		; set trigger
.nosong	rts


; VARIABLES
; these are for thxSignalEnd(), and are implemented in interrupt.asm
task	dc.l	0	; APTR the task to signal
signals	dc.l	0	; ULONG signalset to send
dosig	dc.w	0	; BOOL we have yet to signal
