/* * misc.c V1.1 * * miscellaneous support routines * * (c) 1992-1993 Holger Brunst */ #include /* Wait pointer image data */ static __chip const UWORD WaitPointer[] = { 0x0000, 0x0000, 0x0400, 0x07c0, 0x0000, 0x07c0, 0x0100, 0x0380, 0x0000, 0x07e0, 0x07c0, 0x1ff8, 0x1ff0, 0x3fec, 0x3ff8, 0x7fde, 0x3ff8, 0x7fbe, 0x7ffc, 0xff7f, 0x7efc, 0xffff, 0x7ffc, 0xffff, 0x3ff8, 0x7ffe, 0x3ff8, 0x7ffe, 0x1ff0, 0x3ffc, 0x07c0, 0x1ff8, 0x0000, 0x07e0, 0x0000, 0x0000 }; /* Disable a window */ void DisableWindow(struct Window *w) { /* Disable right mouse button */ w->Flags |= WFLG_RMBTRAP; /* Disable IDCMP */ ModifyIDCMP(w, IDCMP_REFRESHWINDOW); /* Set wait pointer */ SetPointer(w, WaitPointer, 16, 16, -6, 0); } /* Enable a window */ void EnableWindow(struct Window *w, ULONG idcmp) { /* Clear wait pointer */ ClearPointer(w); /* Enable IDCMP */ ModifyIDCMP(w, idcmp); /* Enable right mouse button */ w->Flags &= ~WFLG_RMBTRAP; } /* Remove all remaining messages from message port */ static void StripIntuiMessages(struct MsgPort *mp, struct Window *win) { struct IntuiMessage *msg; struct Node *succ; msg = (struct IntuiMessage *) mp->mp_MsgList.lh_Head; while (succ = msg->ExecMessage.mn_Node.ln_Succ) { if (msg->IDCMPWindow == win) { /* Intuition is about to free this message. * Make sure that we have politely sent it back. */ Remove((struct Node *) msg); ReplyMsg((struct Message *) msg); } msg = (struct IntuiMessage *) succ; } } /* Close a window safely */ void CloseWindowSafely(struct Window *win) { /* we forbid here to keep out of race conditions with Intuition */ Forbid(); /* send back any messages for this window * that have not yet been processed */ StripIntuiMessages(win->UserPort, win); /* clear UserPort so Intuition will not free it */ win->UserPort = NULL; /* tell Intuition to stop sending more messages */ ModifyIDCMP(win, 0L); /* turn multitasking back on */ Permit(); /* and really close the window */ CloseWindow(win); } /* Create a list of GT gadgets */ struct Gadget *CreateGadgetList(struct GadgetData *gData, ULONG gadNum, ULONG idOffset) { struct Gadget *ClockGads, *gad; struct NewGadget NewGad; ULONG i; /* Create GadTools gadget context */ ClockGads = NULL; if (gad = CreateContext(&ClockGads)) { NewGad.ng_TextAttr = &GrntAttr; NewGad.ng_VisualInfo = ScreenVI; for (i = 0; i < gadNum; i++, gData++) { NewGad.ng_LeftEdge=gData->left; NewGad.ng_TopEdge=gData->top; NewGad.ng_Width=gData->width; NewGad.ng_Height=gData->height; NewGad.ng_GadgetText=gData->name; NewGad.ng_GadgetID=i+idOffset; NewGad.ng_Flags=gData->flags; /* Create Gadget */ if (!(gad = CreateGadgetA(gData->type, gad, &NewGad, gData->tags))) break; /* Store gadget pointer in GadgetData structure */ gData->gadget=gad; } /* Gadgets created? */ if (gad) return (ClockGads); /* Couldn't create gadgets */ FreeGadgets(ClockGads); } /* Return failure */ return (NULL); } /* I was to lousy to write any special kind of routine in order to switch between the two sides. So I decided to simply zoom it */ static USHORT buf[32]; void Zoom(struct Screen *s, USHORT *p, short num) { long i, steps; struct ColorMap *cm = s->ViewPort.ColorMap; /* Read current screen colors */ for (i = 0; i < num; i++) buf[i] = GetRGB4(cm, i); /* Change screen colors in 16 steps */ for (steps = 0; steps < 16; steps++) { /* Wait for vertical blank to syncronize zoom function */ WaitTOF(); /* Change 'num' color registers */ for (i = 0; i < num; i++) { /* increase/decrease RGB values */ if (p[i] != ~0) { if ((buf[i] & 0xf00) > (p[i] & 0xf00)) buf[i] -= 0x100; else if ((buf[i] & 0xf00) < (p[i] & 0xf00)) buf[i] += 0x100; if ((buf[i] & 0xf0) > (p[i] & 0xf0)) buf[i] -= 0x10; else if ((buf[i] & 0xf0) < (p[i] & 0xf0)) buf[i] += 0x10; if ((buf[i] & 0xf) > (p[i] & 0xf)) buf[i] -= 0x1; else if ((buf[i] & 0xf) < (p[i] & 0xf)) buf[i] += 0x1; } } /* Display new pallete */ LoadRGB4(&s->ViewPort, buf, num); } } /* Load Iff-image This routine is very stupid but it works with my picture */ struct BitMap *OpenILBM(UBYTE *Name) { UBYTE *planes; USHORT *palette, color; long *iffData; short planeX, numRows; long planeSize, buffer[2]; REGISTER BYTE *dest, repByte; REGISTER short byteSum, numBytes; REGISTER union { BYTE *B; WORD *W; long *L; } uniPtr; struct BitMap *map; struct FileHandle *iffHandle; /* Open iff image data */ if (iffHandle = (struct FileHandle *) Open(Name, MODE_OLDFILE)) { /* Read image file */ if (Read((BPTR) iffHandle, &buffer[0], 8) == 8) { /* Iff ? */ if (buffer[0] == 'FORM') { /* Get memory for image */ if (iffData = AllocMem(buffer[1], MEMF_PUBLIC)) { /* Memory for BitMap structure */ if (map = (struct BitMap *) AllocMem(sizeof (struct BitMap) + 64, MEMF_PUBLIC | MEMF_CLEAR)) { /* Read first chunk */ if (Read((BPTR)iffHandle, iffData, buffer[1]) == buffer[1]) { /* Analyse iff */ uniPtr.L = iffData; if (*uniPtr.L++ == 'ILBM') { if (*uniPtr.L++ == 'BMHD') { InitBitMap(map, uniPtr.B[12], uniPtr.W[2], uniPtr.W[3]); uniPtr.B += *uniPtr.L + 4; /* Read color map */ if (*uniPtr.L == 'CMAP') { planes = (UBYTE *) uniPtr.B + 8; palette = (USHORT *) &map->Planes[6]; for (planeX = 1 << map->Depth; planeX > 0; --planeX) { color = *planes++ << 4; color |= *planes++; *palette++ = color | *planes++ >> 4; } /* Find body */ while (*uniPtr.L != 'BODY') { ++uniPtr.L; uniPtr.B += *uniPtr.L + 4; if (uniPtr.B >= (BYTE *) iffData + buffer[1]) break; } /* Read Body */ if (*uniPtr.L == 'BODY') { planeSize = map->BytesPerRow * map->Rows; if (planes = (UBYTE *) AllocMem(planeSize * map->Depth, MEMF_CHIP)) { for (planeX = 0; planeX < map->Depth; ++planeX) map->Planes[planeX] = (PLANEPTR) planes + planeSize * planeX; /* Decrunch image */ uniPtr.L += 2; for (numRows = map->Rows; numRows > 0; --numRows) { for (planeX = 0; planeX < map->Depth; ++planeX) { byteSum = map->BytesPerRow; dest = (BYTE *) map->Planes[planeX]; do { if ((numBytes = *uniPtr.B++) < 0) { numBytes = -numBytes; repByte = *uniPtr.B++; byteSum -= numBytes+1; for (; numBytes > -1; --numBytes) *dest++ = repByte; } else { byteSum -= numBytes+1; for (; numBytes > -1; --numBytes) *dest++ = *uniPtr.B++; } } while (byteSum > 0); map->Planes[planeX] += map->BytesPerRow; } } for (planeX = 0; planeX < map->Depth; ++planeX) map->Planes[planeX] = map->Planes[planeX] - planeSize; Close((BPTR)iffHandle); FreeMem(iffData, buffer[1]); return (map); } } } } } } FreeMem(map, sizeof (struct BitMap) + 64); } FreeMem(iffData, buffer[1]); } } } Close((BPTR)iffHandle); } return (FALSE); } /* Get rid of the image */ void CloseILBM(map) struct BitMap *map; { FreeMem(map->Planes[0], map->BytesPerRow * map->Rows * map->Depth); FreeMem(map, sizeof (struct BitMap) + 64); }