2 Copyright © 1995-2016, The AROS Development Team. All rights reserved.
6 # include <aros/debug.h>
8 #include <proto/exec.h>
9 #include <proto/utility.h>
10 #include <proto/realtime.h>
11 #include <exec/lists.h>
12 #include "realtime_intern.h"
14 struct Conductor
*createConductor(BOOL
private, LONG
*error
,STRPTR name
,
15 struct Library
*RealTimeBase
);
17 /*****************************************************************************
21 #include <utility/tagitem.h>
22 #include <libraries/realtime.h>
24 AROS_LH2(BOOL
, SetPlayerAttrsA
,
28 AROS_LHA(struct Player
*, player
, A0
),
29 AROS_LHA(struct TagItem
*, tagList
, A1
),
33 struct Library
*, RealTimeBase
, 9, RealTime
)
37 Sets the attributes of a player. An attribute not specified in the array
38 of tags is unchanged after this procedure.
42 player -- The player the attributes of which to set.
43 tagList -- Pointer to an array of tags describing the player's
48 The same tags as for CreatePlayerA().
52 Success/failure indicator. If failure, then, in case the PLAYER_ErrorCode
53 is provided, more information can be obtained via that pointer.
63 DeletePlayer(), GetPlayerAttrsA()
67 ******************************************************************************/
73 struct TagItem
*tl
= tagList
;
77 error
= (LONG
*)GetTagData(PLAYER_ErrorCode
, (IPTR
)NULL
, tl
);
79 while ((tag
= NextTagItem(&tl
)) != NULL
)
84 player
->pl_Link
.ln_Name
= (APTR
)tag
->ti_Data
;
88 player
->pl_Hook
= (struct Hook
*)tag
->ti_Data
;
92 player
->pl_Link
.ln_Pri
= (BYTE
)tag
->ti_Data
;
94 if (player
->pl_Link
.ln_Succ
!= NULL
)
96 /* If this node has been (is) inserted before, then remove it
97 and put it in the right place. */
99 /* Is this player attached to a conductor? */
100 if (player
->pl_Source
!= NULL
)
102 lock
= LockRealTime(RT_CONDUCTORS
);
103 Remove((struct Node
*)player
);
104 Enqueue((struct List
*)&player
->pl_Source
->cdt_Players
,
105 (struct Node
*)player
);
106 UnlockRealTime(lock
);
112 *error
= RTE_NOCONDUCTOR
;
121 case PLAYER_Conductor
:
123 D(bug("Found PLAYER_Conductor tag\n"));
125 if ((IPTR
)tag
->ti_Data
== -1UL)
127 player
->pl_Source
= createConductor(TRUE
, error
,
128 (STRPTR
)tag
->ti_Data
,
133 struct Conductor
*cd
= FindConductor((STRPTR
)tag
->ti_Data
);
137 D(bug("Trying to create a public conductor.\n"));
138 player
->pl_Source
= createConductor(FALSE
, error
,
139 (STRPTR
)tag
->ti_Data
,
144 player
->pl_Source
= cd
;
148 if (player
->pl_Source
!= NULL
)
152 lock
= LockRealTime(RT_CONDUCTORS
);
154 /* Enqueue the player to the conductor list */
155 Enqueue((struct List
*)&player
->pl_Source
->cdt_Players
,
156 (struct Node
*)player
);
158 UnlockRealTime(lock
);
164 *error
= RTE_NOCONDUCTOR
;
171 if ((BOOL
)tag
->ti_Data
)
173 struct Conductor
*conductor
= player
->pl_Source
;
175 player
->pl_Flags
|= PLAYERF_READY
;
177 if (conductor
!= NULL
)
179 ObtainSemaphoreShared(&conductor
->cdt_Lock
);
181 if (conductor
->cdt_Barrier
!= NULL
)
183 Signal(conductor
->cdt_Barrier
, SIGF_SINGLE
);
186 ReleaseSemaphore(&conductor
->cdt_Lock
);
191 player
->pl_Flags
&= ~PLAYERF_READY
;
196 case PLAYER_AlarmTime
:
197 player
->pl_Flags
|= PLAYERF_ALARMSET
;
198 player
->pl_AlarmTime
= (LONG
)tag
->ti_Data
;
202 if ((BOOL
)tag
->ti_Data
)
204 player
->pl_Flags
|= PLAYERF_ALARMSET
;
208 player
->pl_Flags
&= ~PLAYERF_ALARMSET
;
213 case PLAYER_AlarmSigTask
:
214 if ((struct Task
*)tag
->ti_Data
== NULL
)
216 player
->pl_Flags
&= ~PLAYERF_ALARMSET
;
219 player
->pl_Task
= (struct Task
*)tag
->ti_Data
;
222 case PLAYER_AlarmSigBit
:
223 if ((BYTE
)tag
->ti_Data
== -1)
225 player
->pl_Flags
&= ~PLAYERF_ALARMSET
;
228 /* We could use player->pl_Link.ln_Type here */
229 player
->pl_Reserved0
= (BYTE
)tag
->ti_Data
; /* NOTE! */
233 if ((BOOL
)tag
->ti_Data
)
235 player
->pl_Flags
|= PLAYERF_QUIET
;
239 player
->pl_Flags
&= ~PLAYERF_QUIET
;
244 case PLAYER_UserData
:
245 player
->pl_UserData
= (APTR
)tag
->ti_Data
;
249 player
->pl_PlayerID
= (UWORD
)tag
->ti_Data
;
252 case PLAYER_Conducted
:
253 if ((BOOL
)tag
->ti_Data
)
255 player
->pl_Flags
|= PLAYERF_CONDUCTED
;
259 player
->pl_Flags
&= ~PLAYERF_CONDUCTED
;
265 lock
= LockRealTime(RT_CONDUCTORS
);
267 if ((BOOL
)tag
->ti_Data
)
269 if (player
->pl_Source
->cdt_Flags
& CONDUCTF_EXTERNAL
)
271 /* Only one external synchronizer at a time, please */
272 UnlockRealTime(lock
);
277 player
->pl_Source
->cdt_Flags
|= CONDUCTF_EXTERNAL
;
278 player
->pl_Flags
|= PLAYERF_EXTSYNC
;
282 /* If this player was the external synchronizer, we
284 if (player
->pl_Flags
& PLAYERF_EXTSYNC
)
286 player
->pl_Source
->cdt_Flags
&= ~CONDUCTF_EXTERNAL
;
287 player
->pl_Source
->cdt_Flags
&= ~CONDUCTF_GOTTICK
;
290 player
->pl_Flags
&= ~PLAYERF_EXTSYNC
;
293 UnlockRealTime(lock
);
299 /* Consistency checks */
300 if (player
->pl_Task
== NULL
)
302 player
->pl_Flags
&= ~PLAYERF_ALARMSET
;
308 } /* SetPlayerAttrsA */
310 struct Conductor
*createConductor(BOOL
private, LONG
*error
, STRPTR name
,
311 struct Library
*RealTimeBase
)
313 struct Conductor
*cd
= AllocMem(sizeof(struct Conductor
),
314 MEMF_PUBLIC
| MEMF_CLEAR
);
320 *error
= RTE_NOMEMORY
;
326 cd
->cdt_Link
.ln_Name
= name
;
328 NEWLIST(&cd
->cdt_Players
);
329 InitSemaphore(&cd
->cdt_Lock
);
331 /* Initialize conductor clock */
332 cd
->cdt_ClockTime
= GPB(RealTimeBase
)->rtb_Time
;
333 cd
->cdt_StartTime
= GPB(RealTimeBase
)->rtb_Time
;
335 /* Conductors are created in 'stopped' mode. To make the clock start
336 running, call SetConductorState(player, CONDSTATE_RUNNING, _); */
337 cd
->cdt_State
= CONDSTATE_STOPPED
;
341 cd
->cdt_Flags
|= CONDUCTF_PRIVATE
;
345 /* Add the conductor to the realtime library conductor list */
348 lock
= LockRealTime(RT_CONDUCTORS
);
350 AddTail((struct List
*)&GPB(RealTimeBase
)->rtb_ConductorList
,
353 UnlockRealTime(lock
);