Import the current wip animation datatype and subclasses. further development will...
[AROS.git] / workbench / classes / datatypes / animation / animationplayback.c
blobf7be96380ec426fa9ec1eae8ddb2ca233374406f
1 /*
2 Copyright © 2015-2016, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #ifndef DEBUG
7 # define DEBUG 0
8 #endif
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))
32 AROS_USERFUNC_INIT
34 struct Animation_Data *animd = (struct Animation_Data *)hook->h_Data;
35 BOOL doTick = FALSE, doLoad = TRUE;
36 #if (0)
37 D(bug("[animation.datatype]: %s(%08x)\n", __PRETTY_FUNCTION__, msg->pmt_Method));
38 #endif
40 switch (msg->pmt_Method)
42 case PM_TICK:
43 animd->ad_TimerData.atd_Tick++;
45 if (animd->ad_ProcessData->pp_BufferLevel < animd->ad_ProcessData->pp_BufferFrames)
46 doLoad = TRUE;
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;
54 doTick = TRUE;
56 break;
58 case PM_SHUTTLE:
59 doTick = TRUE;
60 break;
62 case PM_STATE:
63 doTick = TRUE;
64 break;
67 #if (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));
70 #endif
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));
74 return 0;
76 AROS_USERFUNC_EXIT
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));
107 return TRUE;
111 return FALSE;
114 AROS_UFH3(void, playerProc,
115 AROS_UFHA(STRPTR, argPtr, A0),
116 AROS_UFHA(ULONG, argSize, D0),
117 AROS_UFHA(struct ExecBase *, SysBase, A6))
119 AROS_USERFUNC_INIT
121 struct ProcessPrivate *priv = FindTask(NULL)->tc_UserData;
122 struct AnimFrame *curFrame = NULL, *prevFrame = NULL;
123 struct gpRender gprMsg;
124 struct TagItem attrtags[] =
126 { TAG_IGNORE, 0},
127 { TAG_IGNORE, 0},
128 { TAG_DONE, 0}
130 UWORD frame = 0;
131 ULONG signal;
133 D(bug("[animation.datatype/PLAY]: %s()\n", __PRETTY_FUNCTION__));
135 if (priv)
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__));
145 while (TRUE)
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)
155 break;
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);
176 else
178 curFrame = prevFrame;
179 while ((curFrame = (struct AnimFrame *)GetSucc(&curFrame->af_Node)) != NULL)
181 if (curFrame->af_Frame.alf_Frame == frame)
182 break;
184 if (!(curFrame))
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);
206 else
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;
217 continue;
219 else
221 frame = 0;
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__));
262 return;
264 AROS_USERFUNC_EXIT