home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Extra 1996 #3 / AmigaPlus_CD-ROM-EXTRA_Nr.3.bin / aminet-spiele / denk&grübel / crazyclock / source / misc.c < prev    next >
C/C++ Source or Header  |  1993-10-12  |  9KB  |  302 lines

  1. /*
  2.  * misc.c V1.1
  3.  *
  4.  * miscellaneous support routines
  5.  *
  6.  * (c) 1992-1993 Holger Brunst
  7.  */
  8.  
  9. #include <CClock.h> 
  10.  
  11. /* Wait pointer image data */
  12. static __chip const UWORD WaitPointer[] = {
  13.                                            0x0000, 0x0000,
  14.  
  15.                                            0x0400, 0x07c0,
  16.                                            0x0000, 0x07c0,
  17.                                            0x0100, 0x0380,
  18.                                            0x0000, 0x07e0,
  19.                                            0x07c0, 0x1ff8,
  20.                                            0x1ff0, 0x3fec,
  21.                                            0x3ff8, 0x7fde,
  22.                                            0x3ff8, 0x7fbe,
  23.                                            0x7ffc, 0xff7f,
  24.                                            0x7efc, 0xffff,
  25.                                            0x7ffc, 0xffff,
  26.                                            0x3ff8, 0x7ffe,
  27.                                            0x3ff8, 0x7ffe,
  28.                                            0x1ff0, 0x3ffc,
  29.                                            0x07c0, 0x1ff8,
  30.                                            0x0000, 0x07e0,
  31.  
  32.                                            0x0000, 0x0000
  33.                                           };
  34.  
  35. /* Disable a window */
  36. void DisableWindow(struct Window *w)
  37. {
  38.  /* Disable right mouse button */
  39.  w->Flags |= WFLG_RMBTRAP;
  40.  
  41.  /* Disable IDCMP */
  42.  ModifyIDCMP(w, IDCMP_REFRESHWINDOW);
  43.  
  44.  /* Set wait pointer */
  45.  SetPointer(w, WaitPointer, 16, 16, -6, 0);
  46. }
  47.  
  48. /* Enable a window */
  49. void EnableWindow(struct Window *w, ULONG idcmp)
  50. {
  51.  /* Clear wait pointer */
  52.  ClearPointer(w);
  53.  
  54.  /* Enable IDCMP */
  55.  ModifyIDCMP(w, idcmp);
  56.  
  57.  /* Enable right mouse button */
  58.  w->Flags &= ~WFLG_RMBTRAP;
  59. }
  60.  
  61. /* Remove all remaining messages from message port */
  62. static void StripIntuiMessages(struct MsgPort *mp, struct Window *win)
  63. {
  64.  struct IntuiMessage    *msg;
  65.  struct Node            *succ;
  66.  
  67.  msg = (struct IntuiMessage *) mp->mp_MsgList.lh_Head;
  68.  
  69.  while (succ = msg->ExecMessage.mn_Node.ln_Succ) {
  70.  
  71.   if (msg->IDCMPWindow ==  win) {
  72.  
  73.    /* Intuition is about to free this message.
  74.     * Make sure that we have politely sent it back.
  75.     */
  76.    Remove((struct Node *) msg);
  77.    ReplyMsg((struct Message *) msg);
  78.   }
  79.   msg = (struct IntuiMessage *) succ;
  80.  }
  81. }
  82.  
  83. /* Close a window safely */
  84. void CloseWindowSafely(struct Window *win)
  85. {
  86.  /* we forbid here to keep out of race conditions with Intuition */
  87.  Forbid();
  88.  
  89.  /* send back any messages for this window 
  90.   * that have not yet been processed
  91.   */
  92.  StripIntuiMessages(win->UserPort, win);
  93.  
  94.  /* clear UserPort so Intuition will not free it */
  95.  win->UserPort = NULL;
  96.  
  97.  /* tell Intuition to stop sending more messages */
  98.  ModifyIDCMP(win, 0L);
  99.  
  100.  /* turn multitasking back on */
  101.  Permit();
  102.  
  103.  /* and really close the window */
  104.  CloseWindow(win);
  105. }
  106.  
  107. /* Create a list of GT gadgets */
  108. struct Gadget *CreateGadgetList(struct GadgetData *gData, ULONG gadNum, ULONG idOffset)
  109. {
  110.  struct Gadget      *ClockGads, *gad;
  111.  struct NewGadget   NewGad;
  112.  ULONG              i;
  113.  
  114.  /* Create GadTools gadget context */
  115.  ClockGads = NULL;
  116.  if (gad = CreateContext(&ClockGads)) {
  117.   NewGad.ng_TextAttr = &GrntAttr;
  118.   NewGad.ng_VisualInfo = ScreenVI;
  119.   for (i = 0; i < gadNum; i++, gData++) {
  120.    NewGad.ng_LeftEdge=gData->left;
  121.    NewGad.ng_TopEdge=gData->top;
  122.    NewGad.ng_Width=gData->width;
  123.    NewGad.ng_Height=gData->height;
  124.    NewGad.ng_GadgetText=gData->name;
  125.    NewGad.ng_GadgetID=i+idOffset;
  126.    NewGad.ng_Flags=gData->flags;
  127.  
  128.    /* Create Gadget */  
  129.    if (!(gad =
  130.    CreateGadgetA(gData->type, gad, &NewGad, gData->tags))) break;
  131.  
  132.    /* Store gadget pointer in GadgetData structure */ 
  133.    gData->gadget=gad;
  134.   }
  135.   /* Gadgets created? */
  136.   if (gad) return (ClockGads); 
  137.  
  138.   /* Couldn't create gadgets */
  139.   FreeGadgets(ClockGads);
  140.  } 
  141.  /* Return failure */
  142.  return (NULL);
  143. }
  144.  
  145. /* I was to lousy to write any special kind of routine in order to switch
  146.    between the two sides. So I decided to simply zoom it */ 
  147. static USHORT  buf[32];  
  148. void Zoom(struct Screen *s, USHORT *p, short num)
  149. {
  150.  long i, steps;
  151.  struct ColorMap *cm = s->ViewPort.ColorMap;
  152.  
  153.  /* Read current screen colors */
  154.  for (i = 0; i < num; i++)
  155.   buf[i] = GetRGB4(cm, i);
  156.  
  157.  /* Change screen colors in 16 steps */
  158.  for (steps = 0; steps < 16; steps++) {
  159.   /* Wait for vertical blank to syncronize zoom function */ 
  160.   WaitTOF();
  161.  
  162.   /* Change 'num' color registers */
  163.   for (i = 0; i < num; i++) {
  164.    /* increase/decrease RGB values */ 
  165.    if (p[i] != ~0) {
  166.     if ((buf[i] & 0xf00) > (p[i] & 0xf00))        
  167.      buf[i] -= 0x100;
  168.     else if ((buf[i] & 0xf00) < (p[i] & 0xf00))
  169.      buf[i] += 0x100;
  170.  
  171.     if ((buf[i] & 0xf0) > (p[i] & 0xf0))        
  172.      buf[i] -= 0x10;
  173.     else if ((buf[i] & 0xf0) < (p[i] & 0xf0))
  174.      buf[i] += 0x10;
  175.  
  176.     if ((buf[i] & 0xf) > (p[i] & 0xf))        
  177.      buf[i] -= 0x1;
  178.     else if ((buf[i] & 0xf) < (p[i] & 0xf))
  179.      buf[i] += 0x1;
  180.    }
  181.   }
  182.   /* Display new pallete */
  183.   LoadRGB4(&s->ViewPort, buf, num); 
  184.  }
  185. }
  186.  
  187. /* Load Iff-image
  188.    This routine is very stupid but it works with my picture */
  189. struct BitMap *OpenILBM(UBYTE *Name)
  190. {
  191.  UBYTE  *planes;
  192.  USHORT *palette, color;
  193.  long   *iffData;
  194.  
  195.  short  planeX, numRows;
  196.  long   planeSize, buffer[2];
  197.  
  198.  REGISTER BYTE        *dest, repByte;
  199.  REGISTER short        byteSum, numBytes;
  200.  REGISTER union {
  201.   BYTE    *B;
  202.   WORD    *W;
  203.   long    *L;
  204.  } uniPtr;
  205.  
  206.  struct BitMap        *map;
  207.  struct FileHandle    *iffHandle;
  208.  
  209.  /* Open iff image data */
  210.  if (iffHandle = (struct FileHandle *) Open(Name, MODE_OLDFILE)) {
  211.   /* Read image file */
  212.   if (Read((BPTR) iffHandle, &buffer[0], 8) == 8) {
  213.    /* Iff ? */
  214.    if (buffer[0] == 'FORM') {
  215.     /* Get memory for image */
  216.     if (iffData = AllocMem(buffer[1], MEMF_PUBLIC)) {
  217.      /* Memory for BitMap structure */
  218.      if (map = (struct BitMap *)
  219.            AllocMem(sizeof (struct BitMap) + 64, MEMF_PUBLIC | MEMF_CLEAR)) {
  220.       /* Read first chunk */
  221.       if (Read((BPTR)iffHandle, iffData, buffer[1]) == buffer[1]) {
  222.        /* Analyse iff */
  223.        uniPtr.L = iffData;
  224.        if (*uniPtr.L++ == 'ILBM') {
  225.         if (*uniPtr.L++ == 'BMHD') {
  226.          InitBitMap(map, uniPtr.B[12], uniPtr.W[2], uniPtr.W[3]);
  227.          uniPtr.B += *uniPtr.L + 4; 
  228.          /* Read color map */
  229.          if (*uniPtr.L == 'CMAP') {
  230.           planes = (UBYTE *) uniPtr.B + 8;        
  231.           palette = (USHORT *) &map->Planes[6];
  232.  
  233.           for (planeX = 1 << map->Depth; planeX > 0; --planeX) {
  234.            color = *planes++ << 4;
  235.            color |= *planes++;        
  236.            *palette++ = color | *planes++ >> 4;
  237.           }
  238.           /* Find body */
  239.           while (*uniPtr.L != 'BODY') {
  240.            ++uniPtr.L;
  241.            uniPtr.B += *uniPtr.L + 4;
  242.            if (uniPtr.B >= (BYTE *) iffData + buffer[1])
  243.             break;
  244.           }
  245.           /* Read Body */
  246.           if (*uniPtr.L == 'BODY') {
  247.            planeSize = map->BytesPerRow * map->Rows;
  248.            if (planes = (UBYTE *)
  249.                 AllocMem(planeSize * map->Depth, MEMF_CHIP)) {
  250.             for (planeX = 0; planeX < map->Depth; ++planeX) 
  251.              map->Planes[planeX] = (PLANEPTR) planes + planeSize * planeX;
  252.              /* Decrunch image */
  253.             uniPtr.L += 2;
  254.             for (numRows = map->Rows; numRows > 0; --numRows) {
  255.              for (planeX = 0; planeX < map->Depth; ++planeX) {
  256.               byteSum = map->BytesPerRow;
  257.               dest = (BYTE *) map->Planes[planeX];
  258.               do {
  259.                if ((numBytes = *uniPtr.B++) < 0) {
  260.                numBytes = -numBytes;
  261.                repByte = *uniPtr.B++;
  262.  
  263.                byteSum -= numBytes+1;
  264.                for (; numBytes > -1; --numBytes)
  265.                 *dest++ = repByte;
  266.                }
  267.                else {
  268.                 byteSum -= numBytes+1;
  269.                 for (; numBytes > -1; --numBytes)
  270.                  *dest++ = *uniPtr.B++;
  271.                }
  272.               } while (byteSum > 0);
  273.               map->Planes[planeX] += map->BytesPerRow;
  274.              }
  275.             }
  276.             for (planeX = 0; planeX < map->Depth; ++planeX) 
  277.              map->Planes[planeX] = map->Planes[planeX] - planeSize;
  278.  
  279.             Close((BPTR)iffHandle);
  280.             FreeMem(iffData, buffer[1]);
  281.  
  282.             return (map);
  283.            }        
  284.           }
  285.          }
  286.         }
  287.        }
  288.       } FreeMem(map, sizeof (struct BitMap) + 64);
  289.      } FreeMem(iffData, buffer[1]);
  290.     }
  291.    }
  292.   } Close((BPTR)iffHandle);
  293.  } return (FALSE);
  294. }
  295. /* Get rid of the image */
  296. void CloseILBM(map)
  297. struct BitMap *map;
  298. {
  299.  FreeMem(map->Planes[0], map->BytesPerRow * map->Rows * map->Depth);
  300.  FreeMem(map, sizeof (struct BitMap) + 64);
  301. }
  302.