Import the current wip animation datatype and subclasses. further development will...
[AROS.git] / workbench / classes / datatypes / animation / animationclass.c
blob0d028e4ae53e90be165410c9ad854a8a49e868de
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/iffparse.h>
18 #include <proto/layers.h>
19 #include <proto/datatypes.h>
20 #include <proto/cybergraphics.h>
21 #include <proto/realtime.h>
23 #include <exec/types.h>
24 #include <exec/memory.h>
25 #include <dos/dostags.h>
26 #include <graphics/gfxbase.h>
27 #include <graphics/rpattr.h>
28 #include <intuition/imageclass.h>
29 #include <intuition/icclass.h>
30 #include <intuition/gadgetclass.h>
31 #include <intuition/cghooks.h>
32 #include <datatypes/datatypesclass.h>
33 #include <cybergraphx/cybergraphics.h>
34 #include <libraries/realtime.h>
36 #include <gadgets/tapedeck.h>
38 #include "animationclass.h"
40 #include <stdio.h>
42 extern AROS_UFP3(ULONG, playerHookFunc,
43 AROS_UFPA(struct Hook *, hook, A0),
44 AROS_UFPA(struct Player *, obj, A2),
45 AROS_UFPA(struct pmTime *, msg, A1));
47 extern AROS_UFP3(void, bufferProc,
48 AROS_UFPA(STRPTR, argPtr, A0),
49 AROS_UFPA(ULONG, argSize, D0),
50 AROS_UFPA(struct ExecBase *, SysBase, A6));
52 extern AROS_UFP3(void, playerProc,
53 AROS_UFPA(STRPTR, argPtr, A0),
54 AROS_UFPA(ULONG, argSize, D0),
55 AROS_UFPA(struct ExecBase *, SysBase, A6));
57 extern void ReadENVPrefs(APTR, APTR);
59 ADD2LIBS("realtime.library", 0, struct Library *, RealTimeBase);
60 ADD2LIBS("gadgets/tapedeck.gadget", 0, struct Library *, TapeDeckBase);
62 const IPTR SupportedMethods[] =
64 OM_NEW,
65 OM_GET,
66 OM_SET,
67 OM_UPDATE,
68 OM_DISPOSE,
70 GM_LAYOUT,
71 GM_HITTEST,
72 GM_GOACTIVE,
73 GM_GOINACTIVE,
74 GM_HANDLEINPUT,
75 GM_RENDER,
77 DTM_FRAMEBOX,
79 DTM_TRIGGER,
81 DTM_CLEARSELECTED,
82 DTM_COPY,
83 DTM_PRINT,
84 DTM_WRITE,
86 #if (0)
87 ADTM_LOCATE,
88 ADTM_PAUSE,
89 ADTM_START,
90 ADTM_STOP,
91 ADTM_LOADFRAME,
92 ADTM_UNLOADFRAME,
93 ADTM_LOADNEWFORMATFRAME,
94 ADTM_UNLOADNEWFORMATFRAME,
95 #endif
97 (~0)
100 struct DTMethod SupportedTriggerMethods[] =
102 { "Play", "PLAY", STM_PLAY },
103 { "Stop", "STOP", STM_STOP },
104 { "Pause", "PAUSE", STM_PAUSE },
106 { "Rewind", "REWIND", STM_REWIND },
107 { "Fast Forward", "FF", STM_FASTFORWARD },
109 { NULL, NULL, 0 },
112 char *GenTaskName(char *basename, char*taskname)
114 int namLen, id = 0;
115 char *newName;
117 namLen = strlen(basename);
118 newName = AllocVec(namLen + strlen(taskname) + 2 + 5, MEMF_ANY);
119 while (TRUE)
121 if (id == 0)
122 sprintf(newName, "%s %s", basename, taskname);
123 else
124 sprintf(newName, "%s %s.%d", basename, taskname, id);
125 if (FindTask(newName) == NULL)
126 break;
128 return newName;
131 /*** PRIVATE METHODS ***/
132 IPTR DT_InitPlayer(struct IClass *cl, struct Gadget *g, Msg msg)
134 struct Animation_Data *animd = INST_DATA (cl, g);
135 struct TagItem playertags[] =
137 { PLAYER_Name, (IPTR) "animation" },
138 { PLAYER_Conductor, (IPTR) "playback" },
139 { PLAYER_Priority, 0 },
140 { PLAYER_Hook, 0 },
141 { TAG_DONE, 0 }
144 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
146 if (!animd->ad_Player)
148 /* create a realtime player */
149 animd->ad_PlayerHook.h_Entry = (HOOKFUNC)playerHookFunc;
150 animd->ad_PlayerHook.h_Data = animd;
151 playertags[3].ti_Data = (IPTR)&animd->ad_PlayerHook;
152 animd->ad_Player = CreatePlayerA(playertags);
154 D(bug("[animation.datatype] %s: Realtime Player @ 0x%p\n", __PRETTY_FUNCTION__, animd->ad_Player));
156 if (!animd->ad_ProcessData)
158 char *projName = NULL;
160 animd->ad_ProcessData = AllocMem(sizeof(struct ProcessPrivate), MEMF_ANY);
161 animd->ad_ProcessData->pp_Object = (Object *)g;
162 animd->ad_ProcessData->pp_Data = animd;
164 InitSemaphore(&animd->ad_FrameData.afd_AnimFramesLock);
166 animd->ad_ProcessData->pp_PlayerFlags = 0;
167 animd->ad_ProcessData->pp_BufferFlags = 0;
169 animd->ad_ProcessData->pp_BufferFrames = animd->ad_BufferTime * animd->ad_TimerData.atd_FramesPerSec;
170 animd->ad_ProcessData->pp_BufferLevel = 0;
172 animd->ad_ProcessData->pp_BufferEnable = -1;
173 animd->ad_ProcessData->pp_BufferDisable = -1;
174 animd->ad_ProcessData->pp_BufferFill = -1;
175 animd->ad_ProcessData->pp_BufferPurge = -1;
177 animd->ad_ProcessData->pp_PlaybackEnable = -1;
178 animd->ad_ProcessData->pp_PlaybackDisable = -1;
179 animd->ad_ProcessData->pp_PlaybackTick = -1;
181 GetAttr(DTA_Name, (Object *)g, (IPTR *)&projName);
182 if (projName)
184 animd->ad_BaseName = FilePart(projName);
185 animd->ad_ProcessData->pp_BufferingName = GenTaskName(animd->ad_BaseName, "Buffering");
186 animd->ad_ProcessData->pp_PlayBackName = GenTaskName(animd->ad_BaseName, "Playback");
188 else
190 animd->ad_ProcessData->pp_BufferingName = GenTaskName("Animation", "Buffering");
191 animd->ad_ProcessData->pp_PlayBackName = GenTaskName("Animation", "Playback");
195 if ((animd->ad_ProcessData) && !(animd->ad_BufferProc))
197 animd->ad_BufferProc = CreateNewProcTags(
198 NP_Entry, (IPTR)bufferProc,
199 NP_Name, (IPTR)animd->ad_ProcessData->pp_BufferingName,
200 NP_Priority, (IPTR)((BYTE)-1),
201 NP_Synchronous, FALSE,
202 NP_Input, Input (),
203 NP_CloseInput, FALSE,
204 NP_Output, Output (),
205 NP_CloseOutput, FALSE,
206 NP_UserData, (IPTR)animd->ad_ProcessData,
207 NP_StackSize, animd->ad_ProcStack,
208 TAG_DONE);
209 while (!(animd->ad_ProcessData->pp_BufferFlags & PRIVPROCF_RUNNING))
211 Delay (1);
214 D(bug("[animation.datatype] %s: Buffering Process @ 0x%p\n", __PRETTY_FUNCTION__, animd->ad_BufferProc));
216 if ((animd->ad_ProcessData) && !(animd->ad_PlayerProc))
218 animd->ad_PlayerProc = CreateNewProcTags(
219 NP_Entry, (IPTR)playerProc,
220 NP_Name, (IPTR)animd->ad_ProcessData->pp_PlayBackName,
221 NP_Priority, 0,
222 NP_Synchronous, FALSE,
223 NP_Input, Input (),
224 NP_CloseInput, FALSE,
225 NP_Output, Output (),
226 NP_CloseOutput, FALSE,
227 NP_UserData, (IPTR)animd->ad_ProcessData,
228 NP_StackSize, animd->ad_ProcStack,
229 TAG_DONE);
230 while (!(animd->ad_ProcessData->pp_PlayerFlags & PRIVPROCF_RUNNING))
232 Delay (1);
235 D(bug("[animation.datatype] %s: Playback Process @ 0x%p\n", __PRETTY_FUNCTION__, animd->ad_PlayerProc));
237 return 1;
240 IPTR DT_FreePens(struct IClass *cl, struct Gadget *g, Msg msg)
242 struct Animation_Data *animd = INST_DATA (cl, g);
243 int i;
245 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
247 if ((animd->ad_ColorData.acd_ColorMap) && (animd->ad_ColorData.acd_NumAlloc > 0))
249 D(bug("[animation.datatype] %s: attempting to free %d pens\n", __PRETTY_FUNCTION__, animd->ad_ColorData.acd_NumAlloc));
250 D(bug("[animation.datatype] %s: colormap @ 0x%p\n", __PRETTY_FUNCTION__, animd->ad_ColorData.acd_ColorMap));
251 for (i = animd->ad_ColorData.acd_NumAlloc - 1; i >= 0; i--)
253 D(bug("[animation.datatype] %s: freeing pen %d\n", __PRETTY_FUNCTION__, animd->ad_ColorData.acd_Allocated[i]));
254 ReleasePen(animd->ad_ColorData.acd_ColorMap, animd->ad_ColorData.acd_Allocated[i]);
257 animd->ad_ColorData.acd_NumAlloc = 0;
258 animd->ad_Flags &= ~ANIMDF_REMAPPEDPENS;
261 return 1;
264 IPTR DT_FreeColorTables(struct IClass *cl, struct Gadget *g, Msg msg)
266 struct Animation_Data *animd = INST_DATA (cl, g);
268 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
270 if (animd->ad_ColorData.acd_ColorRegs)
271 FreeMem(animd->ad_ColorData.acd_ColorRegs, 1 + animd->ad_ColorData.acd_NumColors * sizeof (struct ColorRegister));
272 if (animd->ad_ColorData.acd_ColorTable[0])
273 FreeMem(animd->ad_ColorData.acd_ColorTable[0], 1 + animd->ad_ColorData.acd_NumColors * sizeof (UBYTE));
274 if (animd->ad_ColorData.acd_ColorTable[1])
275 FreeMem(animd->ad_ColorData.acd_ColorTable[1], 1 + animd->ad_ColorData.acd_NumColors * sizeof (UBYTE));
276 if (animd->ad_ColorData.acd_Allocated)
278 DoMethod((Object *)g, PRIVATE_FREEPENS);
279 FreeMem(animd->ad_ColorData.acd_Allocated, 1 + animd->ad_ColorData.acd_NumColors * sizeof (UBYTE));
281 if (animd->ad_ColorData.acd_CRegs)
282 FreeMem(animd->ad_ColorData.acd_CRegs, 1 + animd->ad_ColorData.acd_NumColors * (sizeof (ULONG) * 3));
283 if (animd->ad_ColorData.acd_GRegs)
284 FreeMem(animd->ad_ColorData.acd_GRegs, 1 + animd->ad_ColorData.acd_NumColors * (sizeof (ULONG) * 3));
286 return 1;
289 IPTR DT_AllocColorTables(struct IClass *cl, struct Gadget *g, struct privAllocColorTables *msg)
291 struct Animation_Data *animd = INST_DATA (cl, g);
293 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
295 if ((msg->NumColors != animd->ad_ColorData.acd_NumColors) &&
296 (animd->ad_ColorData.acd_NumColors > 0))
298 DoMethod((Object *)g, PRIVATE_FREECOLORTABLES);
300 animd->ad_ColorData.acd_NumColors = msg->NumColors;
301 if (animd->ad_ColorData.acd_NumColors > 0)
303 animd->ad_ColorData.acd_ColorRegs = AllocMem(1 + animd->ad_ColorData.acd_NumColors * sizeof (struct ColorRegister), MEMF_CLEAR);
304 D(bug("[animation.datatype] %s: ColorRegs @ 0x%p\n", __PRETTY_FUNCTION__, animd->ad_ColorData.acd_ColorRegs));
305 animd->ad_ColorData.acd_ColorTable[0] = AllocMem(1 + animd->ad_ColorData.acd_NumColors * sizeof (UBYTE), MEMF_CLEAR); // shared pen table
306 D(bug("[animation.datatype] %s: ColorTable @ 0x%p\n", __PRETTY_FUNCTION__, animd->ad_ColorData.acd_ColorTable[0]));
307 animd->ad_ColorData.acd_ColorTable[1] = AllocMem(1 + animd->ad_ColorData.acd_NumColors * sizeof (UBYTE), MEMF_CLEAR);
308 D(bug("[animation.datatype] %s: ColorTable2 @ 0x%p\n", __PRETTY_FUNCTION__, animd->ad_ColorData.acd_ColorTable[1]));
309 animd->ad_ColorData.acd_Allocated = AllocMem(1 + animd->ad_ColorData.acd_NumColors * sizeof (UBYTE), MEMF_CLEAR);
310 D(bug("[animation.datatype] %s: Allocated pens Array @ 0x%p\n", __PRETTY_FUNCTION__, animd->ad_ColorData.acd_Allocated));
311 animd->ad_ColorData.acd_CRegs = AllocMem(1 + animd->ad_ColorData.acd_NumColors * (sizeof (ULONG) * 3), MEMF_CLEAR); // RGB32 triples used with SetRGB32CM
312 D(bug("[animation.datatype] %s: CRegs @ 0x%p\n", __PRETTY_FUNCTION__, animd->ad_ColorData.acd_CRegs));
313 animd->ad_ColorData.acd_GRegs = AllocMem(1 + animd->ad_ColorData.acd_NumColors * (sizeof (ULONG) * 3), MEMF_CLEAR); // remapped version of ad_ColorData.acd_CRegs
314 D(bug("[animation.datatype] %s: GRegs @ 0x%p\n", __PRETTY_FUNCTION__, animd->ad_ColorData.acd_GRegs));
317 return 1;
320 IPTR DT_AllocBuffer(struct IClass *cl, struct Gadget *g, struct privAllocBuffer *msg)
322 struct Animation_Data *animd = INST_DATA (cl, g);
324 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
326 if (animd->ad_FrameBuffer)
327 FreeBitMap(animd->ad_FrameBuffer);
329 animd->ad_FrameBuffer = AllocBitMap(animd->ad_BitMapHeader.bmh_Width, animd->ad_BitMapHeader.bmh_Height, msg->Depth,
330 BMF_CLEAR, msg->Friend);
332 D(bug("[animation.datatype] %s: Frame Buffer @ 0x%p\n", __PRETTY_FUNCTION__, animd->ad_FrameBuffer));
333 D(bug("[animation.datatype] %s: %dx%dx%d\n", __PRETTY_FUNCTION__, animd->ad_BitMapHeader.bmh_Width, animd->ad_BitMapHeader.bmh_Height, msg->Depth));
335 return (IPTR)animd->ad_FrameBuffer;
338 IPTR DT_RenderBuffer(struct IClass *cl, struct Gadget *g, struct privRenderBuffer *msg)
340 struct Animation_Data *animd = INST_DATA (cl, g);
342 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
344 if (msg->Source)
346 if ((animd->ad_ColorData.acd_NumColors > 0) && (animd->ad_Flags & ANIMDF_REMAP))
348 DoMethod((Object *)g, PRIVATE_REMAPBUFFER, msg->Source);
350 else
351 BltBitMap(msg->Source, 0, 0, animd->ad_FrameBuffer, 0, 0, animd->ad_BitMapHeader.bmh_Width, animd->ad_BitMapHeader.bmh_Height, 0xC0, 0xFF, NULL);
354 return (IPTR)1;
357 UBYTE HAMFlag(UBYTE depth, UBYTE pen)
359 if (depth == 8)
360 return ((pen & 0xC0) >> 6);
361 return ((pen & 0x30) >> 4);
364 UBYTE HAMComponent(UBYTE depth, UBYTE pen)
366 if (depth == 8)
367 return (pen & 0x3F);
368 return (pen & 0xF);
371 UBYTE HAMColor(UBYTE depth, UBYTE pen, UBYTE val)
373 if (depth < 8)
374 return (HAMComponent(depth, pen) << 4);
375 return (val & 0x3) | (HAMComponent(depth, pen) << 2);
378 IPTR DT_RemapBuffer(struct IClass *cl, struct Gadget *g, struct privRenderBuffer *msg)
380 struct Animation_Data *animd = INST_DATA (cl, g);
381 struct RastPort *remapRP, *targetRP;
382 struct TagItem bestpenTags[] =
384 { OBP_Precision, animd->ad_ColorData.acd_PenPrecison },
385 { TAG_DONE, 0 }
387 UBYTE *tmpline, *outline;
388 ULONG curpen;
389 int i, x;
391 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
393 if (animd->ad_Window)
395 if ((animd->ad_ColorData.acd_NumColors > 0) && !(animd->ad_Flags & ANIMDF_REMAPPEDPENS))
397 animd->ad_ColorData.acd_ColorMap = animd->ad_Window->WScreen->ViewPort.ColorMap;
398 D(bug("[animation.datatype] %s: colormap @ 0x%p\n", __PRETTY_FUNCTION__, animd->ad_ColorData.acd_ColorMap));
400 for (i = 0; i < animd->ad_ColorData.acd_NumColors; i++)
402 curpen = animd->ad_ColorData.acd_NumAlloc++;
403 animd->ad_ColorData.acd_Allocated[curpen] = ObtainBestPenA(animd->ad_ColorData.acd_ColorMap,
404 animd->ad_ColorData.acd_CRegs[i * 3], animd->ad_ColorData.acd_CRegs[i * 3 + 1], animd->ad_ColorData.acd_CRegs[i * 3 + 2],
405 bestpenTags);
407 // get the actual color components for the pen.
408 GetRGB32(animd->ad_Window->WScreen->ViewPort.ColorMap,
409 animd->ad_ColorData.acd_Allocated[curpen], 1, &animd->ad_ColorData.acd_GRegs[animd->ad_ColorData.acd_NumAlloc * 3]);
411 D(bug("[animation.datatype] %s: bestpen #%d for %02x%02x%02x\n", __PRETTY_FUNCTION__, animd->ad_ColorData.acd_Allocated[curpen], (animd->ad_ColorData.acd_CRegs[i * 3] & 0xFF), (animd->ad_ColorData.acd_CRegs[i * 3 + 1] & 0xFF), (animd->ad_ColorData.acd_CRegs[i * 3 + 2] & 0xFF)));
413 animd->ad_ColorData.acd_ColorTable[0][i] = animd->ad_ColorData.acd_Allocated[curpen];
414 animd->ad_ColorData.acd_ColorTable[1][i] = animd->ad_ColorData.acd_Allocated[curpen];
416 animd->ad_Flags |= ANIMDF_REMAPPEDPENS;
419 // remap the source ..
420 if (animd->ad_FrameBuffer && ((tmpline = AllocVec(animd->ad_BitMapHeader.bmh_Width, MEMF_ANY)) != NULL))
422 UBYTE srcdepth, buffdepth;
423 srcdepth = (UBYTE)GetBitMapAttr(msg->Source, BMA_DEPTH);
424 buffdepth = (UBYTE)GetBitMapAttr(animd->ad_FrameBuffer, BMA_DEPTH);
426 if ((animd->ad_ModeID & HAM_KEY) && (srcdepth <= 8))
428 D(bug("[animation.datatype] %s: remapping HAM%d\n", __PRETTY_FUNCTION__, srcdepth));
429 outline = AllocVec(animd->ad_BitMapHeader.bmh_Width << 2, MEMF_ANY);
431 else
432 outline = tmpline;
434 remapRP = CreateRastPort();
435 targetRP = CreateRastPort();
437 remapRP->BitMap = msg->Source;
438 targetRP->BitMap = animd->ad_FrameBuffer;
440 for(i = 0; i < animd->ad_BitMapHeader.bmh_Height; i++)
442 if ((animd->ad_ModeID & HAM_KEY) && (srcdepth <= 8))
444 UBYTE hamr = 0, hamg = 0, hamb = 0;
446 for(x = 0; x < animd->ad_BitMapHeader.bmh_Width; x++)
448 BOOL compose = TRUE;
449 ULONG mask = 1 << (7 - (x & 7));
450 UBYTE p;
452 tmpline[x] = 0;
453 for (p = 0; p < srcdepth; p++)
455 UBYTE *planedata = (UBYTE *)msg->Source->Planes[p];
456 ULONG offset = (i * animd->ad_BitMapHeader.bmh_Width) + x;
458 if ((planedata) && (planedata[offset / 8 ] & mask))
459 tmpline[x] |= (1 << p);
462 curpen = tmpline[x];
463 if (HAMFlag(srcdepth, curpen) == 0)
465 curpen = HAMComponent(srcdepth, curpen);
466 if (buffdepth <= 8)
468 compose = FALSE;
469 outline[x] = animd->ad_ColorData.acd_ColorTable[1][curpen];
471 hamr = (animd->ad_ColorData.acd_CRegs[curpen * 3] & 0xFF);
472 hamg = (animd->ad_ColorData.acd_CRegs[curpen * 3 + 1] & 0xFF);
473 hamb = (animd->ad_ColorData.acd_CRegs[curpen * 3 + 2] & 0xFF);
475 else if (HAMFlag(srcdepth, curpen) == 1)
477 //modify blue..
478 hamb = HAMColor(srcdepth, curpen, hamb);
480 else if (HAMFlag(srcdepth, curpen) == 2)
482 // modify red
483 hamr = HAMColor(srcdepth, curpen, hamr);
485 else if (HAMFlag(srcdepth, curpen) == 3)
487 //modify green
488 hamg = HAMColor(srcdepth, curpen, hamg);
491 if (compose)
493 if (buffdepth <= 8)
495 // TODO: Map pixel color
496 outline[x] = 0;
498 else
500 outline[x * 4] = 0;
501 outline[x * 4 + 1] = hamr;
502 outline[x * 4 + 2] = hamg;
503 outline[x * 4 + 3] = hamb;
507 if (buffdepth <= 8)
508 WritePixelLine8(targetRP,0,i,animd->ad_BitMapHeader.bmh_Width,outline,NULL);
509 else
510 WritePixelArray(outline, 0, 0, animd->ad_BitMapHeader.bmh_Width, targetRP, 0, i, animd->ad_BitMapHeader.bmh_Width, 1, RECTFMT_ARGB);
512 else
514 ReadPixelLine8(remapRP,0,i,animd->ad_BitMapHeader.bmh_Width,tmpline,NULL);
516 for(x = 0; x < animd->ad_BitMapHeader.bmh_Width; x++)
518 curpen = tmpline[x];
519 outline[x] = animd->ad_ColorData.acd_ColorTable[1][curpen];
522 WritePixelLine8(targetRP,0,i,animd->ad_BitMapHeader.bmh_Width,outline,NULL);
526 FreeRastPort(remapRP);
527 FreeRastPort(targetRP);
529 if (outline != tmpline)
530 FreeVec(outline);
531 FreeVec(tmpline);
534 return 1;
537 /*** PUBLIC METHODS ***/
538 IPTR DT_GetMethod(struct IClass *cl, struct Gadget *g, struct opGet *msg)
540 struct Animation_Data *animd = INST_DATA (cl, g);
542 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
544 switch(msg->opg_AttrID)
546 case ADTA_KeyFrame:
547 D(bug("[animation.datatype] %s: ADTA_KeyFrame\n", __PRETTY_FUNCTION__));
548 *msg->opg_Storage = (IPTR) animd->ad_KeyFrame;
549 break;
551 case ADTA_ModeID:
552 D(bug("[animation.datatype] %s: ADTA_ModeID\n", __PRETTY_FUNCTION__));
553 *msg->opg_Storage = (IPTR) animd->ad_ModeID;
554 break;
556 case ADTA_Width:
557 D(bug("[animation.datatype] %s: ADTA_Width\n", __PRETTY_FUNCTION__));
558 *msg->opg_Storage = (IPTR) animd->ad_BitMapHeader.bmh_Width;
559 D(bug("[animation.datatype] %s: = %d\n", __PRETTY_FUNCTION__, *msg->opg_Storage));
560 break;
562 case ADTA_Height:
563 D(bug("[animation.datatype] %s: ADTA_Height\n", __PRETTY_FUNCTION__));
564 *msg->opg_Storage = (IPTR) animd->ad_BitMapHeader.bmh_Height;
565 D(bug("[animation.datatype] %s: = %d\n", __PRETTY_FUNCTION__, *msg->opg_Storage));
566 break;
568 case ADTA_Depth:
569 D(bug("[animation.datatype] %s: ADTA_Depth\n", __PRETTY_FUNCTION__));
570 *msg->opg_Storage = (IPTR) animd->ad_BitMapHeader.bmh_Depth;
571 D(bug("[animation.datatype] %s: = %d\n", __PRETTY_FUNCTION__, *msg->opg_Storage));
572 break;
574 case ADTA_Frames:
575 D(bug("[animation.datatype] %s: ADTA_Frames\n", __PRETTY_FUNCTION__));
576 *msg->opg_Storage = (IPTR) animd->ad_FrameData.afd_Frames;
577 break;
579 case ADTA_Frame:
580 D(bug("[animation.datatype] %s: ADTA_Frame\n", __PRETTY_FUNCTION__));
581 *msg->opg_Storage = (IPTR) animd->ad_FrameData.afd_FrameCurrent;
582 break;
584 case ADTA_FramesPerSecond:
585 D(bug("[animation.datatype] %s: ADTA_FramesPerSecond\n", __PRETTY_FUNCTION__));
586 *msg->opg_Storage = (IPTR) animd->ad_TimerData.atd_FramesPerSec;
587 break;
589 case ADTA_FrameIncrement:
590 D(bug("[animation.datatype] %s: ADTA_FrameIncrement\n", __PRETTY_FUNCTION__));
591 break;
592 case ADTA_Sample:
593 D(bug("[animation.datatype] %s: ADTA_Sample\n", __PRETTY_FUNCTION__));
594 break;
595 case ADTA_SampleLength:
596 D(bug("[animation.datatype] %s: ADTA_SampleLength\n", __PRETTY_FUNCTION__));
597 break;
598 case ADTA_Period:
599 D(bug("[animation.datatype] %s: ADTA_Period\n", __PRETTY_FUNCTION__));
600 break;
601 case ADTA_Volume:
602 D(bug("[animation.datatype] %s: ADTA_Volume\n", __PRETTY_FUNCTION__));
603 break;
604 case ADTA_Cycles:
605 D(bug("[animation.datatype] %s: ADTA_Cycles\n", __PRETTY_FUNCTION__));
606 break;
608 case ADTA_NumColors:
609 D(bug("[animation.datatype] %s: ADTA_NumColors\n", __PRETTY_FUNCTION__));
610 *msg->opg_Storage = (IPTR) animd->ad_ColorData.acd_NumColors;
611 D(bug("[animation.datatype] %s: = %d\n", __PRETTY_FUNCTION__, *msg->opg_Storage));
612 break;
614 case ADTA_NumAlloc:
615 D(bug("[animation.datatype] %s: ADTA_NumAlloc\n", __PRETTY_FUNCTION__));
616 *msg->opg_Storage = (IPTR) animd->ad_ColorData.acd_NumAlloc;
617 D(bug("[animation.datatype] %s: = %d\n", __PRETTY_FUNCTION__, *msg->opg_Storage));
618 break;
620 case ADTA_ColorRegisters:
621 D(bug("[animation.datatype] %s: ADTA_ColorRegisters\n", __PRETTY_FUNCTION__));
622 *msg->opg_Storage = (IPTR) animd->ad_ColorData.acd_ColorRegs;
623 D(bug("[animation.datatype] %s: = %p\n", __PRETTY_FUNCTION__, *msg->opg_Storage));
624 break;
626 case ADTA_ColorTable:
627 D(bug("[animation.datatype] %s: ADTA_ColorTable\n", __PRETTY_FUNCTION__));
628 *msg->opg_Storage = (IPTR) animd->ad_ColorData.acd_ColorTable[0];
629 D(bug("[animation.datatype] %s: = %p\n", __PRETTY_FUNCTION__, *msg->opg_Storage));
630 break;
632 case ADTA_ColorTable2:
633 D(bug("[animation.datatype] %s: ADTA_ColorTable2\n", __PRETTY_FUNCTION__));
634 *msg->opg_Storage = (IPTR) animd->ad_ColorData.acd_ColorTable[1];
635 D(bug("[animation.datatype] %s: = %p\n", __PRETTY_FUNCTION__, *msg->opg_Storage));
636 break;
638 case ADTA_Allocated:
639 D(bug("[animation.datatype] %s: ADTA_Allocated\n", __PRETTY_FUNCTION__));
640 *msg->opg_Storage = (IPTR) animd->ad_ColorData.acd_Allocated;
641 D(bug("[animation.datatype] %s: = %p\n", __PRETTY_FUNCTION__, *msg->opg_Storage));
642 break;
644 case ADTA_CRegs:
645 D(bug("[animation.datatype] %s: ADTA_CRegs\n", __PRETTY_FUNCTION__));
646 *msg->opg_Storage = (IPTR) animd->ad_ColorData.acd_CRegs;
647 D(bug("[animation.datatype] %s: = %p\n", __PRETTY_FUNCTION__, *msg->opg_Storage));
648 break;
650 case ADTA_GRegs:
651 D(bug("[animation.datatype] %s: ADTA_GRegs\n", __PRETTY_FUNCTION__));
652 *msg->opg_Storage = (IPTR) animd->ad_ColorData.acd_GRegs;
653 D(bug("[animation.datatype] %s: = %p\n", __PRETTY_FUNCTION__, *msg->opg_Storage));
654 break;
656 case PDTA_BitMapHeader:
657 D(bug("[animation.datatype] %s: PDTA_BitMapHeader\n", __PRETTY_FUNCTION__));
658 *msg->opg_Storage = (IPTR) &animd->ad_BitMapHeader;
659 break;
661 case DTA_TriggerMethods:
662 D(bug("[animation.datatype] %s: DTA_TriggerMethods\n", __PRETTY_FUNCTION__));
663 *msg->opg_Storage = (IPTR) SupportedTriggerMethods;
664 break;
666 case DTA_Methods:
667 D(bug("[animation.datatype] %s: DTA_Methods\n", __PRETTY_FUNCTION__));
668 *msg->opg_Storage = (IPTR) SupportedMethods;
669 break;
671 case DTA_ControlPanel:
672 D(bug("[animation.datatype] %s: DTA_ControlPanel\n", __PRETTY_FUNCTION__));
673 if ((animd->ad_Tapedeck) && (animd->ad_Flags & ANIMDF_CONTROLPANEL))
674 *msg->opg_Storage = (IPTR) TRUE;
675 else
676 *msg->opg_Storage = (IPTR) FALSE;
677 break;
679 case DTA_Immediate:
680 D(bug("[animation.datatype] %s: DTA_Immediate\n", __PRETTY_FUNCTION__));
681 if (animd->ad_Flags & ANIMDF_IMMEDIATE)
682 *msg->opg_Storage = (IPTR) TRUE;
683 else
684 *msg->opg_Storage = (IPTR) FALSE;
685 break;
687 case ADTA_Remap:
688 D(bug("[animation.datatype] %s: ADTA_Remap\n", __PRETTY_FUNCTION__));
689 if (animd->ad_Flags & ANIMDF_REMAP)
690 *msg->opg_Storage = (IPTR) TRUE;
691 else
692 *msg->opg_Storage = (IPTR) FALSE;
693 break;
695 #if (0)
696 case ADTA_Repeat:
697 D(bug("[animation.datatype] %s: ADTA_Repeat\n", __PRETTY_FUNCTION__));
698 if (animd->ad_Flags & ANIMDF_REPEAT)
699 *msg->opg_Storage = (IPTR) TRUE;
700 else
701 *msg->opg_Storage = (IPTR) FALSE;
702 break;
704 /* NB -: the autodoc isnt clear if we can 'get' these ... */
705 case ADTA_AdaptiveFPS:
706 D(bug("[animation.datatype] %s: ADTA_AdaptiveFPS\n", __PRETTY_FUNCTION__));
707 if (animd->ad_Flags & ANIMDF_ADAPTFPS)
708 *msg->opg_Storage = (IPTR) TRUE;
709 else
710 *msg->opg_Storage = (IPTR) FALSE;
711 break;
713 case ADTA_SmartSkip:
714 D(bug("[animation.datatype] %s: ADTA_SmartSkip\n", __PRETTY_FUNCTION__));
715 if (animd->ad_Flags & ANIMDF_SMARTSKIP)
716 *msg->opg_Storage = (IPTR) TRUE;
717 else
718 *msg->opg_Storage = (IPTR) FALSE;
719 break;
721 case ADTA_OvertakeScreem:
722 D(bug("[animation.datatype] %s: ADTA_OvertakeScreem\n", __PRETTY_FUNCTION__));
723 if (animd->ad_Flags & ANIMDF_ADJUSTPALETTE)
724 *msg->opg_Storage = (IPTR) TRUE;
725 else
726 *msg->opg_Storage = (IPTR) FALSE;
727 break;
728 #endif
730 case OBP_Precision:
731 *msg->opg_Storage = (IPTR) animd->ad_ColorData.acd_PenPrecison;
732 break;
734 default:
735 return DoSuperMethodA (cl, g, (Msg) msg);
738 return (IPTR)TRUE;
741 IPTR DT_SetMethod(struct IClass *cl, struct Gadget *g, struct opSet *msg)
743 struct Animation_Data *animd = INST_DATA (cl, g);
744 struct TagItem *tstate = msg->ops_AttrList;
745 struct TagItem attrtags[] =
747 { TAG_IGNORE, 0},
748 { TAG_DONE, 0}
750 struct TagItem *tag;
752 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
754 while((tag = NextTagItem(&tstate)) != NULL)
756 switch(tag->ti_Tag)
758 case ADTA_ModeID:
759 D(bug("[animation.datatype] %s: ADTA_ModeID (%08x)\n", __PRETTY_FUNCTION__, tag->ti_Data));
760 animd->ad_ModeID = (IPTR) tag->ti_Data;
762 if (animd->ad_ModeID & HAM_KEY)
763 D(bug("[animation.datatype] %s: HAM mode!\n", __PRETTY_FUNCTION__));
765 break;
767 case ADTA_Width:
768 D(bug("[animation.datatype] %s: ADTA_Width (%d)\n", __PRETTY_FUNCTION__, tag->ti_Data));
769 animd->ad_BitMapHeader.bmh_Width = (UWORD) tag->ti_Data;
770 attrtags[0].ti_Tag = DTA_NominalHoriz;
771 attrtags[0].ti_Data = tag->ti_Data;
772 SetAttrsA((Object *)g, attrtags);
773 break;
775 case ADTA_Height:
776 D(bug("[animation.datatype] %s: ADTA_Height (%d)\n", __PRETTY_FUNCTION__, tag->ti_Data));
777 animd->ad_BitMapHeader.bmh_Height = (UWORD) tag->ti_Data;
778 attrtags[0].ti_Tag = DTA_NominalVert;
779 if ((animd->ad_Tapedeck) && (animd->ad_Flags & ANIMDF_CONTROLPANEL))
780 GetAttr(GA_Height, (Object *)animd->ad_Tapedeck, (IPTR *)&attrtags[0].ti_Data);
781 else
782 attrtags[0].ti_Data = 0;
783 attrtags[0].ti_Data += tag->ti_Data;
784 SetAttrsA((Object *)g, attrtags);
785 break;
787 case ADTA_Depth:
788 D(bug("[animation.datatype] %s: ADTA_Depth (%d)\n", __PRETTY_FUNCTION__, tag->ti_Data));
789 animd->ad_BitMapHeader.bmh_Depth = (UBYTE) tag->ti_Data;
790 break;
792 case ADTA_Frames:
793 D(bug("[animation.datatype] %s: ADTA_Frames (%d)\n", __PRETTY_FUNCTION__, tag->ti_Data));
794 animd->ad_FrameData.afd_Frames = (UWORD) tag->ti_Data;
795 if (animd->ad_Tapedeck)
797 attrtags[0].ti_Tag = TDECK_Frames;
798 attrtags[0].ti_Data = tag->ti_Data;
799 SetAttrsA((Object *)animd->ad_Tapedeck, attrtags);
801 break;
803 case ADTA_KeyFrame:
804 D(bug("[animation.datatype] %s: ADTA_KeyFrame (0x%p)\n", __PRETTY_FUNCTION__, tag->ti_Data));
805 animd->ad_KeyFrame = (struct BitMap *) tag->ti_Data;
806 break;
808 case ADTA_NumColors:
809 D(bug("[animation.datatype] %s: ADTA_NumColors (%d)\n", __PRETTY_FUNCTION__, tag->ti_Data));
810 DoMethod((Object *)g, PRIVATE_ALLOCCOLORTABLES, tag->ti_Data);
811 break;
813 case ADTA_FramesPerSecond:
814 D(bug("[animation.datatype] %s: ADTA_FramesPerSecond (%d)\n", __PRETTY_FUNCTION__, tag->ti_Data));
815 animd->ad_TimerData.atd_FramesPerSec = (UWORD) tag->ti_Data;
816 if (animd->ad_TimerData.atd_FramesPerSec == 0)
817 animd->ad_TimerData.atd_FramesPerSec = 1;
818 else if (animd->ad_TimerData.atd_FramesPerSec > 60)
819 animd->ad_TimerData.atd_FramesPerSec = 60;
820 animd->ad_TimerData.atd_TicksPerFrame = (ANIMPLAYER_TICKFREQ / animd->ad_TimerData.atd_FramesPerSec);
821 if (animd->ad_ProcessData)
823 animd->ad_ProcessData->pp_BufferFrames = animd->ad_BufferTime * animd->ad_TimerData.atd_FramesPerSec;
825 break;
827 case SDTA_Sample:
828 D(bug("[animation.datatype] %s: SDTA_Sample\n", __PRETTY_FUNCTION__));
829 break;
830 case SDTA_SampleLength:
831 D(bug("[animation.datatype] %s: SDTA_SampleLength\n", __PRETTY_FUNCTION__));
832 break;
833 case SDTA_Period:
834 D(bug("[animation.datatype] %s: SDTA_Period\n", __PRETTY_FUNCTION__));
835 break;
836 case SDTA_Volume:
837 D(bug("[animation.datatype] %s: SDTA_Volume\n", __PRETTY_FUNCTION__));
838 break;
840 case DTA_TopHoriz:
841 D(bug("[animation.datatype] %s: DTA_TopHoriz (%d)\n", __PRETTY_FUNCTION__, tag->ti_Data));
842 animd->ad_HorizTop = (UWORD) tag->ti_Data;
843 break;
845 case DTA_TotalHoriz:
846 D(bug("[animation.datatype] %s: DTA_TotalHoriz (%d)\n", __PRETTY_FUNCTION__, tag->ti_Data));
847 animd->ad_HorizTotal = (UWORD) tag->ti_Data;
848 break;
850 case DTA_VisibleHoriz:
851 D(bug("[animation.datatype] %s: DTA_VisibleHoriz (%d)\n", __PRETTY_FUNCTION__, tag->ti_Data));
852 animd->ad_HorizVis = (UWORD) tag->ti_Data;
853 break;
855 case DTA_TopVert:
856 D(bug("[animation.datatype] %s: DTA_TopVert (%d)\n", __PRETTY_FUNCTION__, tag->ti_Data));
857 animd->ad_VertTop = (UWORD) tag->ti_Data;
858 break;
860 case DTA_TotalVert:
861 D(bug("[animation.datatype] %s: DTA_TotalVert (%d)\n", __PRETTY_FUNCTION__, tag->ti_Data));
862 animd->ad_VertTotal = (UWORD) tag->ti_Data;
863 break;
865 case DTA_VisibleVert:
866 D(bug("[animation.datatype] %s: DTA_VisibleVert (%d)\n", __PRETTY_FUNCTION__, tag->ti_Data));
867 animd->ad_VertVis = (UWORD) tag->ti_Data;
868 break;
870 case DTA_ControlPanel:
871 D(bug("[animation.datatype] %s: DTA_ControlPanel\n", __PRETTY_FUNCTION__));
872 if ((animd->ad_Tapedeck) && (tag->ti_Data))
873 animd->ad_Flags |= ANIMDF_CONTROLPANEL;
874 else
875 animd->ad_Flags &= ~(ANIMDF_CONTROLPANEL);
876 break;
878 case DTA_Immediate:
879 D(bug("[animation.datatype] %s: DTA_Immediate\n", __PRETTY_FUNCTION__));
880 if (tag->ti_Data)
881 animd->ad_Flags |= ANIMDF_IMMEDIATE;
882 else
883 animd->ad_Flags &= ~(ANIMDF_IMMEDIATE);
884 break;
886 case ADTA_Remap:
887 D(bug("[animation.datatype] %s: ADTA_Remap\n", __PRETTY_FUNCTION__));
888 if (tag->ti_Data)
889 animd->ad_Flags |= ANIMDF_REMAP;
890 else
891 animd->ad_Flags &= ~(ANIMDF_REMAP);
892 break;
894 #if (0)
895 case ADTA_Repeat:
896 D(bug("[animation.datatype] %s: ADTA_Repeat\n", __PRETTY_FUNCTION__));
897 if (tag->ti_Data)
898 animd->ad_Flags |= ANIMDF_REPEAT;
899 else
900 animd->ad_Flags &= ~(ANIMDF_REPEAT);
901 break;
903 case ADTA_AdaptiveFPS:
904 D(bug("[animation.datatype] %s: ADTA_AdaptiveFPS\n", __PRETTY_FUNCTION__));
905 if (tag->ti_Data)
906 animd->ad_Flags |= ANIMDF_ADAPTFPS;
907 else
908 animd->ad_Flags &= ~(ANIMDF_ADAPTFPS);
909 break;
911 case ADTA_SmartSkip:
912 D(bug("[animation.datatype] %s: ADTA_SmartSkip\n", __PRETTY_FUNCTION__));
913 if (tag->ti_Data)
914 animd->ad_Flags |= ANIMDF_SMARTSKIP;
915 else
916 animd->ad_Flags &= ~(ANIMDF_SMARTSKIP);
917 break;
919 case ADTA_OvertakeScreem:
920 D(bug("[animation.datatype] %s: ADTA_OvertakeScreem\n", __PRETTY_FUNCTION__));
921 if (tag->ti_Data)
922 animd->ad_Flags |= ANIMDF_ADJUSTPALETTE;
923 else
924 animd->ad_Flags &= ~(ANIMDF_ADJUSTPALETTE);
925 break;
926 #endif
927 case OBP_Precision:
928 animd->ad_ColorData.acd_PenPrecison = (ULONG)tag->ti_Data;
929 break;
933 return (DoSuperMethodA (cl, g, (Msg) msg));
936 IPTR DT_NewMethod(struct IClass *cl, Object *o, struct opSet *msg)
938 struct Gadget *g;
939 struct Animation_Data *animd;
940 struct TagItem tdtags[] =
942 { GA_RelVerify, TRUE},
943 { GA_Width, 200},
944 { GA_Height, 15},
945 { TAG_DONE, 0}
948 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
950 g = (struct Gadget *) DoSuperMethodA(cl, o, (Msg) msg);
951 if (g)
953 D(bug("[animation.datatype] %s: Created object 0x%p\n", __PRETTY_FUNCTION__, g));
954 D(bug("[animation.datatype] %s: for '%s'\n", __PRETTY_FUNCTION__, OCLASS((Object *)g)->cl_ID));
955 animd = (struct Animation_Data *) INST_DATA(cl, g);
957 NewList(&animd->ad_FrameData.afd_AnimFrames);
959 animd->ad_Flags = ANIMDF_CONTROLPANEL|ANIMDF_REMAP;
960 #if (1)
961 animd->ad_Flags |= ANIMDF_IMMEDIATE;
962 #endif
963 animd->ad_TimerData.atd_FramesPerSec = 60;
964 animd->ad_TimerData.atd_TicksPerFrame = ANIMPLAYER_TICKFREQ / animd->ad_TimerData.atd_FramesPerSec;
965 animd->ad_ColorData.acd_PenPrecison = PRECISION_IMAGE;
966 animd->ad_ProcStack = 8192;
967 animd->ad_BufferStep = 2; // Try to load 2 frames at a time
968 animd->ad_BufferTime = 3;
970 if (msg->ops_AttrList)
972 D(bug("[animation.datatype] %s: Setting attributes.. \n", __PRETTY_FUNCTION__));
973 DT_SetMethod(cl, g, msg);
976 ReadENVPrefs(g, animd);
978 D(bug("[animation.datatype] %s: Prepare controls.. \n", __PRETTY_FUNCTION__));
980 /* create a tapedeck gadget */
981 if ((animd->ad_Tapedeck = NewObjectA(NULL, "tapedeck.gadget", tdtags)) != NULL)
983 D(bug("[animation.datatype] %s: Tapedeck @ 0x%p\n", __PRETTY_FUNCTION__, animd->ad_Tapedeck));
986 DT_InitPlayer(cl, g, (Msg) msg);
989 D(bug("[animation.datatype] %s: returning %p\n", __PRETTY_FUNCTION__, g));
991 return (IPTR)g;
994 IPTR DT_RemoveDTObject(struct IClass *cl, Object *o, Msg msg)
996 struct Animation_Data *animd = INST_DATA (cl, o);
998 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1000 DoMethod(o, ADTM_STOP);
1002 if (animd->ad_ProcessData)
1004 // disable our subprocesses ..
1005 Signal((struct Task *)animd->ad_BufferProc, (1 << animd->ad_ProcessData->pp_BufferDisable));
1006 Signal((struct Task *)animd->ad_PlayerProc, (1 << animd->ad_ProcessData->pp_PlaybackDisable));
1008 // wait for them to finish ...
1009 while (animd->ad_ProcessData->pp_BufferFlags & PRIVPROCF_ACTIVE)
1011 Delay (1);
1013 while (animd->ad_ProcessData->pp_PlayerFlags & PRIVPROCF_ACTIVE)
1015 Delay (1);
1017 Delay (2);
1020 return DoSuperMethodA(cl, o, msg);
1023 IPTR DT_DisposeMethod(struct IClass *cl, Object *o, Msg msg)
1025 struct Animation_Data *animd = INST_DATA (cl, o);
1026 struct AnimFrame *curFrame = NULL, *lastFrame = NULL;
1028 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1030 if (animd->ad_Player)
1031 DeletePlayer(animd->ad_Player);
1033 if (animd->ad_BufferProc)
1035 Signal((struct Task *)animd->ad_BufferProc, SIGBREAKF_CTRL_C);
1037 while (animd->ad_ProcessData->pp_BufferFlags & PRIVPROCF_RUNNING)
1039 Delay (1);
1043 if (animd->ad_PlayerProc)
1045 Signal((struct Task *)animd->ad_PlayerProc, SIGBREAKF_CTRL_C);
1047 while (animd->ad_ProcessData->pp_PlayerFlags & PRIVPROCF_RUNNING)
1049 Delay (1);
1053 if (animd->ad_ProcessData)
1055 FreeVec(animd->ad_ProcessData->pp_BufferingName);
1056 FreeVec(animd->ad_ProcessData->pp_PlayBackName);
1057 FreeMem(animd->ad_ProcessData, sizeof(struct ProcessPrivate));
1060 ForeachNodeSafe(&animd->ad_FrameData.afd_AnimFrames, curFrame, lastFrame)
1062 D(bug("[animation.datatype] %s: disposing of frame @ 0x%p\n", __PRETTY_FUNCTION__, curFrame));
1063 Remove(&curFrame->af_Node);
1064 FreeMem(curFrame, sizeof(struct AnimFrame));
1067 DoMethod(o, PRIVATE_FREECOLORTABLES);
1069 if (animd->ad_FrameBuffer)
1070 FreeBitMap(animd->ad_FrameBuffer);
1072 if (animd->ad_Tapedeck)
1073 DisposeObject (animd->ad_Tapedeck);
1075 return DoSuperMethodA(cl, o, msg);
1078 IPTR DT_GoActiveMethod(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1080 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1081 return NULL;
1084 IPTR DT_GoInActiveMethod(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1086 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1087 return NULL;
1090 IPTR DT_HandleInputMethod(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1092 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1093 return NULL;
1096 IPTR DT_HelpTestMethod(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1098 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1099 return NULL;
1102 IPTR DT_HitTestMethod(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1104 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1105 return NULL;
1108 IPTR DT_Layout(struct IClass *cl, struct Gadget *g, struct gpLayout *msg)
1110 struct Animation_Data *animd = INST_DATA (cl, (Object *)g);
1111 struct IBox *gadBox;
1112 IPTR RetVal, totalheight;
1114 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1116 animd->ad_Flags |= ANIMDF_LAYOUT;
1118 // cache the window pointer
1119 animd->ad_Window = msg->gpl_GInfo->gi_Window;
1121 RetVal = DoSuperMethodA(cl, (Object *)g, (Msg)msg);
1123 GetAttr(DTA_Domain, (Object *)g, (IPTR *)&gadBox);
1125 animd->ad_RenderLeft = gadBox->Left;
1126 animd->ad_RenderTop = gadBox->Top;
1127 if (gadBox->Width > animd->ad_BitMapHeader.bmh_Width)
1128 animd->ad_RenderWidth = animd->ad_BitMapHeader.bmh_Width;
1129 else
1130 animd->ad_RenderWidth = gadBox->Width;
1132 if (gadBox->Height > animd->ad_BitMapHeader.bmh_Height)
1133 animd->ad_RenderHeight = animd->ad_BitMapHeader.bmh_Height;
1134 else
1135 animd->ad_RenderHeight = gadBox->Height;
1137 totalheight = animd->ad_BitMapHeader.bmh_Height;
1139 // propogate our known dimensions to the tapedeck ..
1140 if (animd->ad_Tapedeck)
1142 struct TagItem tdAttrs[] =
1144 { GA_Left, animd->ad_RenderLeft },
1145 { GA_Top, 0 },
1146 { GA_Width, animd->ad_BitMapHeader.bmh_Width },
1147 { GA_Height, 0 },
1148 { TAG_DONE, 0 }
1151 GetAttr(GA_Height, (Object *)animd->ad_Tapedeck, (IPTR *)&tdAttrs[3].ti_Data);
1152 totalheight += tdAttrs[3].ti_Data;
1153 D(bug("[animation.datatype]: %s: tapedeck height = %d\n", __PRETTY_FUNCTION__, tdAttrs[3].ti_Data));
1155 animd->ad_Flags |= ANIMDF_SHOWPANEL;
1157 // try to adjust to accomodate it ..
1158 if (gadBox->Height >= totalheight)
1159 tdAttrs[1].ti_Data = animd->ad_RenderTop + animd->ad_BitMapHeader.bmh_Height;
1160 else
1162 if (gadBox->Height > tdAttrs[3].ti_Data)
1164 animd->ad_RenderHeight = gadBox->Height - tdAttrs[3].ti_Data;
1165 tdAttrs[1].ti_Data = animd->ad_RenderTop + animd->ad_RenderHeight;
1167 else
1169 // TODO: Adjust the tapedeck height or hide it?
1170 D(bug("[animation.datatype]: %s: tapedeck too big for visible space!\n", __PRETTY_FUNCTION__));
1171 animd->ad_Flags &= ~ANIMDF_SHOWPANEL;
1175 if (animd->ad_RenderWidth > animd->ad_BitMapHeader.bmh_Width)
1176 tdAttrs[2].ti_Data = animd->ad_BitMapHeader.bmh_Width;
1177 else
1178 tdAttrs[2].ti_Data = animd->ad_RenderWidth;
1180 SetAttrsA((Object *)animd->ad_Tapedeck, tdAttrs);
1182 // .. and ask it to layout
1183 // NB - Do not use async layout or it crashes .. =(
1184 DoMethod((Object *)animd->ad_Tapedeck,
1185 GM_LAYOUT, (IPTR)msg->gpl_GInfo, (IPTR)msg->gpl_Initial);
1188 animd->ad_Flags &= ~ANIMDF_LAYOUT;
1191 struct TagItem notifyAttrs[] =
1193 { GA_ID, g->GadgetID },
1194 { DTA_Busy, FALSE },
1195 { DTA_TotalHoriz, animd->ad_BitMapHeader.bmh_Width },
1196 { DTA_VisibleHoriz, animd->ad_RenderWidth },
1197 { DTA_TotalVert, totalheight },
1198 { DTA_VisibleVert, gadBox->Height },
1199 { TAG_DONE, 0 }
1202 DoMethod((Object *) g, OM_NOTIFY, notifyAttrs, (IPTR) msg->gpl_GInfo, 0);
1205 if (animd->ad_Flags & ANIMDF_IMMEDIATE)
1207 DoMethod((Object *)g, ADTM_START, 0);
1210 return RetVal;
1213 IPTR DT_Render(struct IClass *cl, struct Gadget *g, struct gpRender *msg)
1215 struct Animation_Data *animd = INST_DATA (cl, (Object *)g);
1217 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1219 if (!animd->ad_FrameBuffer)
1221 IPTR bmdepth;
1223 bmdepth = GetBitMapAttr(msg->gpr_RPort->BitMap, BMA_DEPTH);
1224 if (bmdepth < animd->ad_BitMapHeader.bmh_Depth)
1225 bmdepth = animd->ad_BitMapHeader.bmh_Depth;
1227 DoMethod((Object *)g, PRIVATE_ALLOCBUFFER, msg->gpr_RPort->BitMap, bmdepth);
1229 if (animd->ad_KeyFrame)
1231 DoMethod((Object *)g, PRIVATE_RENDERBUFFER, animd->ad_KeyFrame);
1235 LockLayer(0, msg->gpr_GInfo->gi_Window->WLayer);
1237 if (animd->ad_FrameBuffer)
1239 BltBitMapRastPort(animd->ad_FrameBuffer,
1240 animd->ad_HorizTop, animd->ad_VertTop,
1241 msg->gpr_RPort,
1242 animd->ad_RenderLeft, animd->ad_RenderTop, animd->ad_RenderWidth, animd->ad_RenderHeight, 0xC0);
1244 else
1246 // for now fill the animations area
1247 SetRPAttrs(msg->gpr_RPort, RPTAG_FgColor, 0xEE8888, TAG_DONE );
1248 RectFill(msg->gpr_RPort,
1249 animd->ad_RenderLeft, animd->ad_RenderTop,
1250 animd->ad_RenderLeft + animd->ad_RenderWidth - 1, animd->ad_RenderTop + animd->ad_RenderHeight - 1);
1253 if (animd->ad_Flags & ANIMDF_SHOWPANEL)
1255 DoMethodA((Object *)animd->ad_Tapedeck, (Msg)msg);
1258 UnlockLayer(msg->gpr_GInfo->gi_Window->WLayer);
1260 return (IPTR)TRUE;
1263 IPTR DT_FrameBox(struct IClass *cl, struct Gadget *g, struct dtFrameBox *msg)
1265 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1266 return NULL;
1269 IPTR DT_ProcLayout(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1271 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1272 return NULL;
1275 IPTR DT_Print(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1277 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1278 return NULL;
1281 IPTR DT_Copy(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1283 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1284 return NULL;
1287 IPTR DT_Trigger(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1289 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1290 return NULL;
1293 IPTR DT_Write(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1295 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1296 return NULL;
1299 IPTR DT_Locate(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1301 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1302 return NULL;
1305 IPTR DT_Pause(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1307 struct Animation_Data *animd = INST_DATA (cl, (Object *)g);
1309 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1311 if (animd->ad_Tapedeck)
1313 struct TagItem tdAttrs[] =
1315 { TDECK_Mode, BUT_STOP },
1316 { TAG_DONE, 0 }
1318 SetAttrsA((Object *)animd->ad_Tapedeck, tdAttrs);
1320 SetConductorState (animd->ad_Player, CONDSTATE_PAUSED, animd->ad_FrameData.afd_FrameCurrent * animd->ad_TimerData.atd_TicksPerFrame);
1322 return NULL;
1325 IPTR DT_Start(struct IClass *cl, struct Gadget *g, struct adtStart *msg)
1327 struct Animation_Data *animd = INST_DATA (cl, (Object *)g);
1329 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1331 if (animd->ad_Tapedeck)
1333 struct TagItem tdAttrs[] =
1335 { TDECK_Mode, BUT_PLAY },
1336 { TAG_DONE, 0 }
1338 SetAttrsA((Object *)animd->ad_Tapedeck, tdAttrs);
1340 SetConductorState(animd->ad_Player, CONDSTATE_RUNNING, msg->asa_Frame * animd->ad_TimerData.atd_TicksPerFrame);
1341 if (animd->ad_ProcessData)
1343 // enable our subprocesses ..
1344 Signal((struct Task *)animd->ad_BufferProc, (1 << animd->ad_ProcessData->pp_BufferEnable));
1345 Signal((struct Task *)animd->ad_PlayerProc, (1 << animd->ad_ProcessData->pp_PlaybackEnable));
1348 return NULL;
1351 IPTR DT_Stop(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1353 struct Animation_Data *animd = INST_DATA (cl, (Object *)g);
1355 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1357 if (animd->ad_Tapedeck)
1359 struct TagItem tdAttrs[] =
1361 { TDECK_Mode, BUT_STOP },
1362 { TAG_DONE, 0 }
1364 SetAttrsA((Object *)animd->ad_Tapedeck, tdAttrs);
1366 SetConductorState(animd->ad_Player, CONDSTATE_STOPPED, 0);
1368 return NULL;
1371 IPTR DT_LoadNewFormatFrame(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1373 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1374 return NULL;
1377 IPTR DT_UnLoadNewFormatFrame(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1379 D(bug("[animation.datatype]: %s()\n", __PRETTY_FUNCTION__));
1380 return NULL;