home *** CD-ROM | disk | FTP | other *** search
- /********************************************** Date: 20-Feb-89 *****/
- /* */
- /* Vedi.c - written by Diego Perini, based on Rett Andersen's ideas */
- /* */
- /* Copyright (C) 1989, QUEST Software - Verona - IT */
- /* All rights reserved */
- /* */
- /* Last modified: 22 March 1990 Registered Developer: ECI004 */
- /* */
- /* Show any kind of IFF pictures including the new IFF_BEAM Picture */
- /* */
- /********************************************************************/
- /* */
- /* IFF Format and routines in pd courtesy of Electronic Arts and C= */
- /* */
- /********************************************************************/
- /* */
- /* Released in the public domain to spread the use of BeamPalettes. */
- /* */
- /* Feel free to modify it and include it in your valuable projects. */
- /* */
- /********************************************************************/
-
- #include <exec/types.h>
- #include <exec/tasks.h>
- #include <exec/memory.h>
- #include <exec/interrupts.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <graphics/view.h>
- #include <graphics/gfxbase.h>
- #include <graphics/gfxmacros.h>
- #include <hardware/custom.h>
- #include <hardware/intbits.h>
- #include <hardware/dmabits.h>
- #include <intuition/intuitionbase.h>
- #include <workbench/workbench.h>
- #include <workbench/startup.h>
-
- #include <iff/ilbm.h>
- #include <iff/readpict.h>
-
- #include <functions.h>
-
- #define LOCAL static
-
- #define VERSION 1
- #define REVISION 18
-
- #define MIN(a,b) ((a)<(b)?(a):(b))
- #define MAX(a,b) ((a)>(b)?(a):(b))
-
- /* MAX_SCAN_LINES value should be changed to allow for NTSC support */
- #define MAX_COLS_WIDTH 768 /* max # of cols horizzont */
- #define MAX_SCAN_LINES 592 /* max # of lines vertical */
- #define MAX_COLOR_REGS 32 /* max # of color register */
-
- #define EHB EXTRA_HALFBRITE /* EHB short like HAM.(dp) */
-
- #define HX MAX_COLS_WIDTH + 1 /* used in DisplayPic() to */
- #define LX MAX_COLS_WIDTH / 2 + 1 /* check picture x limit's */
-
- #define HY MAX_SCAN_LINES + 1 /* used in DisplayPic() to */
- #define LY MAX_SCAN_LINES / 2 + 1 /* check picture y limit's */
-
- struct Preferences *Prefs; /* ptr to Preferences */
-
- struct GfxBase *GfxBase; /* ptr to GfxBase */
- struct IntuitionBase *IntuitionBase; /* ptr to IntuitionBase */
-
- LOCAL struct ViewPort *vp = {0}; /* the viewport we get */
- LOCAL struct BitMap bm = {0}; /* the bitmap allocated */
-
- LOCAL struct Screen *screen; /* my wonderfull screen */
- LOCAL struct Window *window; /* my backdrop window */
-
- struct UCopList *ucoplist; /* for copper lists */
-
- struct Interrupt CopInt; /* for copper interrupts */
-
- LOCAL ILBMFrame iFrame; /* current ILBM Frame */
-
- LOCAL struct WBStartup *wbStartup = NULL; /* workbench arguments */
- extern struct WBStartup *WBenchMsg; /* workbench message */
-
- LOCAL struct IntuiMessage *msg; /* message structure */
-
- unsigned long
- class = NULL, /* message class */
- code = NULL, /* message code */
- count = NULL; /* current scan line */
-
- BOOL Quit; /* used in wait user end */
-
- short NormalCols, NormalRows; /* don't ask me about */
-
- int ScreenNTSC = 0; /* this set your system */
-
- extern UWORD BeamPalette[MAX_SCAN_LINES][MAX_COLOR_REGS];
- /* hold the palette for 592 lines */
- /* for Interlaced Overscan in PAL */
-
- USHORT Black[32] = {0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000};
- /* used to clear the main screen */
-
- struct NewScreen ns = {
- 0, 0, /* LeftEdge and TopEdge */
- 8, 8, /* Width and Height */
- 1, /* Depth */
- 0, 1, /* DetailPen and BlockPen */
- NULL, /* Special display modes */
- CUSTOMSCREEN, /* Screen Type */
- NULL, /* Use my font */
- NULL, /* Title of the screen */
- NULL, /* No gadgets yet */
- NULL /* Ptr to CustomBitmap */
- };
-
- struct NewWindow nw ={
- 0, 0, /* LeftEdge and TopEdge */
- 8, 8, /* Width and Height */
- -1, -1, /* DetailPen and BlockPen */
- VANILLAKEY, /* Intuition IDCMP Flags */
- ACTIVATE
- |SMART_REFRESH
- |RMBTRAP
- |BACKDROP
- |BORDERLESS, /* New Window Flags */
- NULL, NULL, /* Gadget, Image pointers */
- NULL, /* Title of the window */
- NULL, /* Put Screen ptr here */
- NULL, /* SuperBitMap pointer */
- 10, 10, /* MinWidth and MinHeight */
- 768, MAX_SCAN_LINES, /* MaxWidth and MaxHeight */
- CUSTOMSCREEN /* Type of window */
- };
-
- LOCAL char MsgOkay[] = { "(IFF_OKAY) Didn't find a FORM ILBM in the file." };
- LOCAL char MsgEndMark[] = { "(END_MARK) How did you get this message?" };
- LOCAL char MsgDone[] = { "(IFF_DONE) All done."};
- LOCAL char MsgDos[] = { "(DOS_ERROR) The DOS returned an error." };
- LOCAL char MsgNot[] = { "(NOT_IFF) Not an IFF file." };
- LOCAL char MsgNoFile[] = { "(NO_FILE) No such file found." };
- LOCAL char MsgClientError[] = { "(CLIENT_ERROR) Vedi bug or insufficient RAM."};
- LOCAL char MsgForm[] = { "(BAD_FORM) A malformed FORM ILBM." };
- LOCAL char MsgShort[] = { "(SHORT_CHUNK) A malformed FORM ILBM." };
- LOCAL char MsgBad[] = { "(BAD_IFF) A mangled IFF file." };
-
- LOCAL char *IFFPMessages[-(long)LAST_ERROR+1] = {
- MsgOkay, /* IFF_OKAY */
- MsgEndMark, /* END_MARK */
- MsgDone, /* IFF_DONE */
- MsgDos, /* DOS_ERROR */
- MsgNot, /* NOT_IFF */
- MsgNoFile, /* NO_FILE */
- MsgClientError, /* CLIENT_ERROR */
- MsgForm, /* BAD_FORM */
- MsgShort, /* SHORT_CHUNK */
- MsgBad /* BAD_IFF */
- };
-
- struct UCopList *
- MakeBeamList(nRows,nCols) /*----- Generates Screen Copper List -----*/
- int nRows;
- int nCols;
- {
- struct UCopList *ucoplist;
- struct CopIns *copins;
- int i, j, step;
-
- if (vp->Modes & LACE)
- step = 2;
- else
- step = 1;
-
- SetRGB4(vp, 0L, 0L, 0L, 0L);
- for( j = 1 ; j < nCols ; j++ ) {
- SetRGB4(vp, (long)j,
- (long)((BeamPalette[0][j] >> 8 ) & 0xf),
- (long)((BeamPalette[0][j] >> 4 ) & 0xf),
- (long)((BeamPalette[0][j] >> 0 ) & 0xf));
- }
-
- ucoplist = (struct UCopList *)AllocMem(12L,MEMF_PUBLIC|MEMF_CLEAR);
-
- CINIT(ucoplist, (long)(nRows + nRows * nCols + 2));
-
- for( i = step ; i < nRows ; i += step ) {
- copins = ucoplist->FirstCopList->CopPtr;
- CWAIT(ucoplist, (long)(i), 0L);
- copins->OpCode |= CPR_NT_LOF;
-
- for( j = 1 ; j < nCols ; j++ ) {
- copins = ucoplist->FirstCopList->CopPtr;
- CMOVE(ucoplist, custom.color[j], (long)BeamPalette[i][j]);
- copins->OpCode |= CPR_NT_LOF;
- }
-
- if (vp->Modes & LACE) {
- copins = ucoplist->FirstCopList->CopPtr;
- CWAIT(ucoplist, (long)(i), 0L);
- copins->OpCode |= CPR_NT_SHT;
-
- for( j = 1 ; j < nCols ; j++ ) {
- copins = ucoplist->FirstCopList->CopPtr;
- CMOVE(ucoplist, custom.color[j], (long)BeamPalette[i+1][j]);
- copins->OpCode |= CPR_NT_SHT;
- }
- }
- }
-
- CEND(ucoplist);
-
- return(ucoplist);
- }
-
- struct BitMap *
- getBitMap(ptilbmFrame) /*----- Open screen & return bitmap ptr -----*/
- ILBMFrame *ptilbmFrame;
- {
- struct BitMap *destBitMap; /* a BitMap ptr */
-
- ns.Width = ptilbmFrame->bmHdr.w; /* screen width */
- ns.Height = ptilbmFrame->bmHdr.h; /* screen height */
- ns.Depth = ptilbmFrame->bmHdr.nPlanes; /* screen depth */
- ns.Type |= SCREENBEHIND; /* screen opens in the back of Wb */
- ns.ViewModes = NULL; /* no modes yet */
-
- /* if a CAMG chunk exists set the modes according to it's values */
- if ( ptilbmFrame->foundCAMG )
- ns.ViewModes = ptilbmFrame->camgChunk.ViewModes;
- else /* set the modes according to the dimensions of the picture */
- {
- if ( ns.Width > 384 ) /* max width in lo-res */
- ns.ViewModes |= HIRES;
-
- if ( ns.Height > 296 ) /* max height no laced */
- ns.ViewModes |= LACE;
-
- if ((ptilbmFrame->bmHdr.nPlanes == 6) &&
- (ptilbmFrame->nColorRegs > 16))
- ns.ViewModes |= EHB; /* if 6 planes & 32 colors mode = EHB */
-
- if ((ptilbmFrame->bmHdr.nPlanes == 6) &&
- (ptilbmFrame->nColorRegs == 16))
- ns.ViewModes |= HAM; /* if 6 planes & 16 colors mode = HAM */
- }
-
- if ((screen = (struct Screen *)OpenScreen(&ns)) == NULL) return(0);
-
- vp = &screen->ViewPort; /* viewport address for current screen */
-
- LoadRGB4(vp,&Black[0],(long)ptilbmFrame->nColorRegs);
- /* load the colormap for the current picture in the viewport */
-
- nw.Width = ns.Width ; /* window width = screen width */
- nw.Height = ns.Height; /* window height = screen height */
- nw.Screen = screen; /* window screen = actual screen */
-
- window = (struct Window *)OpenWindow(&nw);
-
- destBitMap = (struct BitMap *)screen->RastPort.BitMap;
-
- return(destBitMap); /* destBitMap allocated */
- }
-
- void
- DisplayPic(ptilbmFrame) /*------------ Display picture -------------*/
- ILBMFrame *ptilbmFrame;
- {
- vp = &screen->ViewPort; /* viewport address for current screen */
-
- /* the next two IF blocks are needed to center overscan pictures */
- /* picture width must not be larger than 384 lo-res pixel horiz */
- /* picture height must not be larger than 296 lo-res pixel vert */
- /* if the picture outruns the dimensions it will not be centered */
-
- if (((vp->Modes & HIRES) && (ns.Width < HX)) || (ns.Width < LX))
- vp->DxOffset = (vp->Modes & HIRES)
- ? ((NormalCols / 1) - ns.Width ) / 2 :
- ((NormalCols / 2) - ns.Width ) / 2 ;
-
- if (((vp->Modes & LACE) && (ns.Height < HY)) || (ns.Height < LY))
- vp->DyOffset = (vp->Modes & LACE )
- ? ((2 * NormalRows) - ns.Height) / 2 :
- ((1 * NormalRows) - ns.Height) / 2 ;
-
- LoadRGB4(vp,&ptilbmFrame->colorMap[0],
- (long)ptilbmFrame->nColorRegs);
- /* load the colormap for the current picture in the viewport */
-
- if (ptilbmFrame->foundBEAM) { /* BEAM chunk exists make coplist */
- vp->DspIns = NULL; /* do not include Display Instructions */
- vp->SprIns = NULL; /* do not include Sprite Instructions */
- vp->ClrIns = NULL; /* do not include Clear Instructions */
- vp->UCopIns = MakeBeamList(ptilbmFrame->bmHdr.h,
- ptilbmFrame->nColorRegs);
- }
-
- RemakeDisplay(); /* remake entire display including user coplist */
- ScreenToFront(screen);/* bring the screen to front when all done */
-
- Quit = FALSE; /* set quit flag FALSE */
- while (Quit == FALSE) { /* wait til quit TRUE */
- Wait( 1L << window->UserPort->mp_SigBit); /* do not busy wait */
- while (msg = (struct IntuiMessage *)GetMsg(window->UserPort)) {
- class = msg->Class; /* store message class */
- code = msg->Code; /* store message code */
-
- ReplyMsg(msg); /* reply to messages */
-
- switch(class) { /* check class */
- case VANILLAKEY: /* a key press ? */
- if ((code == '\003') || /* quit keys are */
- (code == '\033')) Quit = TRUE; /* ESC or CTRL-C */
- break;
- default: /* skip all the other */
- break; /* class of messages */
- } /* end of switch(class) block */
- } /* end of while (msg = ... block */
- } /* end of while (Quit==FALSE) block */
- ScreenToBack(screen); /* send the screen back before closing */
- /* avoids screen flash while releasing */
- /* copper lists & closing user screens */
- }
-
- /*** PrintS *****/
-
- PrintS(msg)
- char *msg;
- {
- if (!wbStartup) printf(msg);
- }
-
- /*** GoodBye *****/
-
- void
- GoodBye(msg)
- char *msg;
- {
- PrintS(msg);
- PrintS("\n\n");
- exit(0);
- }
-
- /*** OpenArg() *****/
-
- long
- OpenArg(wa)
- struct WBArg *wa;
- {
- struct FileLock *olddir;
- struct FileHandle *file;
-
- if (wa->wa_Lock)
- olddir = (struct FileLock *)CurrentDir(wa->wa_Lock);
-
- file = (struct FileHandle *)Open(wa->wa_Name, MODE_OLDFILE);
-
- if (wa->wa_Lock)
- CurrentDir(olddir);
-
- return((long)file);
- }
-
- /*** main0 *****/
-
- void
- main0(wa)
- struct WBArg *wa;
- {
- long file;
- IFFP iffp = NO_FILE;
-
- file = OpenArg(wa);
-
- if (file) {
- iffp = ReadPicture(file, &iFrame);
- Close(file);
- }
-
- if (iffp == IFF_DONE)
- DisplayPic(&iFrame);
-
- PrintS(IFFPMessages[-iffp]);
- PrintS("\n");
-
- if (window) CloseWindow(window);
- if (screen) CloseScreen(screen);
- }
-
- /*** main() *****/
-
- void
- main(argc, argv)
- int argc;
- char **argv;
- {
- struct WBArg wbArg, *wbArgs;
- long olddir;
-
- PrintS("\n*** Vedi - IFF File Viewer - Ver. 1.18 ***\n\n");
- PrintS("Copyright (c) 1989, QUEST Software - Verona - IT\n");
- PrintS("All rights reserved\n");
-
- if (!(IntuitionBase = (struct IntuitionBase *)
- OpenLibrary("intuition.library",LIBRARY_VERSION)))
- GoodBye("No Intuition Library!");
- if (!(GfxBase = (struct GfxBase *)
- OpenLibrary("graphics.library",LIBRARY_VERSION)))
- GoodBye("No Graphics Library!");
-
- NormalCols = GfxBase->NormalDisplayColumns;
- NormalRows = GfxBase->NormalDisplayRows;
-
- Prefs = (struct Preferences *)AllocMem
- ((long)sizeof(struct Preferences),0L);
- GetPrefs(Prefs,(long)sizeof(struct Preferences));
-
- if (GfxBase->DisplayFlags & PAL) ScreenNTSC = 0;
- else ScreenNTSC = 1;
-
- if (!argc) {
- wbStartup = WBenchMsg;
- wbArgs = wbStartup->sm_ArgList;
- argc = wbStartup->sm_NumArgs;
- while (argc > 1) {
- olddir = (long)CurrentDir(wbArgs[1].wa_Lock);
- main0(&wbArgs[1]);
- argc--;
- wbArgs = &wbArgs[1];
- }
-
- if (argc < 2) {
- PrintS ("\nUsage from Workbench:\n");
- PrintS ("Click left mouse button on Vedi, hold 'SHIFT' key\n");
- GoodBye("pressed while double-clicking on the picture icon");
- }
-
- }
- else {
- if ((argc < 2) || (*argv[1] == '?'))
- GoodBye("\nUsage from CLI: Vedi <filename>");
- wbArg.wa_Lock = NULL;
- while (argc > 1) {
- wbArg.wa_Name = argv[1];
- PrintS("\nReading file ");
- PrintS(wbArg.wa_Name);
- PrintS("...\n\n");
- PrintS("Press ESC to exit...\n\n");
- main0(&wbArg);
- PrintS("\n");
- argc--;
- argv = &argv[1];
- }
- }
-
- FreeMem(Prefs, (long)sizeof(struct Preferences));
-
- CloseLibrary(GfxBase);
- CloseLibrary(IntuitionBase);
-
- exit(0);
- }
-