home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / TolleUhr13.lha / TolleUhr / TolleUhr_C / TolleUhr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-12  |  47.2 KB  |  1,512 lines

  1. #define VERSION "1.3 (18.5.95)"
  2. /***************************************************************************
  3. *                                  *                                       *
  4. * Programm: TolleUhr               * Version: s.o.                         *
  5. *                                  *                                       *
  6. ****************************************************************************
  7. *                                                                          *
  8. * Dieses Programm ist Public-Domain, d.h. wer immer Lust dazu hat, darf    *
  9. * dieses Programm kopieren, umschreiben, usw., vorausgesetzt:              *
  10. *                                                                          *
  11. * 1. Die Autorenliste bleibt voll erhalten. (auch in About-Requestern)     *
  12. * 2. Wer etwas am Programm verbricht, muß sich auch dazuschreiben.         *
  13. *                                                                          *
  14. * Es wird keine Haftung für Schäden irgendwelcher Art übernommen.          *
  15. *                                                                          *
  16. * Autoren: Matthias Fleischer  Adlerstraße 30 7302 Ostfildern 2            *
  17. *          (fleischr@izfm.uni-stuttgart.de)                                *
  18. *          .                                                               *
  19. *          .(Auf Paul, schaff was !)                                       *
  20. *                                                                          *
  21. *          Gunther Nikl  Hans-Beimler-Straße 17 19370 Parchim              *
  22. *          (gnikl@informatik.uni-rostock.de)                               *
  23. *                                                                          *
  24. ***************************************************************************/
  25.  
  26. /**** includes ****/
  27.  
  28. #include <dos/dos.h>
  29. #include <dos/rdargs.h>
  30. #include <exec/memory.h>
  31. #include <devices/audio.h>
  32. #include <devices/timer.h>
  33. #include <graphics/gfxmacros.h>
  34. #include <intuition/intuition.h>
  35. #include <intuition/gadgetclass.h>
  36. #include <datatypes/pictureclass.h>
  37. #include <libraries/gadtools.h>
  38. #include <workbench/startup.h>
  39. #include <workbench/workbench.h>
  40. #ifdef __GNUC__
  41. #define BltBitMap _BltBitMap
  42. #define CreateGadgetA _CreateGadgetA
  43. #if __GNUC_MINOR__ > 3
  44. #define AddGList _AddGList
  45. #define BuildEasyRequestArgs _BuildEasyRequestArgs
  46. #endif
  47. #endif
  48. #include <proto/datatypes.h>
  49. #include <proto/intuition.h>
  50. #include <proto/graphics.h>
  51. #include <proto/gadtools.h>
  52. #include <proto/icon.h>
  53. #include <proto/exec.h>
  54. #include <proto/alib.h>
  55. #include <proto/dos.h>
  56. #ifdef __GNUC__
  57. #undef BltBitMap
  58. LONG BltBitMap();
  59. #undef CreateGadgetA
  60. struct Gadget *CreateGadgetA();
  61. #if __GNUC_MINOR__ > 3
  62. #undef AddGList
  63. void AddGList();
  64. #undef BuildEasyRequestArgs
  65. struct Window *BuildEasyRequestArgs();
  66. #endif
  67. #endif
  68. #include <clib/macros.h>
  69. #include <string.h>
  70.  
  71. /* structure definition */
  72.  
  73. struct BackFillInfo {
  74.   STRPTR               PictureName;
  75.   Object              *PictureObject;
  76.   struct BitMapHeader *BitMapHeader;
  77.   struct BitMap       *BitMap;
  78. };
  79.  
  80. /* magic defines ;-( */
  81.  
  82. #define exit _exit
  83. #define main _main
  84. #define WbMsg _WBenchMsg
  85.  
  86. /* externe Symbole */
  87.  
  88. extern void exit(int);
  89. extern struct WBStartup *WbMsg;
  90.  
  91. /**** Sonstiges ****/
  92.  
  93. const char version[]="$VER: TolleUhr "VERSION" by M.Fleischer and G.Nikl in 1993/95";
  94.  
  95. #define aboutstring (version+6)
  96.  
  97. typedef struct IORequest *iorequest;
  98. typedef struct timerequest *iotime;
  99. typedef struct IOAudio *ioaudio;
  100.  
  101. /**** Eigene Prototypen ****/
  102.  
  103. void loadimage(void);
  104. void openall(void);
  105. void readargs(void);
  106. void mergetooltypes(void);
  107. void parseargs(char *argstring,int laenge);
  108. int xtod(int a);
  109. void setargs(void);
  110. void readstr(char *dest,char *sorc,int n);
  111. int main(void);
  112. void closeall(int retval);
  113. void newsize1(void); /* Löscht BitPlanes */
  114. void closewindowsafely(struct Window *win);
  115. void checkaboutreq(void);
  116. void checkwindows(void);
  117. void newsize2(void); /* Holt BitPlanes */
  118. int nexttick(void);
  119. void zifferblatt (void);
  120. void rahmen(void);
  121. void zeichnen(void);
  122. void zeiger(ULONG winkel,int lfactor,int offset,int apen,int open);
  123. void setpattern(void);
  124. void saveprefs(void);
  125. void setstr(char *dest,UBYTE *sourc,int n);
  126. int dtox(int a);
  127. void testifalarm(void);
  128. void starttune(UWORD *tune);
  129. void playnote(void);
  130. void endtune(void);
  131. struct Window *createrequest
  132. ( struct TagItem windowtags[],ULONG idcmp,int anzgadgets,struct TagItem *gadgettags[],
  133.   struct NewGadget gadgets[],ULONG edge[][3],struct Gadget **glistpointer);
  134. struct Window *myOpenWindow(struct TagItem *wintags,ULONG idcmp);
  135. void CopyTiledBitMap
  136. ( struct BitMap *Src,LONG SrcSizeX,LONG SrcSizeY,
  137.   struct BitMap *Dst,LONG DstSizeX,LONG DstSizeY);
  138.  
  139. /**** disable commandline parsing with libnix (gcc) ****/
  140.  
  141. int __nocommandline=1;
  142.  
  143. /**** Ressourcen müssen global sein (wegen cleanup) ****/
  144.  
  145. struct Library *DataTypesBase=NULL;
  146. struct MsgPort *wport=NULL; /* shared idcmpport */
  147. struct Screen *pubscreen=NULL; /* Den blocken wir */
  148. struct Window *mainwin=NULL,*almwin=NULL,*colwin=NULL,*aboutreq=NULL; /* 4 Fenster */
  149. struct Gadget *almgads,*colgads;
  150. struct Menu *menus=NULL;
  151. APTR visi=NULL;
  152. struct MsgPort *tport=NULL; /* Timer */
  153. iotime treq=NULL;
  154. BYTE notime=1;
  155. BYTE timesent=0;
  156. struct DiskObject *dobj=NULL;
  157. APTR buf=NULL; /* BitPlane für Area-Befehle */
  158. struct MsgPort *audport=NULL; /* Alles für audio.device */
  159. ioaudio audreq[2]={ NULL,NULL };
  160. BYTE noaudio=1; /* device geöffnet ? */
  161. BYTE nosound=1; /* Soundkanal geholt ? */
  162. BYTE audsent[2]={ 0,0 }; /* Sound gespielt ? */
  163. BYTE *waveform=NULL;
  164. char *string=NULL;
  165. int changedlock=0;
  166. int changedpri=0;
  167.  
  168. /**** Voreinstellungen ****/
  169.  
  170. long links =50;
  171. long oben  =50;
  172. long breite=108;
  173. long hoehe =54;
  174. int sekunden=0;
  175. int oval=0;
  176. int zeigen=1;
  177. int zeigertyp=2;
  178. int zeigerbreite=2;
  179. int schatten=0;
  180. int rahmenanz=3;
  181. UBYTE pens[]={ 2,0,2,0,2,1,2,2,2,2,0,1,2,3 };
  182.              /* sec,mina,mino,stda,stdo,shdw,12,1/4,1/12,1/60,b0,b1,b2,b3 */
  183. UBYTE must[]={ 0,0,0,0 };
  184. UBYTE *colour;
  185. ULONG almin=0,mi,alstd=12,st; /* Alarmzeit */
  186. int smarthour=0;
  187. int alarm=0;
  188. int chime=0;
  189. int closegad=0;
  190. int useimage=0;
  191. int remap=1;
  192.  
  193. /**** Globale Variablen ****/
  194.  
  195. ULONG maskx,masky;
  196. UWORD muster[8][2];
  197. int doublex,doubley;
  198. long xoffset,yoffset;
  199. long boleft,botop,breit2,hoehe2;
  200. long hires,interlace,active=0;
  201. ULONG std,min,sec;
  202. long redrawx1,redrawx2,redrawy1,redrawy2; /* Gezeichneter Bereich bezogen
  203.                                              auf Fensterkoordinaten */
  204. struct TagItem notags[]={ TAG_DONE }; /* Leeres TagItem-Feld */
  205. struct RastPort *rport1; /* Fenster */
  206. struct BitMap abitmap; /* Buffer */
  207. struct RastPort rport2;
  208. struct TmpRas temp; /* Für Area-Befehle */
  209. struct AreaInfo info;
  210. SHORT table[13]; /* Für Area-Befehle */
  211. UWORD *playtune;
  212. struct TextAttr topaz={ "topaz.font",8,FS_NORMAL,FPF_ROMFONT };
  213. struct WBArg progarg;
  214. struct BackFillInfo bfi;
  215. STRPTR namebuf;
  216. ULONG oldpri;
  217. BPTR oldlock;
  218.  
  219. /**** Tabellen ****/
  220.  
  221. long handwidth[]={ 4000,3250,2500,1750,1000 };
  222.  
  223. long sizes[][4]={ 0,0,3,2, -3,0,3,2, -3,-2,3,2, 0,2,0,-4 };  /* Für Gadgets */
  224.  
  225. struct Gadget gadgets[]={
  226. { &gadgets[1],0,0,1,1,GADGHNONE,
  227.   GACT_RELVERIFY,CLOSE,NULL,NULL,NULL,0,NULL,0,NULL },       /* Schließ-Gadget */
  228. { &gadgets[2],0,0,1,1,GADGHNONE|GRELRIGHT,
  229.   GACT_RELVERIFY,WUPFRONT,NULL,NULL,NULL,0,NULL,0,NULL },    /* Tiefen-Gadget */
  230. { &gadgets[3],0,0,1,1,GADGHNONE|GRELRIGHT|GRELBOTTOM,
  231.   GACT_RELVERIFY,SIZING,NULL,NULL,NULL,0,NULL,0,NULL },      /* Größen-Gadget */
  232. { NULL       ,0,0,1,1,GADGHNONE|GRELWIDTH|GRELHEIGHT,
  233.   GACT_RELVERIFY,WDRAGGING,NULL,NULL,NULL,0,NULL,0,NULL } }; /* Zieh-Gadget */
  234.  
  235. struct TagItem windowtags[]=
  236. { WA_Left,0,WA_Top,0,WA_Width,0,WA_Height,0, /* Fensterkoordinaten (s.u.) */
  237.   WA_PubScreen,0,                            /* kommt später rein */
  238.   WA_MinWidth,10,WA_MinHeight,10,WA_MaxWidth,-1,WA_MaxHeight,-1,
  239.   WA_Gadgets,(ULONG)gadgets,                 /* Liste von Gadgets */
  240.   WA_Borderless,TRUE,                        /* Rahmen mach ich selber */
  241.   WA_SimpleRefresh,TRUE,                     /* Spart CHIP-MEM */
  242.   WA_NewLookMenus,TRUE,
  243.   WA_AutoAdjust,TRUE,
  244.   WA_ScreenTitle,(ULONG)aboutstring,
  245.   TAG_DONE };
  246.  
  247. #define MAINIDCMP NEWSIZE|CLOSEWINDOW|MENUPICK|REFRESHWINDOW|ACTIVEWINDOW|INACTIVEWINDOW
  248.  
  249. struct TagItem menutags[]=
  250. { GTMN_NewLookMenus,TRUE,TAG_DONE };
  251.  
  252. struct NewMenu menulist[]= /* Liste von Menus */
  253. { { NM_TITLE,"Project",  NULL,0,0,NULL },
  254.   { NM_ITEM, "About",    "?",0,0,NULL },
  255.   { NM_ITEM, "Quit",     "Q",0,NULL },
  256.   { NM_TITLE,"Settings", NULL,0,0,NULL },
  257.   { NM_ITEM, "Seconds",  NULL,CHECKIT|MENUTOGGLE,0,NULL },
  258.   { NM_ITEM, "Oval",     NULL,CHECKIT|MENUTOGGLE,0,NULL },
  259.   { NM_ITEM, "Show",     NULL,0,0,NULL },
  260.   { NM_SUB,  "Minutes",  NULL,CHECKIT,2|4|8|16,NULL },
  261.   { NM_SUB,  "Hours",    NULL,CHECKIT,1|4|8|16,NULL },
  262.   { NM_SUB,  "Quarter",  NULL,CHECKIT,1|2|8|16,NULL },
  263.   { NM_SUB,  "One",      NULL,CHECKIT,1|2|4|16,NULL },
  264.   { NM_SUB,  "None",     NULL,CHECKIT,1|2|4| 8,NULL },
  265.   { NM_ITEM, "Hands",    NULL,0,0,NULL },
  266.   { NM_SUB,  "Line",     NULL,CHECKIT,2|4|8,NULL },
  267.   { NM_SUB,  "Triangle", NULL,CHECKIT,1|4|8,NULL },
  268.   { NM_SUB,  "Rhombus",  NULL,CHECKIT,1|2|8,NULL },
  269.   { NM_SUB,  "Rectangle",NULL,CHECKIT,1|2|4,NULL },
  270.   { NM_SUB,  NM_BARLABEL,NULL,0,0,NULL },
  271.   { NM_SUB,  "Very Thin",NULL,CHECKIT,64|128|256|512,NULL },
  272.   { NM_SUB,  "Thin",     NULL,CHECKIT,32|128|256|512,NULL },
  273.   { NM_SUB,  "Normal",   NULL,CHECKIT,32|64|256|512,NULL },
  274.   { NM_SUB,  "Thick",    NULL,CHECKIT,32|64|128|512,NULL },
  275.   { NM_SUB,  "Very Thick",NULL,CHECKIT,32|64|128|256,NULL },
  276.   { NM_ITEM, "Shadow",   NULL,CHECKIT|MENUTOGGLE,0,NULL },
  277.   { NM_ITEM, "Border",   NULL,0,0,NULL },
  278.   { NM_SUB,  "None",     NULL,CHECKIT,2|4,NULL },
  279.   { NM_SUB,  "Single",   NULL,CHECKIT,1|4,NULL },
  280.   { NM_SUB,  "Double",   NULL,CHECKIT,1|2,NULL },
  281.   { NM_SUB,  NM_BARLABEL,NULL,0,0,NULL },
  282.   { NM_SUB,  "Hires",    NULL,CHECKIT|MENUTOGGLE,0,NULL },
  283.   { NM_SUB,  "Interlace",NULL,CHECKIT|MENUTOGGLE,0,NULL },
  284.   { NM_ITEM, "Chime",    NULL,0,0,NULL },
  285.   { NM_SUB,  "None",     NULL,CHECKIT,2|4,NULL },
  286.   { NM_SUB,  "Hours",    NULL,CHECKIT,1|4,NULL },
  287.   { NM_SUB,  "Quarter",  NULL,CHECKIT,1|2,NULL },
  288.   { NM_SUB,  NM_BARLABEL,NULL,0,0,NULL },
  289.   { NM_SUB,  "Smart",    NULL,CHECKIT|MENUTOGGLE,0,NULL },
  290.   { NM_ITEM, "Alarm",    NULL,0,0,NULL },
  291.   { NM_SUB,  "Set",      NULL,0,0,NULL },
  292.   { NM_SUB,  "On",       NULL,CHECKIT|MENUTOGGLE,0,NULL },
  293.   { NM_ITEM, "Use Image",NULL,CHECKIT|MENUTOGGLE,0,NULL },
  294.   { NM_ITEM, "Close Gadget", NULL,CHECKIT|MENUTOGGLE,0,NULL },
  295.   { NM_ITEM, NM_BARLABEL,NULL,0,0,NULL },
  296.   { NM_ITEM, "Save Prefs","S",0,0,NULL },
  297.   { NM_TITLE,"Colors",   NULL,0,0,NULL }, /* Colours Menu */
  298.   { NM_ITEM, "Seconds",  NULL,0,0,NULL },
  299.   { NM_ITEM, "Min. APen",NULL,0,0,NULL },
  300.   { NM_ITEM, "Min. OPen",NULL,0,0,NULL },
  301.   { NM_ITEM, "Hour APen",NULL,0,0,NULL },
  302.   { NM_ITEM, "Hour OPen",NULL,0,0,NULL },
  303.   { NM_ITEM, "Shadow",   NULL,0,0,NULL },
  304.   { NM_ITEM, "12",       NULL,0,0,NULL },
  305.   { NM_ITEM, "Quarter",  NULL,0,0,NULL },
  306.   { NM_ITEM, "Hours",    NULL,0,0,NULL },
  307.   { NM_ITEM, "Minutes",  NULL,0,0,NULL },
  308.   { NM_ITEM, "Border 0", NULL,0,0,NULL },
  309.   { NM_ITEM, "Border 1", NULL,0,0,NULL },
  310.   { NM_ITEM, "Border 2", NULL,0,0,NULL },
  311.   { NM_ITEM, "Border 3", NULL,0,0,NULL },
  312.   { NM_TITLE,"Pattern",  NULL,0,0,NULL },
  313.   { NM_ITEM, "Color 0",  NULL,0,0,NULL },
  314.   { NM_ITEM, "Color 1",  NULL,0,0,NULL },
  315.   { NM_ITEM, "Color 2",  NULL,0,0,NULL },
  316.   { NM_ITEM, "Color 3",  NULL,0,0,NULL },
  317.   { NM_END,NULL,NULL,0,0,NULL } };
  318.  
  319. BYTE sinus[]= /* sinus-Tabelle */
  320. { 0,13,26,39,52,64,75,85,94,103,110,116,121,124,126,
  321.   127,126,124,121,116,110,103,94,85,75,64,52,39,26,13,
  322.   0,-13,-26,-39,-52,-64,-75,-85,-94,-103,-110,-116,-121,-124,-126,
  323.   -127,-126,-124,-121,-116,-110,-103,-94,-85,-75,-64,-52,-39,-26,-13 },
  324.      cosinus[]= /* cosinus-Tabelle */
  325. { 127,126,124,121,116,110,103,94,85,75,64,52,39,26,13,
  326.   0,-13,-26,-39,-52,-64,-75,-85,-94,-103,-110,-116,-121,-124,-126,
  327.   -127,-126,-124,-121,-116,-110,-103,-94,-85,-75,-64,-52,-39,-26,-13,
  328.   0,13,26,39,52,64,75,85,94,103,110,116,121,124,126 };
  329.  
  330. BYTE srect[]= /* Für rechteckiges Zifferblatt */
  331. { 0,13,27,41,57,73,92,111,124,127,127,127,127,127,127,
  332.   127,127,127,127,127,127,127,124,111,92,73,57,41,27,13,
  333.   0,-13,-27,-41,-57,-73,-92,-111,-124,-127,-127,-127,-127,-127,-127,
  334.   -127,-127,-127,-127,-127,-127,-127,-124,-111,-92,-73,-57,-41,-27,-13 },
  335.      crect[]=
  336. { 127,127,127,127,127,127,127,124,111,92,73,57,41,27,13,
  337.   0,-13,-27,-41,-57,-73,-92,-111,-124,-127,-127,-127,-127,-127,-127,
  338.   -127,-127,-127,-127,-127,-127,-127,-124,-111,-92,-73,-57,-41,-27,-13,
  339.   0,13,27,41,57,73,92,111,124,127,127,127,127,127,127 };
  340.  
  341. UBYTE pent[]={ 6,8,8,7,8,8,7,8,8,7,8,8 }; /* Pen-Tabelle f. Zifferblatt */
  342.  
  343. BYTE dx1[]= /* Daten für Zifferblatt */
  344. { -2, 2, 1,-2, 1, 2,-2,-2,-1,-2,-1,-2 },
  345.      dy1[]=
  346. { -4,-1,-2,-2, 2, 1,-2, 1, 2,-2,-2,-1 },
  347.      dx2[]=
  348. {  4,-2, 1, 4, 1,-2, 4, 2,-1, 4,-1, 2 },
  349.      dy2[]=
  350. {  0, 3, 2, 0,-2,-3, 0,-3,-2, 0, 2, 3 },
  351.      dx3[]=
  352. {  0,-2,-3, 0,-3,-2, 0, 2, 3, 0, 3, 2 },
  353.      dy3[]=
  354. {  8,-1, 2, 4,-2, 1, 4, 1,-2, 4, 2,-1 },
  355.      dx4[]=
  356. { -4, 2,-1,-4,-1, 2,-4,-2, 1,-4, 1,-2 },
  357.      dy4[]=
  358. {  0,-3,-2, 0, 2, 3, 0, 3, 2, 0,-2,-3 };
  359.  
  360.   /* Requester 1 */
  361. struct TagItem window2tags[]= /* Palette-Requester */
  362. { WA_Gadgets,0, /* kommen später rein */
  363.   WA_PubScreen,0, /* das auch */
  364.   WA_Left,100,WA_Top,100,WA_InnerWidth,144,WA_InnerHeight,72, /* Fensterkoordinaten */
  365.   WA_Title,(ULONG)"Choose one:",
  366.   WA_ScreenTitle,(ULONG)aboutstring,
  367.   WA_DepthGadget,1,WA_CloseGadget,1,WA_DragBar,1,WA_Activate,1,
  368.   TAG_DONE };
  369.  
  370. #define COLIDCMP CLOSEWINDOW|PALETTEIDCMP
  371.  
  372. ULONG window2goff[][3]=
  373. { 4,2,PALETTE_KIND };
  374.  
  375. struct NewGadget window2gad[]=
  376. { 0,0,136,68,NULL,NULL,0,0,NULL,0 };
  377.  
  378. struct TagItem window2gadtags1[]=
  379. { GTPA_Depth,0,TAG_DONE };
  380.  
  381. struct TagItem *window2gadtags[]=
  382. { window2gadtags1 };
  383.  
  384.   /* Requester 2 */
  385. struct TagItem window3tags[]= /* Alarmzeit-Requester */
  386. { WA_Gadgets,0, /* kommen später rein */
  387.   WA_PubScreen,0, /* das auch */
  388.   WA_Left,100,WA_Top,100,WA_InnerWidth,144,WA_InnerHeight,72,
  389.   WA_Title,(ULONG)"Alarm",
  390.   WA_ScreenTitle,(ULONG)aboutstring,
  391.   WA_DepthGadget,1,WA_CloseGadget,1,WA_DragBar,1,WA_Activate,1,
  392.   TAG_DONE };
  393.  
  394. #define ALMIDCMP CLOSEWINDOW|BUTTONIDCMP|SLIDERIDCMP
  395.  
  396. ULONG window3goff[][3]=
  397. { { 42,15,SLIDER_KIND },
  398.   { 82,15,SLIDER_KIND },
  399.   {  2,58,BUTTON_KIND },
  400.   { 76,58,BUTTON_KIND } };
  401.  
  402. struct NewGadget window3gad[]=
  403. { { 0,0,20,39,NULL,    &topaz,1,0,NULL,0 },
  404.   { 0,0,20,39,NULL,    &topaz,2,0,NULL,0 },
  405.   { 0,0,66,12,"Use",   &topaz,3,0,NULL,0 },
  406.   { 0,0,66,12,"Cancel",&topaz,4,0,NULL,0 } };
  407.  
  408. struct TagItem window3gadtags1[]=
  409. { GTSL_Level,1,PGA_Freedom,LORIENT_VERT,GTSL_LevelPlace,PLACETEXT_ABOVE,
  410.   GTSL_MaxLevelLen,10,GTSL_Min,1,GTSL_Max,12,GTSL_LevelFormat,
  411.   (ULONG)"%2ld",GA_RelVerify,1,TAG_DONE },
  412.                window3gadtags2[]=
  413. { GTSL_Level,0,PGA_Freedom,LORIENT_VERT,GTSL_LevelPlace,PLACETEXT_ABOVE,
  414.   GTSL_MaxLevelLen,5,GTSL_Min,0,GTSL_Max,59,GTSL_LevelFormat,
  415.   (ULONG)"%02ld",GA_RelVerify,1,TAG_DONE };
  416.  
  417. struct TagItem *window3gadtags[]=
  418. { window3gadtags1,window3gadtags2,notags,notags };
  419.  
  420. UBYTE camap[]={ 1,2,4,8 }; /* Sound Channel Allocation Map */
  421.  
  422. UWORD alarmtune[]={ 800,800,800,800,800,800,800,1600,
  423.                     800,800,800,800,800,800,800,1600,
  424.                     800,800,800,800,800,800,800,1600,
  425.                     800,800,800,800,800,800,800,1600,
  426.                     800,800,800,800,800,800,800,4,0 };
  427.  
  428. UWORD hourtune[]={ 800,1600,800,1600,800,1600,800,1600,
  429.                    800,1600,800,1600,800,1600,800,1600,
  430.                    800,1600,800,1600,800,1600,800,4,0 };
  431.  
  432. UWORD quartertune[]={ 400,400,400,400,400,4,0 };
  433.  
  434. char template[]=
  435. "/M,TOP/N,LEFT/N,WIDTH/N,HEIGHT/N,SECONDS/S,PATTERN/K,OVAL/S,SHADOW/S,"
  436. "SHOWFACE/N,HANDTYPE/N,HANDWIDTH/N,DRAWPENS/K,BORDERTYPE/N,CHIME/N,"
  437. "CLOSEGAD/S,USEIMAGE/S,NOREMAP/S,IMAGE/K,PUBSCREEN/K,TASKPRI/N";
  438.  
  439. char *tooltypes[]={
  440. "TOP","LEFT","WIDTH","HEIGHT","SHOWFACE","HANDTYPE","HANDWIDTH","BORDERTYPE",
  441. "CHIME","SECONDS","OVAL","SHADOW","CLOSEGAD","USEIMAGE","DRAWPENS","PATTERN" };
  442.  
  443. void loadimage(void)
  444. { static struct TagItem dt1tags[]=
  445.   { PDTA_Screen          ,0,
  446.     PDTA_Remap           ,0,
  447.     PDTA_FreeSourceBitMap,TRUE,
  448.     DTA_GroupID          ,GID_PICTURE,
  449.     OBP_Precision        ,PRECISION_IMAGE,
  450.     TAG_DONE };
  451.   static struct TagItem dt2tags[]=
  452.   { PDTA_BitMapHeader,(ULONG)&bfi.BitMapHeader,
  453.     PDTA_DestBitMap,(ULONG)&bfi.BitMap,
  454.     TAG_DONE };
  455.   
  456.   if (bfi.PictureName)
  457.   { dt1tags[0].ti_Data=(ULONG)pubscreen;
  458.     dt1tags[1].ti_Data=(ULONG)remap;
  459.     if (bfi.PictureObject=NewDTObjectA(bfi.PictureName,dt1tags))
  460.       if (DoMethod(bfi.PictureObject,DTM_PROCLAYOUT,NULL,1))
  461.         GetDTAttrsA(bfi.PictureObject,dt2tags);
  462.   }
  463. } /* loadimage */
  464.  
  465. void openall(void)
  466. { /* Libraries sind schon geöffnet, PubScreen schon blockiert */
  467.  
  468.   if (DataTypesBase=OpenLibrary("datatypes.library",39L))
  469.     loadimage();
  470.   if (wport=CreateMsgPort())
  471.     if (tport=CreateMsgPort())
  472.       if (treq=CreateIORequest(tport,sizeof(struct timerequest)))
  473.         if (!(notime=OpenDevice(TIMERNAME,UNIT_VBLANK,(iorequest)treq,0)))
  474.           if (audport=CreateMsgPort()) /* Replyport für audio.device */
  475.             if (audreq[0]=CreateIORequest(audport,sizeof(struct IOAudio)))
  476.               if (audreq[1]=CreateIORequest(audport,sizeof(struct IOAudio)))
  477.                 if (!(noaudio=OpenDevice(AUDIONAME,0,(iorequest)audreq[0],0)))
  478.                   if (waveform=AllocMem(8,MEMF_CHIP|MEMF_CLEAR))
  479.                   { ((LONG *)waveform)[0]=0x7f807f80; /* Rechteck */
  480.                     if (visi=GetVisualInfoA(pubscreen,NULL))
  481.                     { if (sekunden)
  482.                         menulist[4].nm_Flags|=CHECKED;
  483.                       if (oval)
  484.                         menulist[5].nm_Flags|=CHECKED;
  485.                       menulist[7+zeigen].nm_Flags|=CHECKED;
  486.                       menulist[13+zeigertyp].nm_Flags|=CHECKED;
  487.                       menulist[18+zeigerbreite].nm_Flags|=CHECKED;
  488.                       if (schatten)
  489.                         menulist[23].nm_Flags|=CHECKED;
  490.                       menulist[25+rahmenanz].nm_Flags|=CHECKED;
  491.                       if (hires)
  492.                         menulist[29].nm_Flags|=CHECKED;
  493.                       if (interlace)
  494.                         menulist[30].nm_Flags|=CHECKED;
  495.                       menulist[32+chime].nm_Flags|=CHECKED;
  496.                       if (smarthour)
  497.                         menulist[36].nm_Flags|=CHECKED;
  498.                       if (bfi.BitMap && useimage)
  499.                         menulist[40].nm_Flags|=CHECKED;
  500.                       if (closegad)
  501.                         menulist[41].nm_Flags|=CHECKED;
  502.                       if (menus=CreateMenusA(menulist,NULL))
  503.                         if (LayoutMenusA(menus,visi,menutags))
  504.                         { windowtags[0].ti_Data=links;
  505.                           windowtags[1].ti_Data=oben;
  506.                           windowtags[2].ti_Data=breite;
  507.                           windowtags[3].ti_Data=hoehe;
  508.                           windowtags[4].ti_Data=(ULONG)pubscreen;
  509.                           if (mainwin=myOpenWindow(windowtags,MAINIDCMP))
  510.                           { SetMenuStrip(mainwin,menus);
  511.                             rport1=mainwin->RPort;
  512.                             if (!bfi.BitMap || useimage)
  513.                               OffMenu(mainwin,(!bfi.BitMap?FULLMENUNUM(1,8,NOSUB):FULLMENUNUM(3,NOITEM,NOSUB)));
  514.                             SetAPen(rport1,pens[0]);
  515.                             newsize2();
  516.                             nexttick();
  517.                             rahmen();
  518.                             zifferblatt();
  519.                             zeichnen();
  520.                             return;
  521.                           }
  522.                         }
  523.                     }
  524.                   }
  525.   closeall(RETURN_FAIL);
  526. } /* openall */
  527.  
  528. void readargs(void)
  529. { if (WbMsg)
  530.   { struct WBArg *arg=WbMsg->sm_ArgList;
  531.  
  532.     if (WbMsg->sm_NumArgs>1)
  533.       arg++;
  534.     progarg.wa_Lock=arg->wa_Lock;
  535.     progarg.wa_Name=arg->wa_Name;
  536.     oldlock=CurrentDir(progarg.wa_Lock); changedlock=1;
  537.     mergetooltypes();
  538.   }
  539.   else
  540.   { if ((namebuf=AllocVec(124,MEMF_ANY)) == NULL)
  541.       closeall(RETURN_FAIL);
  542.     progarg.wa_Lock=GetProgramDir();
  543.     GetProgramName(namebuf,124);
  544.     progarg.wa_Name=FilePart(namebuf);
  545.     parseargs(NULL,0);
  546.   }
  547. } /* readargs */
  548.  
  549. void mergetooltypes(void)
  550. { ULONG strln,i;
  551.   char **ttypes;
  552.   BPTR old_cd;
  553.  
  554.   old_cd=CurrentDir(progarg.wa_Lock);
  555.   dobj=GetDiskObject(progarg.wa_Name);
  556.   CurrentDir(old_cd);
  557.   if (dobj==NULL)
  558.     closeall(RETURN_FAIL);
  559.   ttypes=dobj->do_ToolTypes; strln=1; i=0;
  560.   while(ttypes[i] != NULL)
  561.    {
  562.     strln+=strlen(ttypes[i])+1; i++;
  563.    }
  564.   if ((string=AllocVec((strln+sizeof(ULONG)-1)&~(sizeof(ULONG)-1),MEMF_ANY))==NULL)
  565.     closeall(RETURN_FAIL);
  566.   i=0;
  567.   while(ttypes[i] != NULL)
  568.    {
  569.      sprintf(string,"%s%s ",string,ttypes[i]); i++;
  570.    }
  571.   string[strln-1]='\n';
  572.   parseargs(string,strln);
  573.   FreeVec(string); string=0;
  574.   FreeDiskObject(dobj); dobj=NULL;
  575. } /* mergetooltypes */
  576.  
  577. void parseargs(char *argstring,int laenge)
  578. { struct RDArgs *rdarg,*args;
  579.   ULONG ergebnis[25],*erg;
  580.  
  581.   if (!(rdarg=AllocDosObject(DOS_RDARGS,NULL)))
  582.     closeall(RETURN_FAIL);
  583.   memset(&ergebnis[0],0,sizeof(ergebnis));
  584.   rdarg->RDA_Source.CS_Buffer=argstring;
  585.   rdarg->RDA_Source.CS_Length=laenge;
  586.   args=ReadArgs(argstring?template:&template[3],ergebnis,rdarg);
  587.   if (!argstring && !args) /* Fehler in der Kommandozeile */
  588.   {
  589.     FreeDosObject(DOS_RDARGS,rdarg); closeall(RETURN_FAIL);
  590.   }
  591.   erg=(argstring?&ergebnis[1]:ergebnis);
  592.   if (erg[0])
  593.     oben  =*(LONG *)erg[0];
  594.   if (erg[1])
  595.     links =*(LONG *)erg[1];
  596.   if (erg[2])
  597.     breite=*(LONG *)erg[2];
  598.   if (erg[3])
  599.     hoehe =*(LONG *)erg[3];
  600.   if (erg[4])
  601.     sekunden=1;
  602.   if (erg[5])
  603.     readstr(must,(char *)erg[5],4);
  604.   if (erg[6])
  605.     oval=1;
  606.   if (erg[7])
  607.     schatten=1;
  608.   if (erg[8])
  609.     zeigen=*(LONG *)erg[8];
  610.   if (erg[9])
  611.     zeigertyp=*(LONG *)erg[9];
  612.   if (erg[10])
  613.     zeigerbreite=*(LONG *)erg[10];
  614.   if (erg[11])
  615.     readstr(pens,(char *)erg[11],14);
  616.   if (erg[12])
  617.     rahmenanz=*(LONG *)erg[12];
  618.   if (erg[13])
  619.     chime=*(LONG *)erg[13];
  620.   if (erg[14])
  621.     closegad=1;
  622.   if (erg[15])
  623.     useimage=1;
  624.   if (erg[16])
  625.     remap=0;
  626.   if (erg[17])
  627.     if (bfi.PictureName=AllocVec(1+strlen((STRPTR)erg[17]),MEMF_ANY))
  628.       strcpy(bfi.PictureName,(STRPTR)erg[17]);
  629.   pubscreen=LockPubScreen((char *)erg[18]); /* 0 gibt Default-PubScreen */
  630.   if (erg[19])
  631.   { oldpri=SetTaskPri(FindTask(NULL),*(LONG *)erg[19]);
  632.     changedpri=1; }
  633.   FreeArgs(args);
  634.   FreeDosObject(DOS_RDARGS,rdarg);
  635.   setargs();
  636. } /* parsecliargs */
  637.  
  638. void readstr(char *dest,char *sorc,int n)
  639. { if (*sorc=='x'||*sorc=='X') /* Hexadezimal */
  640.     while (n-- && *sorc++ && *sorc++)
  641.       *dest++=(xtod(sorc[-1])<<4)+xtod(*sorc);
  642.   else
  643.     while (*sorc && n--) /* Dezimal */
  644.       *dest++=xtod(*sorc++);
  645. } /* readstr */
  646.  
  647. int xtod(int a)
  648. { if (a>='0' && a<='9')
  649.     return(a-'0');
  650.   if (a>='a' && a<='f')
  651.     return(a-'a'+10);
  652.   if (a>='A' && a<='F')
  653.     return(a-'A'+10);
  654.   return(0);
  655. } /* xtod */
  656.  
  657. void setargs(void)
  658. { if (breite<10)/* Zu schmal ? */
  659.     breite=10;
  660.   if (hoehe<10)
  661.     hoehe=10;
  662.   if (zeigen<0 || zeigen>4)
  663.     zeigen=0;
  664.   if (zeigertyp<0 || zeigertyp>3)
  665.     zeigertyp=0;
  666.   if (zeigerbreite<0 || zeigerbreite>4)
  667.     zeigerbreite=0;
  668.   if (rahmenanz<0 || rahmenanz>5)
  669.     rahmenanz=0;
  670.   if (chime<0 || chime>5)
  671.     chime=0;
  672.   if (chime>2)
  673.   { chime-=3;
  674.     smarthour=1;
  675.   }
  676.   if (rahmenanz>2)
  677.   { hires=rahmenanz&1;
  678.     interlace=rahmenanz>3;
  679.     rahmenanz=2;
  680.   }
  681.   setpattern();
  682. } /* setargs */
  683.  
  684. int main(void)
  685. { readargs();
  686.   openall();
  687.   for(;;)
  688.    { ULONG sigs=Wait(SIGBREAKF_CTRL_C|       /* User-Break   */
  689.                      1L<<wport->mp_SigBit|   /* IDCMP-Signal */
  690.                      1L<<tport->mp_SigBit|   /* Timer-Signal */
  691.                      1L<<audport->mp_SigBit| /* Audio-Device */
  692.                      (aboutreq?1L<<aboutreq->UserPort->mp_SigBit:0));
  693.     if (GetMsg(tport)) /* Timer-Signal ? */
  694.     { if (nexttick())
  695.       { zifferblatt();
  696.         testifalarm();
  697.       }
  698.       zeichnen();
  699.     }
  700.     if (GetMsg(audport)) /* Audio */
  701.       playnote();
  702.     checkaboutreq();
  703.     checkwindows(); /* check window port */
  704.     if (sigs&SIGBREAKF_CTRL_C) /* User-Break */
  705.       closeall(RETURN_WARN);
  706.    }
  707. } /* main */
  708.  
  709. void closeall(int retval) /* Aufräumen */
  710. { newsize1(); /* Bitmaps löschen */
  711.   if (string)
  712.     FreeVec(string);
  713.   if (dobj)
  714.     FreeDiskObject(dobj);
  715.   if (aboutreq)
  716.     FreeSysRequest(aboutreq);
  717.   if (colwin)
  718.   { closewindowsafely(colwin);
  719.     FreeGadgets(colgads); }
  720.   if (almwin)
  721.   { closewindowsafely(almwin);
  722.     FreeGadgets(almgads); }
  723.   if (mainwin) /* Window schließen */
  724.     closewindowsafely(mainwin);
  725.   if (menus)
  726.     FreeMenus(menus);
  727.   if (visi)
  728.     FreeVisualInfo(visi);
  729.   if (pubscreen)
  730.     UnlockPubScreen(NULL,pubscreen);
  731.   if (waveform)
  732.     FreeMem(waveform,8);
  733.   if (audsent[0])
  734.   { AbortIO((iorequest)audreq[0]); /* Ton abbrechen */
  735.     WaitIO((iorequest)audreq[0]); }
  736.   if (audsent[1])
  737.   { AbortIO((iorequest)audreq[1]); /* Ton abbrechen */
  738.     WaitIO((iorequest)audreq[1]); }
  739.   if (!nosound)
  740.     endtune();
  741.   if (!noaudio)
  742.     CloseDevice((iorequest)audreq[0]);
  743.   if (audreq[1])
  744.     DeleteIORequest(audreq[1]);
  745.   if (audreq[0])
  746.     DeleteIORequest(audreq[0]);
  747.   if (audport)
  748.     DeleteMsgPort(audport);
  749.   if (timesent)
  750.   { AbortIO((iorequest)treq);
  751.     WaitIO((iorequest)treq); }
  752.   if (!notime) /* Timerequest abbrechen */
  753.     CloseDevice((iorequest)treq);
  754.   if (treq)
  755.     DeleteIORequest(treq);
  756.   if (tport)
  757.     DeleteMsgPort(tport);
  758.   if (wport)
  759.     DeleteMsgPort(wport);
  760.   if (DataTypesBase)
  761.   { if (bfi.PictureObject)
  762.       DisposeDTObject(bfi.PictureObject);
  763.     if (bfi.PictureName)
  764.       FreeVec(bfi.PictureName);
  765.     CloseLibrary(DataTypesBase); }
  766.   if (namebuf)
  767.     FreeVec(namebuf);
  768.   if (changedlock)
  769.     CurrentDir(oldlock);
  770.   if (changedpri)
  771.     SetTaskPri(FindTask(NULL),oldpri);
  772.   exit(retval); /* Fertig */
  773. } /* closeall */
  774.  
  775. void newsize1(void) /* Löscht BitPlanes */
  776. { int i;
  777.  
  778.   if (buf)
  779.   {
  780.     FreeRaster(buf,breit2,hoehe2); buf=NULL;
  781.   }
  782.   for (i=0;i<abitmap.Depth;i++)
  783.   { if (abitmap.Planes[i])
  784.     {
  785.       FreeRaster(abitmap.Planes[i],breit2,hoehe2); abitmap.Planes[i]=NULL;
  786.     }
  787.   }
  788. } /* newsize1 */
  789.  
  790. void closewindowsafely(struct Window *win)
  791. { struct Node *msg,*succ;
  792.  
  793.   Forbid();
  794.   msg=win->UserPort->mp_MsgList.lh_Head; /* assumes valid port */
  795.   while ((succ=msg->ln_Succ)!=NULL)
  796.   { if (((struct IntuiMessage *)msg)->IDCMPWindow==win)
  797.     {
  798.       Remove(msg); ReplyMsg((struct Message *)msg);
  799.     }
  800.     msg=succ;
  801.   }
  802.   win->UserPort=NULL;
  803.   ModifyIDCMP(win,0L);
  804.   ClearMenuStrip(win);
  805.   CloseWindow(win);
  806.   Permit();
  807. } /* closewindowsafely */
  808.  
  809. void checkaboutreq(void)
  810. { if (aboutreq)
  811.     if (SysReqHandler(aboutreq,NULL,FALSE) != -2)
  812.     {
  813.       FreeSysRequest(aboutreq); aboutreq=NULL;
  814.     }
  815. } /* checkaboutreq */
  816.  
  817. void checkwindows(void)
  818. { static struct EasyStruct easyreq={
  819.     sizeof (struct EasyStruct),
  820.     0,
  821.     "About",
  822.     (UBYTE *)aboutstring,
  823.     "Ok"
  824.   };
  825.   struct IntuiMessage *msg;
  826.   struct MenuItem *item;
  827.   struct Window *iwin;
  828.   UWORD check,mnum,inum,snum;
  829.   ULONG class;
  830.   UWORD code;
  831.   APTR iadr;
  832.  
  833.   while (msg=GT_GetIMsg(wport))
  834.   { class=msg->Class;
  835.     code=msg->Code;
  836.     iadr=msg->IAddress;
  837.     iwin=msg->IDCMPWindow;
  838.     GT_ReplyIMsg(msg);
  839.     if (iwin==mainwin)
  840.     { switch (class)
  841.       { case NEWSIZE:
  842.           newsize1();
  843.           newsize2();
  844.           rahmen();
  845.           zifferblatt();
  846.           zeichnen();
  847.           break;
  848.         case REFRESHWINDOW:
  849.           redrawx1=boleft;
  850.           redrawy1=botop;
  851.           redrawx2=boleft+breit2-1;
  852.           redrawy2=botop +hoehe2-1;
  853.           BeginRefresh(mainwin);
  854.           rahmen();
  855.           zeichnen();
  856.           EndRefresh(mainwin,TRUE);
  857.           break;
  858.         case MENUPICK:
  859.           while (code!=MENUNULL)
  860.           { item=ItemAddress(menus,code);
  861.             check=item->Flags&CHECKED;
  862.             snum=SUBNUM(code);
  863.             switch (code)
  864.             { case FULLMENUNUM(0,0,NOSUB): /* About */
  865.                 if (!aboutreq)
  866.                 { iwin=BuildEasyRequestArgs(mainwin,&easyreq,NULL,NULL);
  867.                   if (((ULONG)iwin)>1)
  868.                     aboutreq=iwin;
  869.                 }
  870.                 break;
  871.               case FULLMENUNUM(0,1,NOSUB): /* Quit */
  872.                 closeall(RETURN_OK);
  873.               case FULLMENUNUM(1,0,NOSUB): /* Menu Seconds ausgewählt */
  874.                 sekunden=check;
  875.                 if (timesent)
  876.                 { AbortIO((iorequest)treq);
  877.                   WaitIO((iorequest)treq);
  878.                   timesent=0; }
  879.                 nexttick();
  880.                 break;
  881.               case FULLMENUNUM(1,1,NOSUB): /* oval umschalten */
  882.                 oval=check;
  883.                 break;
  884.               case FULLMENUNUM(1,2,0): /* zifferblatt */
  885.               case FULLMENUNUM(1,2,1):
  886.               case FULLMENUNUM(1,2,2):
  887.               case FULLMENUNUM(1,2,3):
  888.               case FULLMENUNUM(1,2,4):
  889.                 if (check)
  890.                   zeigen=snum;
  891.                 break;
  892.               case FULLMENUNUM(1,3,0): /* zeiger */
  893.               case FULLMENUNUM(1,3,1):
  894.               case FULLMENUNUM(1,3,2):
  895.               case FULLMENUNUM(1,3,3):
  896.                 if (check)
  897.                   zeigertyp=snum;
  898.                 break;
  899.               case FULLMENUNUM(1,3,5): /* zeigerbreite */
  900.               case FULLMENUNUM(1,3,6):
  901.               case FULLMENUNUM(1,3,7):
  902.               case FULLMENUNUM(1,3,8):
  903.               case FULLMENUNUM(1,3,9):
  904.                 if (check)
  905.                   zeigerbreite=snum-5;
  906.                 break;
  907.               case FULLMENUNUM(1,4,NOSUB): /* Shadow */
  908.                 schatten=check;
  909.                 break;
  910.               case FULLMENUNUM(1,5,0): /* Rahmen */
  911.               case FULLMENUNUM(1,5,1):
  912.               case FULLMENUNUM(1,5,2):
  913.                 if (check)
  914.                   rahmenanz=snum;
  915.               case FULLMENUNUM(1,5,4):
  916.                 hires=check;
  917.                 break;
  918.               case FULLMENUNUM(1,5,5):
  919.                 interlace=check;
  920.                 break;
  921.               case FULLMENUNUM(1,6,0): /* Chime */
  922.               case FULLMENUNUM(1,6,1):
  923.               case FULLMENUNUM(1,6,2):
  924.                 if (check)
  925.                   chime=snum;
  926.                 break;
  927.               case FULLMENUNUM(1,6,4):
  928.                 smarthour=check;
  929.                 break;
  930.               case FULLMENUNUM(1,7,0): /* Alarm set */
  931.                 if (!almwin)
  932.                 { st=window3gadtags1[0].ti_Data=alstd;
  933.                   mi=window3gadtags2[0].ti_Data=almin;
  934.                   almwin=createrequest(window3tags,ALMIDCMP,4,window3gadtags,window3gad,window3goff,&almgads);
  935.                 }
  936.                 break;
  937.               case FULLMENUNUM(1,7,1):
  938.                 alarm=check;
  939.                 break;
  940.               case FULLMENUNUM(1,8,NOSUB): /* Use Image */
  941.                 useimage=check;
  942.                 if (!useimage)
  943.                   OnMenu(mainwin,FULLMENUNUM(3,NOITEM,NOSUB));
  944.                 else
  945.                   OffMenu(mainwin,FULLMENUNUM(3,NOITEM,NOSUB));
  946.                 break;
  947.               case FULLMENUNUM(1,9,NOSUB): /* Close gadget */
  948.                 closegad=check;
  949.                 break;
  950.               case FULLMENUNUM(1,11,NOSUB): /* Save Prefs */
  951.                 saveprefs();
  952.                 break;
  953.               default:
  954.                 mnum=MENUNUM(code);
  955.                 if (mnum==2 || mnum==3) /* Colour Menus */
  956.                 { if (!colwin)
  957.                   { inum=ITEMNUM(code);
  958.                     colour=(mnum==2?&pens[inum]:&must[inum]);
  959.                     window2gadtags1[0].ti_Data=abitmap.Depth;
  960.                     colwin=createrequest(window2tags,COLIDCMP,1,window2gadtags,window2gad,window2goff,&colgads);
  961.                   }
  962.                 }
  963.                 break;
  964.             } /* switch menus */
  965.             code=item->NextSelect;
  966.           } /* while */
  967.           newsize1(); /* Zwar manchmal unnötig, aber kurz */
  968.           newsize2();
  969.           rahmen();
  970.           zifferblatt();
  971.           zeichnen();
  972.           break;
  973.         case ACTIVEWINDOW:
  974.           active=1;
  975.           rahmen();
  976.           break;
  977.         case INACTIVEWINDOW:
  978.           active=0;
  979.           rahmen();
  980.           break;
  981.         case CLOSEWINDOW:
  982.           if (closegad)
  983.             closeall(RETURN_OK);
  984.       } /* switch*/
  985.     } /* if */
  986.     else
  987.       if (iwin==colwin)
  988.       { if (class==CLOSEWINDOW || class==GADGETUP)
  989.         { if (class!=CLOSEWINDOW) /* kann nur das Palette-Gadget sein */
  990.           { *colour=code;
  991.             setpattern();
  992.             rahmen();
  993.             zifferblatt();
  994.             zeichnen();
  995.           }
  996.           closewindowsafely(colwin); colwin=NULL;
  997.           FreeGadgets(colgads);
  998.         }
  999.       } /* else if */
  1000.       else
  1001.         if (iwin==almwin)
  1002.         { if (class==CLOSEWINDOW || class==MOUSEMOVE || class==GADGETUP)
  1003.           { if (class!=CLOSEWINDOW)
  1004.             { switch(((struct Gadget *)iadr)->GadgetID)
  1005.               { case 1:
  1006.                   st=code;
  1007.                   goto endit;
  1008.                 case 2:
  1009.                   mi=code;
  1010.                   goto endit;
  1011.                 case 3:
  1012.                   alstd=st; almin=mi; alarm=1;
  1013.                 case 4:
  1014.                 default:
  1015.                   break;
  1016.               }
  1017.             }
  1018.             closewindowsafely(almwin); almwin=NULL;
  1019.             FreeGadgets(almgads);
  1020.             if (alarm)
  1021.             { item=ItemAddress(menus,FULLMENUNUM(1,7,1));
  1022.               if (!(item->Flags&CHECKED))
  1023.               { ClearMenuStrip(mainwin); /* Menu entfernen */
  1024.                 item->Flags|=CHECKED;
  1025.                 ResetMenuStrip(mainwin,menus); /* Menu wieder einfügen */
  1026.               }
  1027.             }
  1028. endit:
  1029.           }
  1030.         } /* else if */
  1031.   } /* while */
  1032. }
  1033.  
  1034. void newsize2(void) /* Holt BitPlanes */
  1035. { static long gadgsize=-1;
  1036.   long newsize;
  1037.   int i,k;
  1038.  
  1039.   boleft=rahmenanz+(hires    ?(rahmenanz==2)<<1:0);
  1040.   botop =rahmenanz+(interlace?(rahmenanz==2)<<1:0);
  1041.   breite=mainwin->Width;
  1042.   hoehe =mainwin->Height;
  1043.   breit2=breite-(boleft<<1);
  1044.   hoehe2=hoehe -(botop <<1);
  1045.   doublex=(maskx==-2&&breit2>12);
  1046.   doubley=(masky==-2&&hoehe2>12);
  1047.   xoffset=(breit2>50?2:(breit2>25?1:0));
  1048.   yoffset=(hoehe2>50?2:(hoehe2>25?1:0));
  1049.   newsize=(breite<hoehe?breite/8:hoehe/8);
  1050.   if (newsize!=gadgsize)
  1051.   { gadgsize=newsize; /* Gadgets müssen in der Größe angepasst werden */
  1052.     RemoveGList(mainwin,gadgets,-1);
  1053.     for (i=0;i<4;i++)
  1054.       for (k=0;k<4;k++) /* Casting ist nicht schön, aber wirksam */
  1055.         ((SHORT *)&gadgets[i].LeftEdge)[k]=sizes[i][k]*gadgsize;
  1056.     AddGList(mainwin,gadgets,0,4,NULL);
  1057.   } /* if */
  1058.   InitBitMap(&abitmap,mainwin->WScreen->BitMap.Depth,breit2,hoehe2);
  1059.   for (i=0;i<abitmap.Depth;i++)
  1060.     if (!(abitmap.Planes[i]=AllocRaster(breit2,hoehe2)))
  1061.       closeall(RETURN_FAIL);
  1062.   InitRastPort(&rport2);
  1063.   rport2.BitMap=&abitmap;
  1064.   if (!(buf=AllocRaster(breit2,hoehe2)))
  1065.     closeall(RETURN_FAIL);
  1066.   rport2.TmpRas=InitTmpRas (&temp,buf,RASSIZE(breit2,hoehe2));
  1067.   InitArea (&info,table,5);
  1068.   rport2.AreaInfo=(struct AreaInfo *)&info;
  1069. } /* newsize2 */
  1070.  
  1071. int nexttick(void)
  1072. { ULONG oldmin;
  1073.  
  1074.   treq->tr_node.io_Command=TR_GETSYSTIME;
  1075.   DoIO((iorequest)treq);/* Zeit besorgen */
  1076.   treq->tr_time.tv_micro=1100000-treq->tr_time.tv_micro;
  1077.   sec=treq->tr_time.tv_secs; /* ^ Ein ganz besonders netter Effekt: Das Timerdevice */
  1078.   treq->tr_time.tv_secs=(sekunden?0:59-sec%60); /* rundet aktuelle Zeit und Wartezeit ab */
  1079.   treq->tr_node.io_Command=TR_ADDREQUEST;
  1080.   SendIO((iorequest)treq); /* Und abschicken */
  1081.   oldmin=min;
  1082.   min=sec/60;
  1083.   sec=sec%60;
  1084.   std=min/12;
  1085.   min=min%60;
  1086.   std=std%60;
  1087.   timesent=-1;
  1088.   return (min-oldmin); /* sec==0 ist unzuverlässig bei hoher CPU-Auslastung */
  1089. } /* nexttick */
  1090.  
  1091. void zifferblatt (void)
  1092. { int i,a,b,c;
  1093.   long x0,y0,x,y;
  1094.  
  1095.   if (bfi.BitMap && useimage) /* Hintergrund: Image oder Muster */
  1096.   {
  1097.     CopyTiledBitMap(bfi.BitMap,bfi.BitMapHeader->bmh_Width,bfi.BitMapHeader->bmh_Height,&abitmap,breit2,hoehe2);
  1098.   }
  1099.   else
  1100.   { BNDRYOFF (&rport2);
  1101.     SetAPen  (&rport2,-1);
  1102.     SetAfPt  (&rport2,*muster,-1);
  1103.     RectFill (&rport2,0,0,breit2-1,hoehe2-1);
  1104.     SetAfPt  (&rport2,0,0);
  1105.   }
  1106.   x0=breit2/2;
  1107.   y0=hoehe2/2;
  1108.   a=(zeigen>1?(zeigen==3?60:15):(zeigen?5:1));
  1109.   if (zeigen<4)
  1110.     for (i=0;i<60;i+=a)
  1111.     { x=x0+((oval?  sinus[i]:srect[i])*breit2/300)&maskx;/* Position des Striches */
  1112.       y=y0-((oval?cosinus[i]:crect[i])*hoehe2/300)&masky;
  1113.       if (i%5)
  1114.       { if (i%5==1)
  1115.         { c=pens[9];
  1116.           SetAPen(&rport2,c);
  1117.           SetOPen(&rport2,c); }
  1118.         AreaMove (&rport2,x+breit2/200,y);
  1119.         AreaDraw (&rport2,x,y+hoehe2/200);
  1120.         AreaDraw (&rport2,x-breit2/200,y);
  1121.         AreaDraw (&rport2,x,y-hoehe2/200);
  1122.         AreaEnd  (&rport2);
  1123.       } else
  1124.       { b=i/5;
  1125.         c=pens[pent[b]];
  1126.         SetAPen(&rport2,c);
  1127.         SetOPen(&rport2,c);
  1128.         AreaMove (&rport2,x+=breit2*dx1[b]/100,y+=hoehe2*dy1[b]/100);
  1129.         AreaDraw (&rport2,x+=breit2*dx2[b]/100,y+=hoehe2*dy2[b]/100);
  1130.         AreaDraw (&rport2,x+=breit2*dx3[b]/100,y+=hoehe2*dy3[b]/100);
  1131.         AreaDraw (&rport2,x+=breit2*dx4[b]/100,y+=hoehe2*dy4[b]/100);
  1132.         AreaEnd  (&rport2);
  1133.       } /* if */
  1134.     } /* for */
  1135.   if (schatten)
  1136.   { zeiger(std,440,1,pens[5],pens[5]);
  1137.     zeiger(min,300,1,pens[5],pens[5]); }
  1138.   zeiger(std,440,0,pens[3],pens[4]);
  1139.   zeiger(min,300,0,pens[1],pens[2]);
  1140.   redrawx1=boleft;
  1141.   redrawy1=botop;
  1142.   redrawx2=boleft+breit2-1;
  1143.   redrawy2=botop +hoehe2-1;
  1144. } /* zifferblatt */
  1145.  
  1146. void rahmen(void)
  1147. { if (rahmenanz)
  1148.   { SetAPen(rport1,(active&&rahmenanz==1)?pens[12]:pens[11]);
  1149.     Move(rport1,1            ,hoehe-1    );
  1150.     Draw(rport1,breite-1     ,hoehe-1    );
  1151.     Draw(rport1,breite-1     ,1          );
  1152.     SetAPen(rport1,(active&&rahmenanz==1)?pens[11]:pens[12]);
  1153.     Move(rport1,0,            hoehe-1    );
  1154.     Draw(rport1,0,            0          );
  1155.     Draw(rport1,breite-1,     0          );
  1156.     if (rahmenanz==2)
  1157.     { SetAPen(rport1,pens[12]); /* Rahmen */
  1158.       Move(rport1,boleft       ,hoehe-botop);
  1159.       Draw(rport1,breite-boleft,hoehe-botop);
  1160.       Draw(rport1,breite-boleft,botop      );
  1161.       SetAPen(rport1,pens[11]);
  1162.       Move(rport1,boleft-1     ,hoehe-botop);
  1163.       Draw(rport1,boleft-1     ,botop-1    );
  1164.       Draw(rport1,breite-boleft,botop-1    );
  1165.       SetAPen(rport1,active?pens[13]:pens[10]);
  1166.       if (hires)
  1167.       { RectFill(rport1,1,1,2,hoehe-2);
  1168.         RectFill(rport1,breite-3,1,breite-2,hoehe-2); }
  1169.       if (interlace)
  1170.       { RectFill(rport1,1,1,breite-2,2);
  1171.         RectFill(rport1,1,hoehe-3,breite-2,hoehe-2); }
  1172.     } /* if */
  1173.   } /* if */
  1174.   SetAPen(rport1,pens[0]);
  1175. } /* rahmen */
  1176.  
  1177. void zeiger(ULONG winkel,int lfactor,int offset,int apen,int open)
  1178. { long x0,y0,x1,y1,x2,y2;
  1179.  
  1180.   x0=breit2/2+(offset?xoffset:0);
  1181.   y0=hoehe2/2+(offset?yoffset:0);
  1182.   x2=sinus  [winkel]*breit2/lfactor;
  1183.   y2=cosinus[winkel]*hoehe2/lfactor;
  1184.   x1=cosinus[winkel]*breit2/handwidth[zeigerbreite];
  1185.   y1=sinus  [winkel]*hoehe2/handwidth[zeigerbreite];
  1186.   SetAPen(&rport2,apen);
  1187.   SetOPen(&rport2,open);
  1188.   switch (zeigertyp)
  1189.   { case 0:
  1190.       SetAPen(&rport2,open);
  1191.       Move (&rport2,x0,y0);
  1192.       Draw (&rport2,x0+x2,y0-y2);
  1193.       if (doublex)
  1194.       { Move (&rport2,1+x0,y0);
  1195.         Draw (&rport2,1+x0+x2,y0-y2); }
  1196.       if (doubley)
  1197.       { Move (&rport2,x0,1+y0);
  1198.         Draw (&rport2,x0+x2,1+y0-y2); }
  1199.       break;
  1200.     case 1:
  1201.       AreaMove (&rport2,x0+x2     ,y0-y2     );
  1202.       AreaDraw (&rport2,x0+x1-x2/4,y0+y1+y2/4);
  1203.       AreaDraw (&rport2,x0-x1-x2/4,y0-y1+y2/4);
  1204.       AreaEnd  (&rport2);
  1205.       break;
  1206.     case 2:
  1207.       AreaMove (&rport2,x0+x2  ,y0-y2  );
  1208.       AreaDraw (&rport2,x0+x1  ,y0+y1  );
  1209.       AreaDraw (&rport2,x0-x2/4,y0+y2/4);
  1210.       AreaDraw (&rport2,x0-x1  ,y0-y1  );
  1211.       AreaEnd  (&rport2);
  1212.       break;
  1213.     case 3:
  1214.       AreaMove (&rport2,x0+=x2-x1/2,y0-=y2+y1/2);
  1215.       AreaDraw (&rport2,x0+=x1     ,y0+=y1     );
  1216.       AreaDraw (&rport2,x0-=x2*5/4 ,y0+=y2*5/4 );
  1217.       AreaDraw (&rport2,x0-=x1     ,y0-=y1     );
  1218.       AreaEnd  (&rport2);
  1219.       break;
  1220.   } /* switch */
  1221. } /* zeiger */
  1222.  
  1223. void zeichnen(void)
  1224. { long tmp;
  1225.  
  1226.   BltBitMapRastPort(&abitmap,redrawx1-boleft,redrawy1-botop,
  1227.                     rport1,redrawx1,redrawy1,
  1228.                     redrawx2-redrawx1+1,redrawy2-redrawy1+1,0xc0);
  1229.   if (sekunden)
  1230.   { redrawx1=breite/2;
  1231.     redrawy1=hoehe /2;
  1232.     redrawx2=redrawx1+sinus  [sec]*breit2/300;
  1233.     redrawy2=redrawy1-cosinus[sec]*hoehe2/300;
  1234.     Move(rport1,redrawx1,redrawy1);
  1235.     Draw(rport1,redrawx2,redrawy2);
  1236.     if (doublex)
  1237.     { Move(rport1,1+redrawx1,redrawy1);
  1238.       Draw(rport1,1+redrawx2,redrawy2); }
  1239.     if (doubley)
  1240.     { Move(rport1,redrawx1,1+redrawy1);
  1241.       Draw(rport1,redrawx2,1+redrawy2); }
  1242.     if (redrawx1>redrawx2)
  1243.     { tmp=redrawx1;
  1244.       redrawx1=redrawx2;
  1245.       redrawx2=tmp; }
  1246.     if (redrawy1>redrawy2)
  1247.     { tmp=redrawy1;
  1248.       redrawy1=redrawy2;
  1249.       redrawy2=tmp; }
  1250.     if (doublex)
  1251.       redrawx2++;
  1252.     if (doubley)
  1253.       redrawy2++;
  1254.   } /* if */
  1255. } /* zeichnen */
  1256.  
  1257. void setpattern(void)
  1258. { int i,a,b,c,d;
  1259.   UBYTE *p1;
  1260.   UWORD *p2;
  1261.  
  1262.   p1=must; a=*p1++; b=*p1++; c=*p1++; d=*p1;
  1263.   if (a==b && c==d) /* nur horizontale Streifen */
  1264.     maskx=0xffffffff;
  1265.   else
  1266.     maskx=0xfffffffe;
  1267.   if (a==c && b==d) /* nur vertikale Streifen */
  1268.     masky=0xffffffff;
  1269.   else
  1270.     masky=0xfffffffe;
  1271.   p2=(UWORD *)muster;
  1272.   for (i=0;i<8;i++)
  1273.   { *p2=(a&1<<i?0x5555:0)|(b&1<<i?0xaaaa:0); p2++;
  1274.     *p2=(c&1<<i?0x5555:0)|(d&1<<i?0xaaaa:0); p2++;
  1275.   }
  1276. } /* setpattern */
  1277.  
  1278. void saveprefs(void)
  1279. { BPTR old_cd;
  1280.  
  1281.   old_cd=CurrentDir(progarg.wa_Lock);
  1282.  
  1283.   if (dobj=GetDiskObjectNew(progarg.wa_Name)) /* Tooltypes einlesen */
  1284.   {
  1285.     UBYTE **ttypes,**p1,**p2,*tbuf,*tbuf1,*p;
  1286.     int i;
  1287.  
  1288.     p1=(UBYTE **)dobj->do_ToolTypes; p2=p1; do {} while(*p2++) ;
  1289.  
  1290.     if ((tbuf=AllocVec(((UBYTE *)p2-(UBYTE *)p1)+sizeof(tooltypes)+40*sizeof(tooltypes)/sizeof(char *),MEMF_ANY)))
  1291.     {
  1292.       (UBYTE *)ttypes=tbuf+40*sizeof(tooltypes)/sizeof(char *);
  1293.  
  1294.       p1=(UBYTE **)dobj->do_ToolTypes; p2=ttypes; do {} while(*p2++=*p1++) ;
  1295.  
  1296.       for (i=0;i<sizeof(tooltypes)/sizeof(char *);i++) /* Eigene Tooltypes */
  1297.       { if (FindToolType(ttypes,tooltypes[i]))         /* entfernen */
  1298.         { p2=ttypes;
  1299.           do {} while(*++p2 && FindToolType(p2,tooltypes[i]));
  1300.           do { p=*p2++; } while(p2[-2]=p);
  1301.         }
  1302.       } /* for */
  1303.  
  1304.       /* Tooltypes zählen */
  1305.       p2=ttypes; do {} while(*p2++) ; --p2; tbuf1=tbuf;
  1306.  
  1307.       sprintf(tbuf1,"%s=%ld",tooltypes[0],mainwin->TopEdge);
  1308.       *p2++=tbuf1; tbuf1+=40;
  1309.       sprintf(tbuf1,"%s=%ld",tooltypes[1],mainwin->LeftEdge);
  1310.       *p2++=tbuf1; tbuf1+=40;
  1311.       sprintf(tbuf1,"%s=%ld",tooltypes[2],breite);
  1312.       *p2++=tbuf1; tbuf1+=40;
  1313.       sprintf(tbuf1,"%s=%ld",tooltypes[3],hoehe);
  1314.       *p2++=tbuf1; tbuf1+=40;
  1315.       sprintf(tbuf1,"%s=%ld",tooltypes[4],zeigen);
  1316.       *p2++=tbuf1; tbuf1+=40;
  1317.       sprintf(tbuf1,"%s=%ld",tooltypes[5],zeigertyp);
  1318.       *p2++=tbuf1; tbuf1+=40;
  1319.       sprintf(tbuf1,"%s=%ld",tooltypes[6],zeigerbreite);
  1320.       *p2++=tbuf1; tbuf1+=40;
  1321.       sprintf(tbuf1,"%s=%ld",tooltypes[7],
  1322.         rahmenanz+(rahmenanz==2?(hires?1:0)+(interlace?2:0):0));
  1323.       *p2++=tbuf1; tbuf1+=40;
  1324.       sprintf(tbuf1,"%s=%ld",tooltypes[8],chime+(smarthour?3:0));
  1325.       *p2++=tbuf1; tbuf1+=40;
  1326.       if (sekunden)
  1327.         { sprintf(tbuf1,"%s",tooltypes[9]); *p2++=tbuf1; tbuf1+=40; }
  1328.       if (oval)
  1329.         { sprintf(tbuf1,"%s",tooltypes[10]); *p2++=tbuf1; tbuf1+=40; }
  1330.       if (schatten)
  1331.         { sprintf(tbuf1,"%s",tooltypes[11]); *p2++=tbuf1; tbuf1+=40; }
  1332.       if (closegad)
  1333.         { sprintf(tbuf1,"%s",tooltypes[12]); *p2++=tbuf1; tbuf1+=40; }
  1334.       if (useimage)
  1335.         { sprintf(tbuf1,"%s",tooltypes[13]); *p2++=tbuf1; tbuf1+=40; }
  1336.       sprintf(tbuf1,"%s=x",tooltypes[14]); setstr(&tbuf1[10],pens,14);
  1337.       *p2++=tbuf1; tbuf1+=40;
  1338.       sprintf(tbuf1,"%s=x",tooltypes[15]); setstr(&tbuf1[9],must,4);
  1339.       *p2++=tbuf1; *p2=NULL;
  1340.  
  1341.       p1=(UBYTE **)dobj->do_ToolTypes;
  1342.       dobj->do_ToolTypes=(char **)ttypes;
  1343.       PutDiskObject(progarg.wa_Name,dobj);
  1344.       dobj->do_ToolTypes=(char **)p1;
  1345.  
  1346.       FreeVec(tbuf);
  1347.  
  1348.     } /* if */
  1349.  
  1350.     FreeDiskObject(dobj); dobj=NULL;
  1351.  
  1352.   } /* if */
  1353.  
  1354.   CurrentDir(old_cd);
  1355.  
  1356. } /* saveprefs */
  1357.  
  1358. void setstr(char *dest,UBYTE *sourc,int n)
  1359. { while (n--)
  1360.   { *dest++=dtox(*sourc>>4);
  1361.     *dest++=dtox(*sourc++&0xf);
  1362.   }
  1363. } /* setstr */
  1364.  
  1365. int dtox(int a)
  1366. { if (a>9)
  1367.     return(a+'A'-10);
  1368.   else
  1369.     return(a+'0');
  1370. } /* dtox */
  1371.  
  1372. void testifalarm(void)
  1373. { ULONG st2;
  1374.   int i,j;
  1375.  
  1376.   st2=std/5;
  1377.   if (!st2)
  1378.     st2=12;
  1379.   if (alarm && min==almin && st2==alstd)
  1380.     starttune(alarmtune);
  1381.   else
  1382.     if (chime && !min)
  1383.       starttune(&hourtune[smarthour?24-st2*2:22]);
  1384.     else
  1385.      if (chime==2)
  1386.      { for(i=6,j=min;;)
  1387.         { i-=2;
  1388.           if ((j-=15)<0)
  1389.             return;
  1390.           if (j==0)
  1391.             break;
  1392.         }
  1393.        starttune(&quartertune[i]);
  1394.      }
  1395. } /* testifalarm */
  1396.  
  1397. void starttune(UWORD *tune)
  1398. { ioaudio areq=audreq[0];
  1399.  
  1400.   if (!nosound) /* Läuft schon einer */
  1401.     return;
  1402.   areq->ioa_Request.io_Command=ADCMD_ALLOCATE;
  1403.   areq->ioa_Request.io_Message.mn_Node.ln_Pri=90; /* ALARM-Level */
  1404.   areq->ioa_Request.io_Flags=ADIOF_NOWAIT;
  1405.   areq->ioa_Data=camap;
  1406.   areq->ioa_Length=sizeof(camap);
  1407.   BeginIO((iorequest)areq);
  1408.   if (nosound=WaitIO((iorequest)areq))
  1409.     return;
  1410.   CopyMemQuick(areq,audreq[1],sizeof(struct IOAudio));
  1411.   playtune=tune;
  1412.   playnote();
  1413.   playnote();
  1414. } /* starttune */
  1415.  
  1416. void playnote(void)
  1417. { static int requestnr=1;
  1418.   ioaudio areq;
  1419.  
  1420.   requestnr=!requestnr;
  1421.   audsent[requestnr]=0;
  1422.   if (!*playtune)
  1423.   { if (!audsent[!requestnr]) /* Anderer Request auch zurück ? */
  1424.       endtune();
  1425.     return; }
  1426.   audsent[requestnr]=-1; /* Merken */
  1427.   areq=audreq[requestnr];
  1428.   areq->ioa_Request.io_Command=CMD_WRITE;
  1429.   areq->ioa_Request.io_Flags=ADIOF_PERVOL;
  1430.   areq->ioa_Data=&waveform[requestnr*4];
  1431.   areq->ioa_Length=4;
  1432.   areq->ioa_Period=500; /* ekliger Piepton */
  1433.   areq->ioa_Volume=64;
  1434.   areq->ioa_Cycles=*playtune++;
  1435.   BeginIO((iorequest)areq);
  1436. } /* playnote */
  1437.  
  1438. void endtune(void)
  1439. { ioaudio areq=audreq[0];
  1440.  
  1441.   areq->ioa_Request.io_Command=ADCMD_FREE;
  1442.   DoIO((iorequest)areq);
  1443.   nosound=-1;
  1444. } /* endtune */
  1445.  
  1446. struct Window *createrequest
  1447. ( struct TagItem windowtags[],ULONG idcmp,int anzgadgets,struct TagItem *gadgettags[],
  1448.   struct NewGadget gadgets[],ULONG edge[][3],struct Gadget **glistpointer)
  1449. { struct Gadget *context;
  1450.   struct Window *window;
  1451.   int i;
  1452.  
  1453.   *glistpointer=NULL;
  1454.   if (context=CreateContext(glistpointer))
  1455.   { for (i=0;i<anzgadgets;i++)
  1456.      { gadgets[i].ng_LeftEdge=edge[i][0]+  mainwin->WScreen->WBorLeft;
  1457.        gadgets[i].ng_TopEdge =edge[i][1]+1+mainwin->WScreen->WBorTop+
  1458.                                            mainwin->WScreen->RastPort.TxHeight;
  1459.        gadgets[i].ng_VisualInfo=visi;
  1460.        if (!(context=CreateGadgetA(edge[i][2],context,&gadgets[i],gadgettags[i])))
  1461.          break;
  1462.      }
  1463.     if (i==anzgadgets)
  1464.     { windowtags[0].ti_Data=(ULONG)*glistpointer;
  1465.       windowtags[1].ti_Data=(ULONG)pubscreen;
  1466.       if (window=myOpenWindow(windowtags,idcmp))
  1467.       { GT_RefreshWindow(window,NULL);
  1468.         return window;
  1469.       }
  1470.     }
  1471.     FreeGadgets(*glistpointer);
  1472.   }
  1473.   return(NULL);
  1474. } /* createrequest */
  1475.  
  1476. struct Window *myOpenWindow(struct TagItem *wintags,ULONG idcmp)
  1477. { struct Window *window;
  1478.  
  1479.   if (window=OpenWindowTagList(NULL,wintags))
  1480.   { window->UserPort=wport;
  1481.     if (!ModifyIDCMP(window,idcmp))
  1482.     { closewindowsafely(window); window=NULL;
  1483.     }
  1484.   }
  1485.   return window;
  1486. } /* myOpenWindow */
  1487.  
  1488. void CopyTiledBitMap(struct BitMap *Src,LONG SrcSizeX,LONG SrcSizeY,struct BitMap *Dst,LONG DstSizeX,LONG DstSizeY)
  1489. {
  1490.   LONG Pos;  /* used as starting position in the "exponential" blit */
  1491.   LONG Size; /* used as bitmap size in the "exponential" blit */
  1492.  
  1493.   /* blit the first piece of the tile */
  1494.   BltBitMap(Src,0,0,Dst,0,0,MIN(SrcSizeX,DstSizeX),MIN(SrcSizeY,DstSizeY),0xC0,-1,NULL);
  1495.  
  1496.   /* this loop generates the first row of the tiles */
  1497.   for (Pos = SrcSizeX,Size = MIN(SrcSizeX,DstSizeX-Pos);Pos<DstSizeX;)
  1498.   {
  1499.     BltBitMap(Dst,0,0,Dst,Pos,0,Size,MIN(SrcSizeY,DstSizeY),0xC0,-1,NULL);
  1500.     Pos += Size;
  1501.     Size = MIN(Size<<1,DstSizeX-Pos);
  1502.   }
  1503.  
  1504.   /* this loop blit the first row down several times to fill the whole dest rect */
  1505.   for (Pos = SrcSizeY,Size = MIN(SrcSizeY,DstSizeY-Pos);Pos<DstSizeY;)
  1506.   {
  1507.     BltBitMap(Dst,0,0,Dst,0,Pos,DstSizeX,Size,0xC0,-1,NULL);
  1508.     Pos += Size;
  1509.     Size = MIN(Size<<1,DstSizeY-Pos);
  1510.   }
  1511. } /* CopyTiledBitmap */
  1512.