/* * ViewILBM.c * Read an ILBM file and display as a screen/window until closed. * Simulated close gadget in upper left corner of window. * Clicking below title bar area toggles screen bar for dragging. * Handles normal and HAM ILBM's * * By Carolyn Scheppner CBM 03/15/86 * Modified 09/02/86 - Only global frame is iFrame * Use message->MouseX and Y * Wait() for IDCMP * Modified 10/15/86 - For HAM * Name changed from SeeILBM to ViewILBM * Modified 11/01/86 - Revised for linkage with myreadpict.c * Modified 11/18/86 - For Astartup ... Amiga.lib, LC.lib linkage * * Based on ShowILBM.c, readpict.c 1/86 * By Jerry Morrison, Steve Shaw, and Steve Hayes, Electronic Arts. * This software is in the public domain. * * >>NOTE<<: This example must be linked with additional IFF rtn files. * See linkage information below. * * The display portion is specific to the Commodore Amiga computer. * * Linkage Information: * (NOTE: All modules including iff stuff compiled with -v on LC2) * * FROM AStartup.obj,ViewILBM.o,myreadpict.o,iffr.o,ilbmr.o,unpacker.o * TO ViewILBM * LIBRARY Amiga.lib, LC.lib * */ #include #include #include #include #include #include #include #include #include #include #include "iff/ilbm.h" #include "myreadpict.h" /* For wbStdio rtns */ extern LONG stdin, stdout, stderr; /* in Astartup.obj */ char conSpec[] = "CON:0/40/640/140/>> ViewILBM <<"; BOOL wbHasStdio = NULL; /* general usage pointers */ struct GfxBase *GfxBase; struct IntuitionBase *IntuitionBase; struct IntuiMessage *message; /* Globals for displaying an image */ struct Screen *screen1; struct Window *window1; struct RastPort *rport1; struct ViewPort *vport1; struct BitMap tBitMap; /* Temp BitMap struct for small pics */ /* For WorkBench startup */ extern struct WBStartup *WBenchMsg; BOOL fromWB; struct FileLock *startLock, *newLock; /* Other globals */ int i, error; BYTE c; BOOL TBtoggle, Done; ULONG class, code, pBytes; SHORT mouseX, mouseY; /* Structures for new Screen, new Window */ struct TextAttr TextFont = { "topaz.font", /* Font Name */ TOPAZ_EIGHTY, /* Font Height */ FS_NORMAL, /* Style */ FPF_ROMFONT, /* Preferences */ }; struct NewScreen ns = { 0, 0, /* LeftEdge and TopEdge */ 0, 0, /* Width and Height */ 0, /* Depth */ 1, 0, /* DetailPen and BlockPen */ NULL, /* Special display modes */ CUSTOMSCREEN, /* Screen Type */ &TextFont, /* Use my font */ " <- Close here after clicking below", /* Title */ NULL, /* No gadgets yet */ NULL, /* Ptr to CustomBitmap */ }; struct NewWindow nw = { 0, 0, /* LeftEdge and TopEdge */ 0, 0, /* Width and Height */ -1, -1, /* DetailPen and BlockPen */ MOUSEBUTTONS, /* IDCMP Flags */ ACTIVATE |BACKDROP |BORDERLESS, /* Flags */ NULL, NULL, /* Gadget and Image pointers */ NULL, /* Title string */ NULL, /* Put Screen ptr here */ NULL, /* SuperBitMap pointer */ 0, 0, /* MinWidth and MinHeight */ 0, 0, /* MaxWidth and MaxHeight */ CUSTOMSCREEN, /* Type of window */ }; USHORT allBlack[32] = {0}; #ifndef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) #endif MIN extern char *IFFPMessages[]; ILBMFrame iFrame; /* my global frame */ /*****************************************************************/ main(argc, argv) int argc; char **argv; { LONG file; IFFP iffp = NO_FILE; struct WBArg *arg; char *filename; fromWB = (argc==0) ? TRUE : FALSE; if(argc>1) /* Passed filename via command line */ { filename = argv[1]; } else if ((argc==0)&&(WBenchMsg->sm_NumArgs > 1)) { /* Passed filename via WorkBench */ arg = WBenchMsg->sm_ArgList; arg++; filename = (char *)arg->wa_Name; newLock = (struct FileLock *)arg->wa_Lock; startLock = (struct FileLock *)CurrentDir(newLock); } else if (argc==1) /* From CLI but no filename */ cleanexit("Usage: 'ViewILBM filename'\n"); else /* From WB but no filename */ cleanexit( "Usage:\nClick ONCE on ViewILBM\nSHIFT and DoubleClick on Pic\n"); if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0))) cleanexit("Can't open graphics library\n"); if(!(IntuitionBase= (struct IntuitionBase *)OpenLibrary("intuition.library",0))) cleanexit("Can't open graphics library\n"); if(file = Open(filename, MODE_OLDFILE)) { iffp = myReadPicture(file,&iFrame); Close(file); if (iffp == IFF_DONE) { error = DisplayPic(&iFrame); if(error) cleanexit("Can't open screen or window\n"); TBtoggle = FALSE; /* Title bar toggle */ Done = FALSE; /* Close flag */ while (!Done) { Wait(1<UserPort->mp_SigBit); chkmsg(); } } else cleanexit(IFFPMessages[-iffp]); } else cleanexit("Picture file not found.\n"); cleanup(); } chkmsg() { while(message=(struct IntuiMessage *)GetMsg(window1->UserPort)) { class = message->Class; code = message->Code; mouseX = message->MouseX; mouseY = message->MouseY; ReplyMsg(message); switch(class) { case MOUSEBUTTONS: if ((code == SELECTDOWN)&& (mouseX < 10)&&(mouseY<10)) { Done = TRUE; } else if ((code == SELECTDOWN)&& ((mouseY>10)||(mouseX>10))&& (TBtoggle==FALSE)) { TBtoggle = TRUE; ShowTitle(screen1,TRUE); } else if ((code == SELECTDOWN)&& (mouseY>10)&&(TBtoggle==TRUE)) { TBtoggle = FALSE; ShowTitle(screen1,FALSE); } break; default: break; } } } cleanexit(s) char *s; { if (*s) { if ((fromWB)&&(! wbHasStdio)) wbHasStdio = openStdio(conSpec); if ((!fromWB)||(wbHasStdio)) { printf("\n%s\n",s); } if (wbHasStdio) { printf("\nPRESS RETURN TO EXIT\n"); while (getchar() != '\n'); } } cleanup(); if (wbHasStdio) closeStdio(); exit(); } cleanup() { /* tBitMap planes were deallocated in DisplayPic() */ if (window1) { while(message=(struct IntuiMessage *)GetMsg(window1->UserPort)) { ReplyMsg(message); } CloseWindow(window1); } if (screen1) CloseScreen(screen1); if (IntuitionBase) CloseLibrary(IntuitionBase); if (GfxBase) CloseLibrary(GfxBase); if (newLock != startLock) CurrentDir(startLock); } /** getBitMap() ********************************************************* * * Open screen or temp bitmap. * Returns ptr destBitMap or 0 = error * *************************************************************************/ struct BitMap *getBitMap(ptilbmFrame) ILBMFrame *ptilbmFrame; { int i, nPlanes, plsize; SHORT sWidth, sHeight, dWidth, dHeight; struct BitMap *destBitMap; sWidth = ptilbmFrame->bmHdr.w; sHeight = ptilbmFrame->bmHdr.h; dWidth = ptilbmFrame->bmHdr.pageWidth; dHeight = ptilbmFrame->bmHdr.pageHeight; nPlanes = MIN(ptilbmFrame->bmHdr.nPlanes, EXDepth); ns.Width = dWidth; ns.Height = dHeight; ns.Depth = nPlanes; if (ptilbmFrame->foundCAMG) { ns.ViewModes = ptilbmFrame->camgChunk.ViewModes; } else { if (ptilbmFrame->bmHdr.pageWidth <= 320) ns.ViewModes = 0; else ns.ViewModes = HIRES; if (ptilbmFrame->bmHdr.pageHeight > 200) ns.ViewModes |= LACE; } if ((screen1 = (struct Screen *)OpenScreen(&ns))==NULL) return(0); vport1 = &screen1->ViewPort; LoadRGB4(vport1, &allBlack[0], ptilbmFrame->nColorRegs); if((ptilbmFrame->camgChunk.ViewModes)&(HAM)) setHam(screen1,FALSE); nw.Width = dWidth; nw.Height = dHeight; nw.Screen = screen1; if ((window1 = (struct Window *)OpenWindow(&nw))==NULL) { CloseScreen(screen1); screen1 = NULL; return(0); } ShowTitle(screen1, FALSE); if ((sWidth == dWidth) && (sHeight == dHeight)) { destBitMap = (struct BitMap *)screen1->RastPort.BitMap; } else { InitBitMap( &tBitMap, nPlanes, sWidth, sHeight); plsize = RowBytes(ptilbmFrame->bmHdr.w) * ptilbmFrame->bmHdr.h; if (tBitMap.Planes[0] = (PLANEPTR)AllocMem(nPlanes * plsize, MEMF_CHIP)) { for (i = 1; i < nPlanes; i++) tBitMap.Planes[i] = (PLANEPTR)tBitMap.Planes[0] + plsize*i; destBitMap = &tBitMap; } else { CloseWindow(window1); window1 = NULL; CloseScreen(screen1); screen1 = NULL; return(0); /* can't allocate temp BitMap */ } } return(destBitMap); /* destBitMap allocated */ } /** DisplayPic() ********************************************************* * * Display loaded bitmap. If tBitMap, first transfer to screen. * *************************************************************************/ DisplayPic(ptilbmFrame) ILBMFrame *ptilbmFrame; { int i, row, byte, nrows, nbytes; struct BitMap *tbp, *sbp; /* temp and screen BitMap ptrs */ UBYTE *tpp, *spp; /* temp and screen plane ptrs */ if (tBitMap.Planes[0]) /* transfer from tBitMap if nec. */ { tbp = &tBitMap; sbp = screen1->RastPort.BitMap; nrows = MIN(tbp->Rows, sbp->Rows); nbytes = MIN(tbp->BytesPerRow, sbp->BytesPerRow); for (i = 0; i < sbp->Depth; i++) { tpp = (UBYTE *)tbp->Planes[i]; spp = (UBYTE *)sbp->Planes[i]; for (row = 0; row < nrows; row++) { tpp = tbp->Planes[i] + (row * tbp->BytesPerRow); spp = sbp->Planes[i] + (row * sbp->BytesPerRow); for (byte = 0; byte < nbytes; byte++) { *spp++ = *tpp++; } } } /* Can now deallocate the temp BitMap */ FreeMem(tBitMap.Planes[0], tBitMap.BytesPerRow * tBitMap.Rows * tBitMap.Depth); } vport1 = &screen1->ViewPort; LoadRGB4(vport1, ptilbmFrame->colorMap, ptilbmFrame->nColorRegs); if((ptilbmFrame->camgChunk.ViewModes)&(HAM)) setHam(screen1,TRUE); return(0); } /* setHam --- For toggling HAM so HAM pic invisible while loading */ setHam(scr,toggle) struct Screen *scr; BOOL toggle; { struct ViewPort *vp; struct View *v; vp = &(scr->ViewPort); v = (struct View *)ViewAddress(); Forbid(); if(toggle) { v->Modes |= HAM; vp->Modes |= HAM; } else { v->Modes &= ~HAM; vp->Modes &= ~HAM; } MakeScreen(scr); RethinkDisplay(); Permit(); } /* wbStdio.c --- Open an Amiga stdio window under workbench * For use with AStartup.obj */ openStdio(conspec) char *conspec; { LONG wfile; struct Process *proc; struct FileHandle *handle; if (wbHasStdio) return(1); if (!(wfile = Open(conspec,MODE_NEWFILE))) return(0); stdin = wfile; stdout = wfile; stderr = wfile; handle = (struct FileHandle *)(wfile << 2); proc = (struct Process *)FindTask(NULL); proc->pr_ConsoleTask = (APTR)(handle->fh_Type); proc->pr_CIS = (BPTR)stdin; proc->pr_COS = (BPTR)stdout; return(1); } closeStdio() { struct Process *proc; struct FileHandle *handle; if (! wbHasStdio) return(0); if (stdin > 0) Close(stdin); stdin = -1; stdout = -1; stderr = -1; handle = (struct FileHandle *)(stdin << 2); proc = (struct Process *)FindTask(NULL); proc->pr_ConsoleTask = NULL; proc->pr_CIS = NULL; proc->pr_COS = NULL; wbHasStdio = NULL; }