home *** CD-ROM | disk | FTP | other *** search
- /*
- Skeleton Library for BTD
- Comments by Markus Illenseer
-
- This source tries to give valuable hints to write a Modul
- for BTD. As you will see, this is quite easy, even if it is
- the first time you write a library.
-
- This Skeleton Blanker draws random dots in 4 colors for a certain time,
- then cleans up the screen and starts again. Nothing sophisticated.
-
- Also do refer to BTD.h for global defines and structures.
-
- */
-
- #include <exec/memory.h>
- #include <exec/execbase.h>
- #include <libraries/iffparse.h>
- #include <utility/tagitem.h>
-
- #include <clib/macros.h>
-
- #define __USE_SYSBASE 42
-
- #include <proto/exec.h>
- #include <proto/graphics.h>
- #include <proto/intuition.h>
-
- #include <BTD.h>
-
- struct ExecBase *SysBase;
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
-
- /*
- Don't open any libraries by yourself. This _must_ be done
- in the assembler part of the library.
-
- Be sure your library is re-entrant. Means, one must be able to
- open the library several times at once. So don't use global
- variables other than static (unchangable) ones. Use ModulStruct
- for that purpose.
- */
-
- /* #define DEBUG YES */
-
- /*
- Remove above comment braces (uncomment) to use the Debug-Output.
- Use Terminal connected to serial line, or use sushi to
- redirect the output. Be carefull with modems!
- Remember to add the Debug.lib in the Makefile.
-
- DEBUG_PRINT prints only text.
- DEBUG_PRINTF prints any text and one (!) variable of any kind
-
- This is the only easy way to debug libaries! The SDB or other
- debuggers have some problems with libraires, at least as source
- level debuggers.
-
- */
-
- #ifdef DEBUG
-
- void KPrintF(char *,...);
-
- #define DEBUG_PRINTF(a,b) KPrintF(a,b);
- #define DEBUG_PRINT(a) KPrintF(a)
- #else
- #define DEBUG_PRINTF(a,b)
- #define DEBUG_PRINT(a)
- #endif
-
- /* Now we define the Macros for easy access to the Tag-Entries */
-
- #define DTAG(o) (BTD_Client+(o))
-
- #define ST_Seconds DTAG(0)
-
- /* How much time we give, until the screen is cleaned up again */
-
- #define DEF_SECONDS 5L
- #define MAX_SECONDS 60L
-
- /*
- This structure defines the INTEGER parameters, which the user
- can supply. Skeleton requires only the seconds until it will
- clean up the screen. For other type of paramters, refer to BTD.h
- */
-
- struct BTDInteger SkeletonIntParams[] =
- {
- ST_Seconds,"Seconds",BTDPT_INTEGER,DEF_SECONDS,1L,MAX_SECONDS,TRUE,
- };
-
- /*
- This Taglist is send to the Preference-Programm which will
- open a window with the hereby supplied gadgets. Skeleton needs
- only the one Integer-Slider
- */
-
- struct BTDNode *SkeletonParams[] =
- {
- &SkeletonIntParams[0].BI_Node,
- NULL
- };
-
- /*
- This structure sends some info about the modul to the Preference-
- Programm. MAKE_ID is required for MUI, and will make it possible
- to save the position of this specific preference window.
- First string defines the NAME of the blanker, possibly something
- different than the probaly cryptic filename of the library.
- Second string contains a short description about the blanker. A \n will
- split up the string into a new line.
- Third string should contain your Name and a Copyright message if
- necessary.
-
- The Version Number is not defined here, but in the Assembler-Part
- of the source!
-
- Last Tag is the Node-Info, which will request the user for parameters
- with above given List in BTDNode.
- */
-
- struct BTDInfo SkeletonInfo =
- {
- BTDI_Revision,MAKE_ID('S','K','E','L'),
- "Skeleton Blanker","Skeleton is intended for programmers\n among you peoples!\nJust a simple and boring blanker modul","Markus Illenseer 1994",
- SkeletonParams
- };
-
-
- /*
- This is our 'global' structure for the skeleton blanker. I refer to
- it as ModulStruct.
- Remember that this is the only way to hold global data for each
- invoked modul out of this library. The Skeleton Blanker will only
- hold info about the supplied second-parameter and about the time when
- the screen was cleaned up the last time. And of course it will hold
- the BTDDrawInfo, which contains lot of required info, eg. RastPort.
-
- If you require anything sophisticated like ImageData, have a look into
- the other supplied modules.
- */
-
- struct SkeletonStruct
- {
- struct BTDDrawInfo *BTDDrawInfo;
- LONG Seconds;
- LONG Time;
- LONG RandN,RandF,RandI;
- };
-
- /*
- The next two functions are some sophisticated Randomnizers
- which are based upon (mathematic) statistic defined true
- Randomnizers. All they need is a seed, afterwards they will use
- the current time as a base for future randoms.
-
- Normally we would have some global variabled for RandN, RandF and
- RandI, but as we need to be re-entrant, we need to store this info
- in the ModulStruct above.
- */
-
- void __regargs InitRandom(struct SkeletonStruct *Skel,ULONG Instance)
-
- {
- ULONG Time[2];
-
- CurrentTime (&Time[0],&Time[1]);
- Skel->RandN=(LONG)Time[0];
-
- if (Time[1]<1024L) Time[1]|=1;
- else Time[1]>>=10;
- Time[1]^=Instance;
-
- Skel->RandF=4*Time[1]+1;
- Skel->RandI=2*Time[1]+1;
- }
-
- WORD __regargs Random(struct SkeletonStruct *Skel,WORD Max)
-
- {
- Skel->RandN=Skel->RandF*Skel->RandN+Skel->RandI;
- if (Skel->RandN<0L) Skel->RandN=-Skel->RandN;
-
- return (WORD)(Skel->RandN%Max);
- }
-
-
- /*
- This function is actually a copy of the FindTag-function of clib/utility,
- but this one is a bit faster and also returns a supplied Default
- when Tag-ID wasn't found
- */
-
- ULONG FindTagData(struct TagItem *TagList,Tag ID,ULONG Default)
-
- {
- while (TagList)
- switch (TagList->ti_Tag)
- {
- case TAG_DONE:
- return Default;
- case TAG_MORE:
- TagList=(struct TagItem *)TagList->ti_Data;
- break;
- default:
- if (TagList->ti_Tag==ID) return TagList->ti_Data;
- else TagList++;
- }
- return Default;
- }
-
- /*
- This is the first procedure every modul requires. It will initialize
- the modul, eat required memory, set colors, whatever. This function
- should be as short as possible. No heavy calculations belong here
-
- struct ModulStruct InitModul(struct TagItem *TagList)
-
- Input: TagList is supplied from BTD-CX, the server, and will send
- you all the parameters you requested from the user in above
- structure BTDInfo.
-
- Output: Fully initialized ModulStruct for further use, is returned
- to the server, who will then invoke AnimModul() with this
- structure.
- */
-
- struct SkeletonStruct *InitSkeleton(struct TagItem *TagList)
-
- {
- struct SkeletonStruct *SkelStruct;
- struct BTDDrawInfo *BTDDrawInfo;
- ULONG *Error,Dummy,Instance,Index;
-
- DEBUG_PRINT("Skeleton: Initialize Modul\n");
-
- /* Find the Entry for the BTDDrawInfo (see BTD.h) and make local copy */
-
- if ((BTDDrawInfo=(struct BTDDrawInfo *)
- FindTagData(TagList,BTD_DrawInfo,NULL))==NULL) return NULL;
-
- /*
- Get us the Dummy, which will contain Error-Messages if we fail to
- initialize our Modul. The server then knows we failed and will display
- a black part on the screen
- */
-
- Error=(LONG *)FindTagData(TagList,BTD_Error,(ULONG)&Dummy);
-
- /*
- Allocate the required MEM for the SkeletonStruct, on error report
- a Memory-error to the server and return home
- */
-
- if ((SkelStruct=AllocVec(sizeof(struct SkeletonStruct),MEMF_PUBLIC|MEMF_CLEAR))==NULL)
- {
- *Error=BTDERR_Memory;
- return NULL;
- }
-
- /*
- copy local BTDDrawInfo into global structure for future use in
- AnimModul()
- */
-
- SkelStruct->BTDDrawInfo=BTDDrawInfo;
-
- /*
- The Instance is sort of OpenCounter and is often used to initialize
- a Randomnizer, so that same modules won't use same random-seed
- */
-
- Instance=FindTagData(TagList,BTD_Instance,0L);
-
- InitRandom(SkelStruct,Instance);
-
- /* Get us the user-supplied parameter SECONDS */
-
- SkelStruct->Seconds=FindTagData(TagList,ST_Seconds,DEF_SECONDS);
-
-
- /*
- Set an initial value, not really required to do so, as we allocated
- the SkelStruct with MEMF_CLEAR flag
- */
-
- SkelStruct->Time=0L;
-
-
- /*
- Now set our requested colors to any RGB-Tripel, you MUST use
- this array, otherwise you won't get your colors, but anything
- else. Can yield to a Guru if you do that!
- */
-
- for(Index=0; Index<4; Index++)
- {
- BTDDrawInfo->BDI_Red[BTDDrawInfo->BDI_Pens[Index]]=Random(SkelStruct,255);
- BTDDrawInfo->BDI_Green[BTDDrawInfo->BDI_Pens[Index]]=Random(SkelStruct,255);
- BTDDrawInfo->BDI_Blue[BTDDrawInfo->BDI_Pens[Index]]=Random(SkelStruct,255);
- BTDDrawInfo->BDI_Changed[BTDDrawInfo->BDI_Pens[Index]]=TRUE;
- }
-
- /* Everything's done. Return the structure for future use */
-
- return SkelStruct;
- }
-
- /* This is the second procedure required for every modul. It should
- do anything required to free resources, free mem and so on.
-
- void EndSkeleton(struct ModulStruct *ModulStruct)
-
- Input: ModulStruct supplied from server BTD-CX
- Output: None. Should all be freed up */
-
- void EndSkeleton(struct SkeletonStruct *SkelStruct)
-
- {
- DEBUG_PRINT("Skeleton: about to finish Modul\n");
- FreeVec (SkelStruct);
- }
-
- /* Third procedure required for a modul. This one is called by the
- server every once in a second. You are not allowed to do anything
- which would yield into a FOREVER-Loop or do anything like a busy-loop
- or something unstoppable.
-
- If you need to do a loop from TOP to BOTTOM (TOP+HEIGHT), add a counter
- in ModulStruct: ypos. Best would even to add xpos also, if required.
-
- These restictions are all due to the fact, that the user want's his
- screen back as fast as possible!
-
- void AnimSkeleton(struct ModulStruct *ModulStruct)
-
- Input: ModulStruct supplied from server BTD-CX.
- OutPut: None.
-
- */
-
- void AnimSkeleton(struct SkeletonStruct *SkelStruct)
-
- {
- ULONG Seconds,Micros;
-
- /* Hum, below DEBUG_PRINT not that usefull. Remove it, or replace
- it with anything you need to check */
-
- DEBUG_PRINT("Skeleton: Animate\n");
-
- /* Get us the current time. */
-
- CurrentTime (&Seconds,&Micros);
-
- if (Seconds>=SkelStruct->Time)
- {
-
- /* Wait for that the pointer is at the top of the screen */
- WaitTOF();
-
- /* Calculate next timeslide */
-
- SkelStruct->Time=Seconds+SkelStruct->Seconds;
-
- /* Set Background color, attention, have a look at the color! */
-
- SetAPen(SkelStruct->BTDDrawInfo->BDI_RPort,BTD_BgPen);
-
- /* Fill our part of the screen with background color */
-
- RectFill (SkelStruct->BTDDrawInfo->BDI_RPort,
- SkelStruct->BTDDrawInfo->BDI_Left,
- SkelStruct->BTDDrawInfo->BDI_Top,
- SkelStruct->BTDDrawInfo->BDI_Left+SkelStruct->BTDDrawInfo->BDI_Width-1,
- SkelStruct->BTDDrawInfo->BDI_Top+SkelStruct->BTDDrawInfo->BDI_Height-1);
- }
-
- /* Now let's do the magic Animation of Skeleton */
-
- /* Choose Random Color and set Pen accordingly */
-
- SetAPen (SkelStruct->BTDDrawInfo->BDI_RPort,
- SkelStruct->BTDDrawInfo->BDI_Pens[Random(SkelStruct,4)]);
-
- /*
- You can speed up the process, if you store LEFT, TOP, HEIGHT. WIDTH
- in ModulStruct directly, rather than in a pointer to BTDDrawInfo
- */
-
- WritePixel (SkelStruct->BTDDrawInfo->BDI_RPort,
- SkelStruct->BTDDrawInfo->BDI_Left+Random(SkelStruct,SkelStruct->BTDDrawInfo->BDI_Width),
- SkelStruct->BTDDrawInfo->BDI_Top+Random(SkelStruct,SkelStruct->BTDDrawInfo->BDI_Height));
- }
-
- ULONG PenCountSkeleton(struct TagItem *TagList)
-
- {
-
- /*
- We request to use 4 colors, we _will_ get them!
- We would even get 324 colors, if there is a screenmode with that
- many colors, and the servers gives us that many.
- If the servers sees that we need more colors as he can provide with
- his used screenmode, he won't use our modul
- */
-
- return 4L;
- }
-