2 Copyright © 2015-2016, The AROS Development Team. All rights reserved.
9 #include <aros/debug.h>
11 #include <clib/alib_protos.h>
12 #include <proto/exec.h>
13 #include <proto/dos.h>
14 #include <proto/intuition.h>
15 #include <proto/graphics.h>
16 #include <proto/utility.h>
17 #include <proto/realtime.h>
18 #include <proto/layers.h>
19 #include <proto/datatypes.h>
21 #include <intuition/gadgetclass.h>
22 #include <libraries/realtime.h>
23 #include <gadgets/tapedeck.h>
25 #include "animationclass.h"
27 AROS_UFH3(ULONG
, playerHookFunc
,
28 AROS_UFHA(struct Hook
*, hook
, A0
),
29 AROS_UFHA(struct Player
*, obj
, A2
),
30 AROS_UFHA(struct pmTime
*, msg
, A1
))
34 struct Animation_Data
*animd
= (struct Animation_Data
*)hook
->h_Data
;
35 BOOL doTick
= FALSE
, doLoad
= TRUE
;
37 D(bug("[animation.datatype]: %s(%08x)\n", __PRETTY_FUNCTION__
, msg
->pmt_Method
));
40 switch (msg
->pmt_Method
)
43 animd
->ad_TimerData
.atd_Tick
++;
45 if (animd
->ad_ProcessData
->pp_BufferLevel
< animd
->ad_ProcessData
->pp_BufferFrames
)
48 if (animd
->ad_TimerData
.atd_Tick
>= animd
->ad_TimerData
.atd_TicksPerFrame
)
50 animd
->ad_TimerData
.atd_Tick
= 0;
51 animd
->ad_FrameData
.afd_FrameCurrent
++;
52 if (animd
->ad_FrameData
.afd_FrameCurrent
>= animd
->ad_FrameData
.afd_Frames
)
53 animd
->ad_FrameData
.afd_FrameCurrent
= 0;
68 if (doLoad
&& (animd
->ad_BufferProc
) && (animd
->ad_ProcessData
->pp_BufferFill
!= -1))
69 Signal((struct Task
*)animd
->ad_BufferProc
, (1 << animd
->ad_ProcessData
->pp_BufferFill
));
71 if (doTick
&& (animd
->ad_PlayerProc
) && (animd
->ad_ProcessData
->pp_PlaybackTick
!= -1))
72 Signal((struct Task
*)animd
->ad_PlayerProc
, (1 << animd
->ad_ProcessData
->pp_PlaybackTick
));
79 void FreePlaybackSignals(struct ProcessPrivate
*priv
)
81 D(bug("[animation.datatype/PLAY]: %s()\n", __PRETTY_FUNCTION__
));
83 if (priv
->pp_PlaybackTick
!= -1)
84 FreeSignal(priv
->pp_PlaybackTick
);
85 if (priv
->pp_PlaybackEnable
!= -1)
86 FreeSignal(priv
->pp_PlaybackEnable
);
87 if (priv
->pp_PlaybackDisable
!= -1)
88 FreeSignal(priv
->pp_PlaybackDisable
);
91 BOOL
AllocPlaybackSignals(struct ProcessPrivate
*priv
)
93 if ((priv
->pp_PlaybackEnable
= AllocSignal(-1)) != -1)
95 D(bug("[animation.datatype/PLAY]: %s: allocated enable signal (%x)\n", __PRETTY_FUNCTION__
, priv
->pp_PlaybackEnable
));
96 if ((priv
->pp_PlaybackDisable
= AllocSignal(-1)) != -1)
98 D(bug("[animation.datatype/PLAY]: %s: allocated disable signal (%x)\n", __PRETTY_FUNCTION__
, priv
->pp_PlaybackDisable
));
99 if ((priv
->pp_PlaybackTick
= AllocSignal(-1)) != -1)
101 D(bug("[animation.datatype/PLAY]: %s: allocated tick signal (%x)\n", __PRETTY_FUNCTION__
, priv
->pp_PlaybackTick
));
103 priv
->pp_PlaybackSigMask
= (1 << priv
->pp_PlaybackEnable
) | (1 << priv
->pp_PlaybackDisable
) | (1 << priv
->pp_PlaybackTick
);
105 D(bug("[animation.datatype/PLAY]: %s: signal mask (%x)\n", __PRETTY_FUNCTION__
, priv
->pp_PlaybackSigMask
));
114 AROS_UFH3(void, playerProc
,
115 AROS_UFHA(STRPTR
, argPtr
, A0
),
116 AROS_UFHA(ULONG
, argSize
, D0
),
117 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
121 struct ProcessPrivate
*priv
= FindTask(NULL
)->tc_UserData
;
122 struct AnimFrame
*curFrame
= NULL
, *prevFrame
= NULL
;
123 struct gpRender gprMsg
;
124 struct TagItem attrtags
[] =
133 D(bug("[animation.datatype/PLAY]: %s()\n", __PRETTY_FUNCTION__
));
137 D(bug("[animation.datatype/PLAY] %s: private data @ 0x%p\n", __PRETTY_FUNCTION__
, priv
));
138 D(bug("[animation.datatype/PLAY] %s: dt obj @ 0x%p, instance data @ 0x%p\n", __PRETTY_FUNCTION__
, priv
->pp_Object
, priv
->pp_Data
));
140 priv
->pp_PlayerFlags
|= PRIVPROCF_RUNNING
;
142 if (AllocPlaybackSignals(priv
))
144 D(bug("[animation.datatype/PLAY]: %s: entering main loop ...\n", __PRETTY_FUNCTION__
));
147 priv
->pp_PlayerFlags
&= ~PRIVPROCF_ACTIVE
;
149 signal
= priv
->pp_PlaybackSigMask
| SIGBREAKF_CTRL_C
;
150 signal
= Wait(signal
);
152 D(bug("[animation.datatype/PLAY]: %s: signalled (%08x)\n", __PRETTY_FUNCTION__
, signal
));
154 if (signal
& SIGBREAKF_CTRL_C
)
157 if (signal
& (1 << priv
->pp_PlaybackEnable
))
158 priv
->pp_PlayerFlags
|= PRIVPROCF_ENABLED
;
159 else if (signal
& (1 << priv
->pp_PlaybackDisable
))
160 priv
->pp_PlayerFlags
&= ~PRIVPROCF_ENABLED
;
162 if ((priv
->pp_PlayerFlags
& PRIVPROCF_ENABLED
) && (signal
& (1 << priv
->pp_PlaybackTick
)))
164 struct privRenderBuffer
*rendFrame
= (struct privRenderBuffer
*)&gprMsg
;
165 rendFrame
->MethodID
= PRIVATE_RENDERBUFFER
;
167 frame
= priv
->pp_Data
->ad_FrameData
.afd_FrameCurrent
;
168 D(bug("[animation.datatype/PLAY]: %s: TICK (frame %d)\n", __PRETTY_FUNCTION__
, frame
));
170 priv
->pp_PlayerFlags
|= PRIVPROCF_ACTIVE
;
172 ObtainSemaphoreShared(&priv
->pp_Data
->ad_FrameData
.afd_AnimFramesLock
);
174 if ((!prevFrame
) || (frame
== 0))
175 curFrame
= (struct AnimFrame
*)GetHead(&priv
->pp_Data
->ad_FrameData
.afd_AnimFrames
);
178 curFrame
= prevFrame
;
179 while ((curFrame
= (struct AnimFrame
*)GetSucc(&curFrame
->af_Node
)) != NULL
)
181 if (curFrame
->af_Frame
.alf_Frame
== frame
)
185 curFrame
= prevFrame
;
188 ReleaseSemaphore(&priv
->pp_Data
->ad_FrameData
.afd_AnimFramesLock
);
190 if ((curFrame
) && (prevFrame
!= curFrame
) &&
191 (curFrame
->af_Frame
.alf_BitMap
))
193 rendFrame
->Source
= curFrame
->af_Frame
.alf_BitMap
;
194 frame
= curFrame
->af_Frame
.alf_Frame
;
195 D(bug("[animation.datatype/PLAY]: %s: Rendering Frame @ 0x%p\n", __PRETTY_FUNCTION__
, curFrame
));
196 D(bug("[animation.datatype/PLAY]: %s: #%d BitMap @ 0x%p\n", __PRETTY_FUNCTION__
, curFrame
->af_Frame
.alf_Frame
, curFrame
->af_Frame
.alf_BitMap
));
197 if (curFrame
->af_Frame
.alf_CMap
)
199 D(bug("[animation.datatype/PLAY]: %s: Frame CMap @ 0x%p\n", __PRETTY_FUNCTION__
, curFrame
, curFrame
->af_Frame
.alf_CMap
));
200 DoMethod(priv
->pp_Object
, PRIVATE_FREEPENS
);
201 GetRGB32(curFrame
->af_Frame
.alf_CMap
, 0UL,
202 (curFrame
->af_Frame
.alf_CMap
->Count
< priv
->pp_Data
->ad_ColorData
.acd_NumColors
) ? curFrame
->af_Frame
.alf_CMap
->Count
: priv
->pp_Data
->ad_ColorData
.acd_NumColors
,
203 priv
->pp_Data
->ad_ColorData
.acd_CRegs
);
208 if ((priv
->pp_Data
->ad_BufferProc
) && (priv
->pp_BufferFill
!= -1))
210 Signal((struct Task
*)priv
->pp_Data
->ad_BufferProc
, (1 << priv
->pp_BufferFill
));
211 SetTaskPri((struct Task
*)priv
->pp_Data
->ad_PlayerProc
, -2);
214 if ((prevFrame
) && (prevFrame
->af_Frame
.alf_BitMap
))
216 priv
->pp_Data
->ad_FrameData
.afd_FrameCurrent
= prevFrame
->af_Frame
.alf_Frame
;
222 rendFrame
->Source
= priv
->pp_Data
->ad_KeyFrame
;
226 priv
->pp_Data
->ad_FrameData
.afd_FrameCurrent
= frame
;
228 // frame has changed ... render it ..
229 DoMethodA(priv
->pp_Object
, (Msg
)&gprMsg
);
231 if ((priv
->pp_Data
->ad_Window
) && !(priv
->pp_Data
->ad_Flags
& ANIMDF_LAYOUT
))
233 if (priv
->pp_Data
->ad_Tapedeck
)
235 // update the tapedeck gadget..
236 attrtags
[0].ti_Tag
= TDECK_CurrentFrame
;
237 attrtags
[0].ti_Data
= frame
;
238 attrtags
[1].ti_Tag
= TAG_IGNORE
;
240 SetAttrsA((Object
*)priv
->pp_Data
->ad_Tapedeck
, attrtags
);
242 D(bug("[animation.datatype/PLAY]: %s: Asking DTObj to render..\n", __PRETTY_FUNCTION__
));
243 // tell the top level gadget to redraw...
244 gprMsg
.MethodID
= GM_RENDER
;
245 gprMsg
.gpr_RPort
= priv
->pp_Data
->ad_Window
->RPort
;
246 gprMsg
.gpr_GInfo
= NULL
;
247 gprMsg
.gpr_Redraw
= 0;
248 DoGadgetMethodA((struct Gadget
*)priv
->pp_Object
, priv
->pp_Data
->ad_Window
, NULL
, (Msg
)&gprMsg
);
250 prevFrame
= curFrame
;
251 Signal((struct Task
*)priv
->pp_Data
->ad_BufferProc
, (1 << priv
->pp_BufferPurge
));
254 FreePlaybackSignals(priv
);
256 priv
->pp_PlayerFlags
&= ~PRIVPROCF_RUNNING
;
257 priv
->pp_Data
->ad_PlayerProc
= NULL
;
260 D(bug("[animation.datatype/PLAY]: %s: exiting ...\n", __PRETTY_FUNCTION__
));