/**************************************************************************** ** ** ** ShowIFF - a comfortable IFF picture viewer for CLI and Workbench ** ** by ** ** Christian A. Weber, Bruggerweg 2, CH-8037 Zürich, Switzerland ** ** ** ** INTERNET: weber@amiga.physik.unizh.ch ** ** UUCP: cbmehq!cbmswi!mighty!chris@cbmvax.commodore.com ** ** ** ** For documentation, refer to the file "ShowIFF.doc". ** ** ** ** All known formats (including Overscan, HAM, Halfbrite, SHAM) are ** ** supported. If a picture is larger than the screen, you may use the ** ** mouse to scroll around (If you have enough CHIP memory...) ** ** ** ** Any suggestions, donations or bug reports are welcome. ** ** ** ***************************************************************************** ** ** ** This program is in the Public Domain. Use it at your own risk. ** ** ** ** Requirements: - arp.library V39+ ** ** - iff.library V19+ ** ** ** ** To compile: - Lattice C compiler V5.04 or above (use 32bit ints) ** ** - The file 'arpstartup.o' (My ARP startup module) ** ** - The file 'arpglue.lib' for Printf etc. ** ** ** ***************************************************************************** ** ** ** Modification History: ** ** -------------------- ** ** ** ** 15-Oct-87 CHW V1.0 Created this file! ** ** 30-Jun-88 CHW V1.4 Directory scan fixed for FFS, cleaned up ** ** 16-Nov-88 CHW V1.5 Overscan implemented ** ** 28-Nov-88 CHW V1.6 Minimal screen size is now 64x64 pixels ** ** 02-Jan-89 CHW V1.7 Double-buffering implemented ** ** 25-Sep-89 CHW V2.01 Changed to Lattice C and ARP library ** ** 27-Sep-89 CHW V2.02 Screen scrolling implemented ** ** 22-Nov-89 CHW V2.03 Rejects Non-ILBM files correctly ** ** 21-Feb-90 CHW V2.04 'NoMemForGfx' bug fixed, overscan fixed ** ** 28-Feb-90 CHW V2.10 SHAM support code added ** ** 14-Mar-90 CHW V2.11 Memory fragmentation workaround, cleanup ** ** 08-Apr-90 CHW V2.12 Pics with more than 6 planes don't guru ** ** 22-Apr-90 CHW V2.14 New startup code, WB cleanup works now. ** ** 16-Jul-90 CHW V2.15 Works now properly with MoreRows & OS 2.0 ** ** 16-Sep-90 CHW V2.16 Scrolling SHAM pictures implemented ** ** 03-Oct-90 CHW V2.17 MaxX0 divided by 2 because of a 2.0 bug ** ** 30-Oct-90 MAB V2.20 ShowIFF can be turned into an appicon ** ** 11-Jan-91 CHW V2.21 SHAM color errors fixed ** ** 11-Jan-91 CHW V2.22 AppIcon image/pos are taken from .info file ** ** 13-Jan-91 CHW V2.23 COMMAND mode added, overscan bug fixed (?) ** ** 14-Jan-91 CHW V2.24 Icon tooltypes added, code moved around ** ** 24-Jan-91 CHW V2.25 Minor bug fixes ** ** 03-May-91 CHW V2.26 Vertical centering and NOCENTER option added ** ** 23-May-91 CHW V2.27 Pointer option added ** ** 27-May-91 CHW V2.28 True Color Table fixed and extended ** ** 23-Jun-91 CHW V2.29 AppIcon's image can be specified (ICON=...) ** ** 23-Apr-92 CHW V2.30 RasInfo-bug workaround only under V36-38 ** ** ** ****************************************************************************/ #define APPICON_MODE /* This works only with the 2.0 include files */ #include #include #include #include #include #include #include #include #include #include #include #include /* Not an official CBM file */ #ifdef APPICON_MODE #include #include #endif #define VERS "ShowIFF 2.30" #define VSTRING VERS " (23.4.92) by Christian A. Weber" #define MIN(a,b) ((a)<(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define reg register /* My favorite alias :-) */ #define ARG_PATTERN 0 /* Argument numbers for GADS() */ #define ARG_ALL 1 #define ARG_LOOP 2 #define ARG_DELAY 3 #define ARG_NOBREAK 4 #define ARG_NOCENTER 5 #define ARG_NOOVERSCAN 6 #define ARG_POINTER 7 #define ARG_COMMAND 8 #define ARG_INVALID 9 #define OPTIONSTOOLTYPE "OPTIONS" #define ICONTOOLTYPE "ICON" #define XPOSTOOLTYPE "ICONXPOS" #define YPOSTOOLTYPE "ICONYPOS" #define ICONNAMETOOLTYPE "ICONNAME" #define APPICONPORTNAME "ShowIFF-AppIcon" #define DEFAULTAPPICONNAME "IFF Picture Viewer" #define PICF_DYNA 1 /*** External references ***/ extern void exit(LONG); /* My startup code's exit function */ extern struct Process *ProcessBase; /* Pointer to our process */ extern struct Library *ArpBase; /* Also used for DOS functions */ extern struct Custom __far custom; /* For SHAM/DYNA copper list */ extern BYTE NewOS; /* 0 if Kick1.2/1.3, >0 if Kick2.x */ /*** Global definitions ***/ char VersionString[] = "\0$VER: " VSTRING "\n\r"; char WindowTitle[] = "CON:0/24/640/82/" VSTRING; char CLI_Template[] = "Patterns/...,ALL/s,L=LOOP/s,D=DELAY/k,NB=NOBREAK/s,NC=NOCENTER/s,NO=NOOVERSCAN/s,POINTER/s,COMMAND/k"; char CLI_Help[] = VSTRING "\n" "Usage: ShowIFF [files or patterns] [ALL] [LOOP] [DELAY delay] [NOBREAK]\n" "\t\t[NOCENTER] [NOOVERSCAN] [POINTER] [COMMAND \"Command %s args\"]"; char StdWindowName[] = "NIL:"; /* Standard Workbench window name */ struct Library *IconBase,*IFFBase; /* Some libraries we use */ char *argv[ARG_INVALID+1]; /* Arguments, filled in by GADS() */ BPTR wbwindow; /* Output window for Workbench mode */ struct DiskObject *dobj; /* Our icon */ LONG wbdelay=3145728; /* keep window open for 3 seconds */ IFFFILE ifffile; /* Pointer to our IFF file */ LONG delay=1000000; /* Time (in seconds) for each picture */ WORD *emptysprite; /* ShowIFF's mouse pointer sprite */ struct Picture { struct Screen *Screen; /* The picture's screen */ struct Window *Window; /* Window for mouse handling */ struct BitMap BitMap; /* CustomBitMap, can be larger than screen */ PLANEPTR MorePlanes[16]; /* Extend bitmap to 24 planes */ UWORD *SHAMColors; /* Ptr to SHAM color table array or NULL */ WORD Y0; /* Beginning of picture relative to screen */ WORD MaxX0,MaxY0; /* Scrolling limits */ UWORD ColorCount; /* Number of colors in color palette */ UWORD ColorTab[256]; /* The picture's color table */ UBYTE Flags; } pic1,pic2; /* 2 pictures for double-buffering */ struct SHAMChunk { struct Chunk Chunk; UWORD Version; UWORD Colors[1]; /* open array */ }; /***************************************************************************/ /* Free all planes of a bitmap */ void MyFreeBitMap(reg struct BitMap *bm) { reg LONG planesize=bm->BytesPerRow*bm->Rows,i; for(i=0; iDepth; ++i) if(bm->Planes[i]) { FreeMem(bm->Planes[i],planesize); bm->Planes[i]=0; } } /***************************************************************************/ /* Initialize a BitMap structure and allocate CHIP memory for the planes */ BOOL MyAllocBitMap(reg struct BitMap *bm,LONG d,LONG w,LONG h) { reg LONG planesize,i; InitBitMap(bm,d,w,h); planesize=bm->BytesPerRow*bm->Rows; for(i=0; iPlanes[i]=AllocMem(planesize,MEMF_CHIP|MEMF_CLEAR))) { MyFreeBitMap(bm); return FALSE; } return TRUE; } /***************************************************************************/ /* Adjust the X/Y position of a screen for correct overscan display */ void SetOverscan(reg struct Screen *screen) { reg x=GfxBase->NormalDisplayColumns,y=GfxBase->NormalDisplayRows; if(!(screen->ViewPort.Modes & HIRES)) x >>= 1; if( screen->ViewPort.Modes & LACE ) y <<= 1; x = (x-screen->Width ) >> 1; y = (y-screen->Height) >> 1; if(y>0) y=0; /* Avoid garbled pictures: */ if(GfxBase->ActiView->DyOffset+y < 0) y = 0-GfxBase->ActiView->DyOffset; /* Correct overscan HAM color distortions: */ if(screen->ViewPort.Modes & HAM) { if(GfxBase->ActiView->DxOffset+x < 96) x=96-GfxBase->ActiView->DxOffset; } #if 0 Printf("S(%ld,%ld) O(%ld,%ld) ",screen->Width,screen->Height,x,y); #endif // if(NewOS) MoveScreen(screen,x,y); // else { screen->ViewPort.DxOffset = x; screen->ViewPort.DyOffset = y; MakeScreen(screen); RethinkDisplay(); } } /***************************************************************************/ /* Create intermediate SHAM copper list if this is an SHAM picture */ void MakeSHAMCopList(struct Picture *pic) { reg struct UCopList *ucop; if(!pic->SHAMColors) return; /* Not an SHAM picture, no work to do */ if(ucop=AllocMem(sizeof(struct UCopList),MEMF_CLEAR)) { reg struct Screen *s=pic->Screen; reg LONG i,j,step=(s->ViewPort.Modes&LACE) ? 2:1; reg UWORD copx=GfxBase->ActiView->DxOffset+s->Width; reg UWORD y0=s->ViewPort.RasInfo->RyOffset; if(pic->Flags & PICF_DYNA) step=1; for(i=1; i<(s->Height/step); ++i) { CWAIT(ucop,pic->Y0+(i-1)*step,(UWORD)((copx>>1)%(UWORD)228)) for(j=1; j<16; ++j) CMOVE(ucop,custom.color[j],pic->SHAMColors[16*(y0+i)+j]) } CEND(ucop) // FreeVPortCopLists(&s->ViewPort); s->ViewPort.UCopIns = ucop; pic->SHAMColors[16*y0]=pic->ColorTab[0]; /* Fix some weird SHAM pics */ LoadRGB4(&s->ViewPort,&pic->SHAMColors[16*y0],16); } } /***************************************************************************/ /* Free a picture (that is a window, screen and a custom BitMap) */ void ClosePicture(reg struct Picture *pic) { if(pic->Window) { ScreenToBack(pic->Screen); if(!argv[ARG_POINTER]) ClearPointer(pic->Window); CloseWindow(pic->Window); pic->Window=0; } if(pic->Screen) { CloseScreen(pic->Screen); pic->Screen=0; } MyFreeBitMap(&pic->BitMap); RemakeDisplay(); /* remake copperlist to increase MEMF_LARGEST */ } /***************************************************************************/ /* Allocate a picture (Allocate custom BitMap, open screen and window) */ BOOL OpenPicture(reg struct Picture *pic,reg struct BitMapHeader *bmhd) { struct NewScreen ns; struct NewWindow nw; ClosePicture(pic); memset(&ns,0,sizeof(ns)); memset(&nw,0,sizeof(nw)); memset(pic,0,sizeof(*pic)); ns.Width = GfxBase->NormalDisplayColumns; ns.Height = GfxBase->NormalDisplayRows; ns.Depth = MAX(1,bmhd->nPlanes); if(ns.Depth>6) ns.Depth=4; ns.ViewModes = (UWORD)GetViewModes(ifffile); ns.Type = CUSTOMSCREEN|CUSTOMBITMAP|SCREENQUIET|SCREENBEHIND; ns.CustomBitMap = &pic->BitMap; if(!(ns.ViewModes & HIRES)) { ns.Width >>= 1; } if( ns.ViewModes & LACE) { ns.Height <<= 1; } if(argv[ARG_NOCENTER]) ns.Height = MIN(bmhd->h,ns.Height); else ns.Width = MIN(bmhd->w,ns.Width); ns.Width = MAX(128,ns.Width); ns.Height = MAX(128,ns.Height); if(!argv[ARG_NOOVERSCAN]) { if((bmhd->w > ns.Width) && (bmhd->w <= (ns.ViewModes&HIRES ? 768:384))) ns.Width = bmhd->w; if((bmhd->h>ns.Height) && (bmhd->h<=(ns.Height+(ns.ViewModes&LACE?80:40)))) ns.Height = bmhd->h; } if(MyAllocBitMap(&pic->BitMap,MAX(bmhd->nPlanes,ns.Depth), MAX(bmhd->w,ns.Width),MAX(bmhd->h,ns.Height))) { reg olddepth = pic->BitMap.Depth; pic->BitMap.Depth = ns.Depth; pic->Screen = OpenScreen(&ns); pic->BitMap.Depth = olddepth; if(nw.Screen=pic->Screen) { nw.Width = ns.Width; nw.Height = ns.Height; nw.IDCMPFlags = MOUSEBUTTONS|MOUSEMOVE|DELTAMOVE|VANILLAKEY; nw.Flags = BACKDROP|BORDERLESS|ACTIVATE|SIMPLE_REFRESH |NOCAREREFRESH|REPORTMOUSE|RMBTRAP; nw.Type = CUSTOMSCREEN; if(pic->Window=OpenWindow(&nw)) { pic->Y0=(ns.Height-bmhd->h)>>1; if(pic->Y0<0) pic->Y0=0; pic->MaxX0 = bmhd->w-ns.Width; pic->MaxY0 = bmhd->h-ns.Height; /* ** In 2.0 there's this RasInfo scrolling bug, they ** said they'll fix it for newer ROMs, so we'll do an ** explicit version check */ if(ns.ViewModes & HIRES) { if( (GfxBase->LibNode.lib_Version >= 36) && (GfxBase->LibNode.lib_Version <= 38)) pic->MaxX0 >>= 1; } if(!argv[ARG_POINTER]) SetPointer(pic->Window,emptysprite,1L,16L,0L,0L); if(bmhd->nPlanes == 24) { static UWORD truecoltab[32] = { 0x000,0x00C,0x0C0,0x0CC,0xC00,0xC0C,0xCC0,0xCCC, 0x080,0x08C,0x0F0,0x0FC,0xC80,0xC8C,0xCF0,0xCFC, 0x800,0x80C,0x8C0,0x8CC,0xF00,0xF0C,0xFC0,0xFCC, 0x880,0x88C,0x8F0,0x8FC,0xF80,0xF8C,0xFF0,0xFFC }; memcpy(pic->ColorTab,truecoltab,sizeof(truecoltab)); pic->Screen->BitMap.Planes[0]=pic->BitMap.Planes[23]; /* B7 */ pic->Screen->BitMap.Planes[1]=pic->BitMap.Planes[15]; /* G7 */ pic->Screen->BitMap.Planes[2]=pic->BitMap.Planes[7]; /* R7 */ pic->Screen->BitMap.Planes[3]=pic->BitMap.Planes[14]; /* G6 */ pic->Screen->BitMap.Planes[4]=pic->BitMap.Planes[6]; /* R7 */ pic->ColorCount = (ns.ViewModes&HIRES) ? 16:32; } else { if(!(pic->ColorCount=GetColorTab(ifffile,pic->ColorTab))) { /* Provide default colors for pictures without a CMAP */ pic->ColorCount=2; pic->ColorTab[0]=0xeca; pic->ColorTab[1]=0x000; } } if(pic->ColorCount>32) pic->ColorCount = 32; /* Old DigiView */ LoadRGB4(&pic->Screen->ViewPort,pic->ColorTab,pic->ColorCount); SetOverscan(pic->Screen); return TRUE; } } } ClosePicture(pic); return FALSE; } /***************************************************************************/ /* Close all resources and exit to CLI/WorkBench */ void Fail(reg char *reason) { Puts(reason); ClosePicture(&pic1); ClosePicture(&pic2); if(ifffile) CloseIFF(ifffile); if(dobj) FreeDiskObject(dobj); if(wbwindow) { WaitForChar(wbwindow,wbdelay); /* Let them see our text */ Close(wbwindow); } if(IFFBase) CloseLibrary(IFFBase); if(IconBase) CloseLibrary(IconBase); exit(0L); /* Back to the startup code (important for Workbench) */ } /***************************************************************************/ /* That's the big one! Load & display a picture (with mouse-scrolling), return FALSE if user presses the RMB (abort), else return TRUE */ BOOL ShowPicture(reg char *name) { reg BOOL cont=TRUE; reg struct BitMapHeader *bmhd; if(!strcmp(name+strlen(name)-5,".info")) return TRUE; /* Skip icons */ Printf("%s ... ",name); if(ifffile) CloseIFF(ifffile); if(!(ifffile=OpenIFF(name))) { Puts("- not an IFF file!"); return TRUE; } if(*(((ULONG *)ifffile)+2) != ID_ILBM) { Puts("- not an ILBM file!"); return TRUE; } if(!(bmhd=GetBMHD(ifffile))) { Printf("- Mangled IFF file (Error %ld)\n",IFFError()); return TRUE; } Printf("%ld x %ld x %ld ",bmhd->w,bmhd->h,bmhd->nPlanes); retry: if(OpenPicture(&pic1,bmhd)) { if(DecodePic(ifffile,&pic1.BitMap)) { reg struct SHAMChunk *sham; reg LONG i; reg WORD xoff=0,yoff=0; if(pic1.Y0) { struct Screen *s=pic1.Screen; ScrollRaster(&s->RastPort,0,-pic1.Y0,0,0, s->BitMap.BytesPerRow<<3,s->BitMap.Rows); } if(sham=FindChunk(ifffile,ID_SHAM)) { Printf("SHAM "); if(sham->Version == 0) { pic1.SHAMColors = sham->Colors; } else Printf("Unsupported mode: %ld ",(LONG)sham->Version); MakeSHAMCopList(&pic1); } if(sham=FindChunk(ifffile,ID_CTBL)) { Printf("DYNA "); pic1.SHAMColors = &sham->Version; /* DYNA has no version */ pic1.Flags |= PICF_DYNA; MakeSHAMCopList(&pic1); } ScreenToFront(pic1.Screen); ClosePicture(&pic2); for(i=delay*50L; i>=0; --i) { reg struct IntuiMessage *msg; WaitTOF(); while(msg=(struct IntuiMessage *)GetMsg(pic1.Window->UserPort)) { newmsg: switch(msg->Class) { case MOUSEMOVE: xoff+=msg->MouseX; yoff+=msg->MouseY; if(xoff>pic1.MaxX0) xoff=pic1.MaxX0; if(xoff<0) xoff=0; if(yoff>pic1.MaxY0) yoff=pic1.MaxY0; if(yoff<0) yoff=0; pic1.Screen->ViewPort.RasInfo->RxOffset=xoff; pic1.Screen->ViewPort.RasInfo->RyOffset=yoff; if(pic1.SHAMColors) { reg struct IntuiMessage *m2; MakeSHAMCopList(&pic1); while(m2=GetMsg(pic1.Window->UserPort)) { ReplyMsg(msg); msg=m2; if(msg->Class == MOUSEMOVE) { xoff+=msg->MouseX; yoff+=msg->MouseY; } else goto newmsg; } } /* ScrollVPort(&pic1.Screen->ViewPort); */ MakeScreen(pic1.Screen); RethinkDisplay(); break; case VANILLAKEY: if(msg->Code == 'c') if(argv[ARG_COMMAND]) { char buf[200]; SPrintf(buf,argv[ARG_COMMAND],name,name); Execute(buf,NULL,Output()); } break; case MOUSEBUTTONS: if(!argv[ARG_NOBREAK]) { if(msg->Code == MENUDOWN) goto usrbreak; if(msg->Code == SELECTDOWN) goto showend; } break; } ReplyMsg(msg); } if(!argv[ARG_NOBREAK]) if(CheckAbort(NULL)) { usrbreak: Puts("***BREAK"); cont=FALSE; goto showend2; } } showend: Puts("- Done"); showend2: pic2=pic1; memset(&pic1,0,sizeof(pic1)); } else { ClosePicture(&pic1); Printf("- Decode error: %ld\n",IFFError()); } } else if(pic2.Window) { ClosePicture(&pic2); goto retry; } else Puts("- Can't open screen!"); return cont; } /***************************************************************************/ /* Expand a pattern and call ShowPicture() for each matching file, return FALSE if the user presses ^C or ShowPicture() returns FALSE */ BOOL ShowPattern(char *pathname) { char buf[256]; reg BPTR file; reg BOOL cont=TRUE; if(PreParse(pathname,buf)) /* TRUE if name contains any wildcards */ { reg struct { struct AnchorPath APath; char FullPath[255]; /* cheap way to extend ap_Buf[] */ } *myanchor; iswild: if(myanchor=ArpAlloc(sizeof(*myanchor))) { reg BOOL showit=TRUE; reg LONG error; myanchor->APath.ap_StrLen = 255; /* Want full path built */ myanchor->APath.ap_Flags = APF_DOWILD; myanchor->APath.ap_BreakBits=SIGBREAKF_CTRL_C; error=FindFirst(pathname,&myanchor->APath); while(!error) { /* +1 because of a lattice bug */ if(SetSignal(0L,SIGBREAKF_CTRL_E+1) & SIGBREAKF_CTRL_E) { Puts("***DIR BREAK"); showit=FALSE; /* myanchor->APath.ap_Flags &= ~APF_DODIR; */ } if(myanchor->APath.ap_Info.fib_DirEntryType>=0) /* Dir */ { if(argv[ARG_ALL]) { if(!(myanchor->APath.ap_Flags & APF_DIDDIR)) { myanchor->APath.ap_Flags |= APF_DODIR; showit=TRUE; } myanchor->APath.ap_Flags &= ~APF_DIDDIR; } } else if(showit) if(!ShowPicture(myanchor->APath.ap_Buf)) { cont = FALSE; break; } error=FindNext(&myanchor->APath); } FreeAnchorChain(&myanchor->APath); switch(error) { case 0: break; case ERROR_BREAK: Puts("***BREAK"); cont=FALSE; break; case ERROR_OBJECT_NOT_FOUND: Puts("File not found."); break; case ERROR_BUFFER_OVERFLOW: Puts("Path too long!"); break; case ERROR_NO_MORE_ENTRIES: break; /* Normal termination */ default: Printf("IO error %ld!\n",error); break; } } else Fail("No mem for anchor!"); } else if(file=Open(pathname,MODE_OLDFILE)) /* Just one file ? */ { Close(file); return ShowPicture(pathname); } else /* No wildcards, and not a file: it's a device or a directory */ { strcpy(buf,pathname); TackOn(pathname=buf,"*"); goto iswild; /* Not really elegant, but it works */ } return cont; } #ifdef APPICON_MODE /***************************************************************************/ /* Started without arguments: create or delete our appicon */ void AppIconStuff(void) { struct Library *WorkbenchBase; struct MsgPort *msgport; struct AppIcon *ai; struct AppMessage *amsg; if(!(WorkbenchBase = OpenLibrary(WORKBENCH_NAME,36))) return; if(msgport=FindPort(APPICONPORTNAME)) /* Already running ? */ { Signal(msgport->mp_SigTask,SIGBREAKF_CTRL_C); /* Kill it */ } else if(msgport = CreatePort(APPICONPORTNAME,0)) { char *tooltype; struct DiskObject *appdobj=NULL; if(tooltype=FindToolType(dobj->do_ToolTypes,ICONTOOLTYPE)) appdobj=GetDiskObject(tooltype); if(!appdobj) appdobj=dobj; if(tooltype=FindToolType(dobj->do_ToolTypes,XPOSTOOLTYPE)) appdobj->do_CurrentX = Atol(tooltype); else appdobj->do_CurrentX = NO_ICON_POSITION; if(tooltype=FindToolType(dobj->do_ToolTypes,YPOSTOOLTYPE)) appdobj->do_CurrentY = Atol(tooltype); else appdobj->do_CurrentY = NO_ICON_POSITION; if(!(tooltype=FindToolType(dobj->do_ToolTypes,ICONNAMETOOLTYPE))) tooltype = DEFAULTAPPICONNAME; if(ai = AddAppIconA(0,0,tooltype,msgport,NULL,appdobj,NULL)) { while(!(Wait(1L << msgport->mp_SigBit | SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)) { reg BPTR oldcos; if(wbwindow=Open(WindowTitle,MODE_OLDFILE)) { oldcos = ProcessBase->pr_COS; ProcessBase->pr_COS = wbwindow; } while(amsg = GetMsg(msgport)) { reg i,cont=TRUE; struct WBArg *arg = amsg->am_ArgList; for(i=0; (i < amsg->am_NumArgs) && cont; i++,arg++) { reg BPTR oldcd=0; if(arg->wa_Lock) oldcd=CurrentDir(arg->wa_Lock); else DisplayBeep(NULL); cont=ShowPattern(arg->wa_Name&&*arg->wa_Name ? arg->wa_Name:"*"); if(oldcd) CurrentDir(oldcd); } ReplyMsg(amsg); } ClosePicture(&pic2); /* Close last screen */ if(wbwindow) { WaitForChar(wbwindow,2097152); /* Wait 2 seconds */ ProcessBase->pr_COS = oldcos; Close(wbwindow); wbwindow=0; SetSignal(0,SIGBREAKF_CTRL_C); /* Clear break sig */ } } RemoveAppIcon(ai); } if(appdobj != dobj) FreeDiskObject(appdobj); /* Make sure there are no more messages pending */ while(amsg = GetMsg(msgport)) ReplyMsg(amsg); DeletePort(msgport); } CloseLibrary(WorkbenchBase); } #endif /***************************************************************************/ /* Main program: parse the command line or WorkBench-args */ void ARPMain(LONG arglen,reg char *argline) { if(!(IconBase = OpenLibrary("icon.library",0))) Fail("No icon.library!"); if(!(IFFBase = OpenLibrary(IFFNAME,0L))) Fail("No iff.library!"); if(IFFBase->lib_Version < IFFVERSION) Puts("WARNING: you have an old version of iff.library!"); emptysprite=ArpAllocMem(20L,MEMF_CHIP|MEMF_CLEAR); if(arglen) /* From CLI */ { if(*argline != '\n') { if(GADS(argline,strlen(argline),CLI_Help,argv,CLI_Template)>0) { if(argv[ARG_DELAY]) delay=Atol(argv[ARG_DELAY]); do { reg char **pattern=(char **)argv[ARG_PATTERN]; if(*pattern) { while(*pattern) if(!ShowPattern(*pattern++)) goto done; } else ShowPattern("*"); } while(argv[ARG_LOOP]); done: ; } else Fail(CLI_Help); } else Fail(CLI_Help); } else /* Called from Workbench */ { reg struct WBStartup *startup = (struct WBStartup *)argline; argv[ARG_ALL] = (void *)TRUE; /* Set defaults */ // argv[ARG_LOOP] = (void *)FALSE; // argv[ARG_NOBREAK] = (void *)FALSE; // argv[ARG_NOOVERSCAN] = (void *)FALSE; if(dobj = GetDiskObject(startup->sm_ArgList->wa_Name)) { reg char *tooltype; if(tooltype=FindToolType(dobj->do_ToolTypes,OPTIONSTOOLTYPE)) { GADS(tooltype,strlen(tooltype),NULL,argv,CLI_Template); if(argv[ARG_DELAY]) delay=Atol(argv[ARG_DELAY]); } } if(startup->sm_NumArgs > 1) /* Started with some arguments */ { reg i; struct WBArg *arg = startup->sm_ArgList; if(wbwindow=Open(WindowTitle,MODE_OLDFILE)) /* Open window */ ProcessBase->pr_COS=wbwindow; for(i=1; ism_NumArgs; ++i) { arg++; if(arg->wa_Lock) CurrentDir(arg->wa_Lock); else Puts("Can't lock dir!"); if(arg->wa_Name && *arg->wa_Name) { if(!ShowPattern(arg->wa_Name)) break; } else ShowPattern("*"); } } else /* no arguments, just clicked */ #ifdef APPICON_MODE if(NewOS) AppIconStuff(); else #endif { if(wbwindow=Open(WindowTitle,MODE_OLDFILE)) /* Open window */ ProcessBase->pr_COS=wbwindow; wbdelay=6291456; /* 6 seconds delay */ #ifdef GERMAN Fail("Bitte klicken Sie alle gewünschten Bild-Dateien oder Schubladen bei ge-\n" "drückter SHIFT-Taste an, klicken Sie danach 2x auf das ShowIFF-Piktogramm."); #else Fail("Please select all drawers and files to view while holding\n" "down the SHIFT key, then double-click the ShowIFF icon."); #endif } } wbdelay=1048576; /* One second delay */ #ifdef GERMAN Fail("Fertig."); #else Fail("All done."); #endif }