home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 403.lha / VediSrc / Vedi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-06  |  16.6 KB  |  472 lines

  1. /********************************************** Date: 20-Feb-89 *****/
  2. /*                                                                  */
  3. /* Vedi.c - written by Diego Perini, based on Rett Andersen's ideas */
  4. /*                                                                  */
  5. /* Copyright (C) 1989, QUEST Software - Verona - IT                 */
  6. /* All rights reserved                                              */
  7. /*                                                                  */
  8. /* Last modified: 22 March 1990        Registered Developer: ECI004 */
  9. /*                                                                  */
  10. /* Show any kind of IFF pictures including the new IFF_BEAM Picture */
  11. /*                                                                  */
  12. /********************************************************************/
  13. /*                                                                  */
  14. /* IFF Format and routines in pd courtesy of Electronic Arts and C= */
  15. /*                                                                  */
  16. /********************************************************************/
  17. /*                                                                  */
  18. /* Released in the public domain to spread the use of BeamPalettes. */
  19. /*                                                                  */
  20. /* Feel free to modify it and include it in your valuable projects. */
  21. /*                                                                  */
  22. /********************************************************************/
  23.  
  24. #include <exec/types.h>
  25. #include <exec/tasks.h>
  26. #include <exec/memory.h>
  27. #include <exec/interrupts.h>
  28. #include <libraries/dos.h>
  29. #include <libraries/dosextens.h>
  30. #include <graphics/view.h>
  31. #include <graphics/gfxbase.h>
  32. #include <graphics/gfxmacros.h>
  33. #include <hardware/custom.h>
  34. #include <hardware/intbits.h>
  35. #include <hardware/dmabits.h>
  36. #include <intuition/intuitionbase.h>
  37. #include <workbench/workbench.h>
  38. #include <workbench/startup.h>
  39.  
  40. #include <iff/ilbm.h>
  41. #include <iff/readpict.h>
  42.  
  43. #include <functions.h>
  44.  
  45. #define LOCAL   static
  46.  
  47. #define VERSION   1
  48. #define REVISION  18
  49.  
  50. #define MIN(a,b)   ((a)<(b)?(a):(b))
  51. #define MAX(a,b)   ((a)>(b)?(a):(b))
  52.  
  53. /* MAX_SCAN_LINES value should be changed to allow for NTSC support */
  54. #define MAX_COLS_WIDTH   768             /* max # of cols horizzont */
  55. #define MAX_SCAN_LINES   592             /* max # of lines vertical */
  56. #define MAX_COLOR_REGS    32             /* max # of color register */
  57.  
  58. #define EHB   EXTRA_HALFBRITE            /* EHB short like HAM.(dp) */
  59.  
  60. #define HX   MAX_COLS_WIDTH + 1          /* used in DisplayPic() to */
  61. #define LX   MAX_COLS_WIDTH / 2 + 1      /* check picture x limit's */
  62.  
  63. #define HY   MAX_SCAN_LINES + 1          /* used in DisplayPic() to */
  64. #define LY   MAX_SCAN_LINES / 2 + 1      /* check picture y limit's */
  65.  
  66. struct Preferences *Prefs;                 /* ptr to Preferences    */
  67.  
  68. struct GfxBase *GfxBase;                   /* ptr to GfxBase        */
  69. struct IntuitionBase *IntuitionBase;       /* ptr to IntuitionBase  */
  70.  
  71. LOCAL struct ViewPort  *vp = {0};          /* the viewport we get   */
  72. LOCAL struct BitMap     bm = {0};          /* the bitmap allocated  */
  73.  
  74. LOCAL struct Screen *screen;               /* my wonderfull screen  */
  75. LOCAL struct Window *window;               /* my backdrop window    */
  76.  
  77. struct UCopList *ucoplist;                 /* for copper lists      */
  78.  
  79. struct Interrupt CopInt;                   /* for copper interrupts */
  80.  
  81. LOCAL ILBMFrame iFrame;                    /* current ILBM Frame    */
  82.  
  83. LOCAL struct WBStartup *wbStartup = NULL;  /* workbench arguments   */
  84. extern struct WBStartup *WBenchMsg;        /* workbench message     */
  85.  
  86. LOCAL struct IntuiMessage *msg;            /* message structure     */
  87.  
  88. unsigned long
  89.       class = NULL,                        /* message class         */
  90.       code  = NULL,                        /* message code          */
  91.       count = NULL;                        /* current scan line     */
  92.  
  93. BOOL Quit;                                 /* used in wait user end */
  94.  
  95. short NormalCols, NormalRows;           /* don't ask me about    */
  96.  
  97. int ScreenNTSC = 0;                        /* this set your system  */
  98.  
  99. extern UWORD BeamPalette[MAX_SCAN_LINES][MAX_COLOR_REGS];
  100.                       /* hold the palette for 592 lines */
  101.                       /* for Interlaced Overscan in PAL */
  102.  
  103. USHORT Black[32] = {0x0000,0x0000,0x0000,0x0000,
  104.                     0x0000,0x0000,0x0000,0x0000,
  105.                     0x0000,0x0000,0x0000,0x0000,
  106.                     0x0000,0x0000,0x0000,0x0000,
  107.                     0x0000,0x0000,0x0000,0x0000,
  108.                     0x0000,0x0000,0x0000,0x0000,
  109.                     0x0000,0x0000,0x0000,0x0000,
  110.                     0x0000,0x0000,0x0000,0x0000};
  111.                       /* used to clear the main screen  */
  112.  
  113. struct   NewScreen      ns = {
  114.    0, 0,                                  /* LeftEdge and TopEdge   */
  115.    8, 8,                                  /* Width and Height       */
  116.    1,                                     /* Depth                  */
  117.    0, 1,                                  /* DetailPen and BlockPen */
  118.    NULL,                                  /* Special display modes  */
  119.    CUSTOMSCREEN,                          /* Screen Type            */
  120.    NULL,                                  /* Use my font            */
  121.    NULL,                                  /* Title of the screen    */
  122.    NULL,                                  /* No gadgets yet         */
  123.    NULL                                   /* Ptr to CustomBitmap    */
  124.    };
  125.  
  126. struct   NewWindow      nw ={
  127.    0, 0,                                  /* LeftEdge and TopEdge   */
  128.    8, 8,                                  /* Width and Height       */
  129.    -1, -1,                                /* DetailPen and BlockPen */
  130.    VANILLAKEY,                            /* Intuition IDCMP Flags  */
  131.    ACTIVATE
  132.    |SMART_REFRESH
  133.    |RMBTRAP
  134.    |BACKDROP
  135.    |BORDERLESS,                           /* New Window Flags       */
  136.    NULL, NULL,                            /* Gadget, Image pointers */
  137.    NULL,                                  /* Title of the window    */
  138.    NULL,                                  /* Put Screen ptr here    */
  139.    NULL,                                  /* SuperBitMap pointer    */
  140.    10, 10,                                /* MinWidth and MinHeight */
  141.    768, MAX_SCAN_LINES,                   /* MaxWidth and MaxHeight */
  142.    CUSTOMSCREEN                           /* Type of window         */
  143.    };
  144.  
  145. LOCAL char MsgOkay[]        = { "(IFF_OKAY) Didn't find a FORM ILBM in the file." };
  146. LOCAL char MsgEndMark[]     = { "(END_MARK) How did you get this message?" };
  147. LOCAL char MsgDone[]        = { "(IFF_DONE) All done."};
  148. LOCAL char MsgDos[]         = { "(DOS_ERROR) The DOS returned an error." };
  149. LOCAL char MsgNot[]         = { "(NOT_IFF) Not an IFF file." };
  150. LOCAL char MsgNoFile[]      = { "(NO_FILE) No such file found." };
  151. LOCAL char MsgClientError[] = { "(CLIENT_ERROR) Vedi bug or insufficient RAM."};
  152. LOCAL char MsgForm[]        = { "(BAD_FORM) A malformed FORM ILBM." };
  153. LOCAL char MsgShort[]       = { "(SHORT_CHUNK) A malformed FORM ILBM." };
  154. LOCAL char MsgBad[]         = { "(BAD_IFF) A mangled IFF file." };
  155.  
  156. LOCAL char *IFFPMessages[-(long)LAST_ERROR+1] = {
  157.    MsgOkay,         /* IFF_OKAY     */
  158.    MsgEndMark,      /* END_MARK     */
  159.    MsgDone,         /* IFF_DONE     */
  160.    MsgDos,          /* DOS_ERROR    */
  161.    MsgNot,          /* NOT_IFF      */
  162.    MsgNoFile,       /* NO_FILE      */
  163.    MsgClientError,  /* CLIENT_ERROR */
  164.    MsgForm,         /* BAD_FORM     */
  165.    MsgShort,        /* SHORT_CHUNK  */
  166.    MsgBad           /* BAD_IFF      */
  167.    };
  168.  
  169. struct UCopList *
  170. MakeBeamList(nRows,nCols) /*----- Generates Screen Copper List -----*/
  171. int nRows;
  172. int nCols;
  173.    {
  174.    struct UCopList *ucoplist;
  175.    struct CopIns *copins;
  176.    int i, j, step;
  177.  
  178.    if (vp->Modes & LACE)
  179.       step = 2;
  180.    else
  181.       step = 1;
  182.  
  183.    SetRGB4(vp, 0L, 0L, 0L, 0L);
  184.    for( j = 1 ; j < nCols ; j++ ) {
  185.       SetRGB4(vp, (long)j,
  186.                   (long)((BeamPalette[0][j] >> 8 ) & 0xf),
  187.                   (long)((BeamPalette[0][j] >> 4 ) & 0xf),
  188.                   (long)((BeamPalette[0][j] >> 0 ) & 0xf));
  189.       }
  190.  
  191.    ucoplist = (struct UCopList *)AllocMem(12L,MEMF_PUBLIC|MEMF_CLEAR);
  192.  
  193.    CINIT(ucoplist, (long)(nRows + nRows * nCols + 2));
  194.  
  195.    for( i = step ; i < nRows ; i += step ) {
  196.       copins = ucoplist->FirstCopList->CopPtr;
  197.       CWAIT(ucoplist, (long)(i), 0L);
  198.       copins->OpCode |= CPR_NT_LOF;
  199.  
  200.       for( j = 1 ; j < nCols ; j++ ) {
  201.          copins = ucoplist->FirstCopList->CopPtr;
  202.          CMOVE(ucoplist, custom.color[j], (long)BeamPalette[i][j]);
  203.          copins->OpCode |= CPR_NT_LOF;
  204.          }
  205.  
  206.       if (vp->Modes & LACE) {
  207.          copins = ucoplist->FirstCopList->CopPtr;
  208.          CWAIT(ucoplist, (long)(i), 0L);
  209.          copins->OpCode |= CPR_NT_SHT;
  210.  
  211.          for( j = 1 ; j < nCols ; j++ ) {
  212.             copins = ucoplist->FirstCopList->CopPtr;
  213.             CMOVE(ucoplist, custom.color[j], (long)BeamPalette[i+1][j]);
  214.             copins->OpCode |= CPR_NT_SHT;
  215.             }
  216.          }
  217.       }
  218.  
  219.    CEND(ucoplist);
  220.  
  221.    return(ucoplist);
  222.    }
  223.  
  224. struct BitMap *
  225. getBitMap(ptilbmFrame) /*----- Open screen & return bitmap ptr -----*/
  226. ILBMFrame *ptilbmFrame;
  227. {
  228.    struct BitMap *destBitMap;                      /* a BitMap ptr  */
  229.  
  230.    ns.Width     = ptilbmFrame->bmHdr.w;            /* screen width  */
  231.    ns.Height    = ptilbmFrame->bmHdr.h;            /* screen height */
  232.    ns.Depth     = ptilbmFrame->bmHdr.nPlanes;      /* screen depth  */
  233.    ns.Type     |= SCREENBEHIND;   /* screen opens in the back of Wb */
  234.    ns.ViewModes = NULL;                            /* no modes yet  */
  235.  
  236.    /* if a CAMG chunk exists set the modes according to it's values */
  237.    if ( ptilbmFrame->foundCAMG )
  238.       ns.ViewModes = ptilbmFrame->camgChunk.ViewModes;
  239.    else /* set the modes according to the dimensions of the picture */
  240.       {
  241.       if ( ns.Width  > 384 )                 /* max width in lo-res */
  242.          ns.ViewModes |= HIRES;
  243.  
  244.       if ( ns.Height > 296 )                 /* max height no laced */
  245.          ns.ViewModes |= LACE;
  246.  
  247.       if ((ptilbmFrame->bmHdr.nPlanes == 6) &&
  248.           (ptilbmFrame->nColorRegs  > 16))
  249.          ns.ViewModes |= EHB; /* if 6 planes & 32 colors mode = EHB */
  250.  
  251.       if ((ptilbmFrame->bmHdr.nPlanes == 6) &&
  252.           (ptilbmFrame->nColorRegs == 16))
  253.          ns.ViewModes |= HAM; /* if 6 planes & 16 colors mode = HAM */
  254.       }
  255.  
  256.    if ((screen = (struct Screen *)OpenScreen(&ns)) == NULL) return(0);
  257.  
  258.    vp = &screen->ViewPort;   /* viewport address for current screen */
  259.  
  260.    LoadRGB4(vp,&Black[0],(long)ptilbmFrame->nColorRegs);
  261.        /* load the colormap for the current picture in the viewport */
  262.  
  263.    nw.Width  = ns.Width ; /* window width  = screen width  */
  264.    nw.Height = ns.Height; /* window height = screen height */
  265.    nw.Screen = screen;    /* window screen = actual screen */
  266.  
  267.    window = (struct Window *)OpenWindow(&nw);
  268.  
  269.    destBitMap = (struct BitMap *)screen->RastPort.BitMap;
  270.  
  271.    return(destBitMap);          /* destBitMap allocated */
  272.    }
  273.  
  274. void
  275. DisplayPic(ptilbmFrame) /*------------ Display picture -------------*/
  276. ILBMFrame *ptilbmFrame;
  277. {
  278.    vp = &screen->ViewPort;   /* viewport address for current screen */
  279.  
  280.    /* the next two IF blocks are needed to center overscan pictures */
  281.    /* picture width  must not be larger than 384 lo-res pixel horiz */
  282.    /* picture height must not be larger than 296 lo-res pixel vert  */
  283.    /* if the picture outruns the dimensions it will not be centered */
  284.  
  285.    if (((vp->Modes & HIRES) && (ns.Width < HX)) || (ns.Width  < LX))
  286.       vp->DxOffset = (vp->Modes & HIRES)
  287.                    ? ((NormalCols / 1) - ns.Width ) / 2 :
  288.                      ((NormalCols / 2) - ns.Width ) / 2 ;
  289.  
  290.    if (((vp->Modes & LACE) && (ns.Height < HY)) || (ns.Height < LY))
  291.       vp->DyOffset = (vp->Modes & LACE )
  292.                    ? ((2 * NormalRows) - ns.Height) / 2 :
  293.                      ((1 * NormalRows) - ns.Height) / 2 ;
  294.  
  295.    LoadRGB4(vp,&ptilbmFrame->colorMap[0],
  296.            (long)ptilbmFrame->nColorRegs);
  297.        /* load the colormap for the current picture in the viewport */
  298.  
  299.    if (ptilbmFrame->foundBEAM) { /* BEAM chunk exists make coplist  */
  300.       vp->DspIns = NULL;    /* do not include Display Instructions  */
  301.       vp->SprIns = NULL;    /* do not include Sprite Instructions   */
  302.       vp->ClrIns = NULL;    /* do not include Clear Instructions    */
  303.       vp->UCopIns = MakeBeamList(ptilbmFrame->bmHdr.h,
  304.                                  ptilbmFrame->nColorRegs);
  305.       }
  306.  
  307.    RemakeDisplay(); /* remake entire display including user coplist */
  308.    ScreenToFront(screen);/* bring the screen to front when all done */
  309.  
  310.    Quit = FALSE;                             /* set quit flag FALSE */
  311.    while (Quit == FALSE) {                   /* wait til quit TRUE  */
  312.       Wait( 1L << window->UserPort->mp_SigBit); /* do not busy wait */
  313.       while (msg = (struct IntuiMessage *)GetMsg(window->UserPort)) {
  314.          class  = msg->Class;                /* store message class */
  315.          code   = msg->Code;                 /* store message code  */
  316.  
  317.          ReplyMsg(msg);                      /* reply to messages   */
  318.  
  319.          switch(class) {                           /* check class   */
  320.             case VANILLAKEY:                       /* a key press ? */
  321.                if ((code == '\003') ||             /* quit keys are */
  322.                    (code == '\033')) Quit = TRUE;  /* ESC or CTRL-C */
  323.                break;
  324.             default:                          /* skip all the other */
  325.                break;                         /* class of messages  */
  326.             }      /* end of switch(class) block */
  327.          }      /* end of while (msg = ... block */
  328.       }      /* end of while (Quit==FALSE) block */
  329.    ScreenToBack(screen);     /* send the screen back before closing */
  330.                              /* avoids screen flash while releasing */
  331.                              /* copper lists & closing user screens */
  332. }
  333.  
  334. /*** PrintS *****/
  335.  
  336. PrintS(msg)
  337. char *msg;
  338. {
  339.    if (!wbStartup)  printf(msg);
  340. }
  341.  
  342. /*** GoodBye *****/
  343.  
  344. void
  345. GoodBye(msg)
  346. char *msg;
  347. {
  348.    PrintS(msg);
  349.    PrintS("\n\n");
  350.    exit(0);
  351. }
  352.  
  353. /*** OpenArg() *****/
  354.  
  355. long
  356. OpenArg(wa)
  357. struct WBArg *wa;
  358. {
  359.    struct FileLock *olddir;
  360.    struct FileHandle *file;
  361.  
  362.    if (wa->wa_Lock)
  363.       olddir = (struct FileLock *)CurrentDir(wa->wa_Lock);
  364.  
  365.    file = (struct FileHandle *)Open(wa->wa_Name, MODE_OLDFILE);
  366.  
  367.    if (wa->wa_Lock)
  368.       CurrentDir(olddir);
  369.  
  370.    return((long)file);
  371. }
  372.  
  373. /*** main0 *****/
  374.  
  375. void
  376. main0(wa)
  377. struct WBArg *wa;
  378. {
  379.    long file;
  380.    IFFP iffp = NO_FILE;
  381.  
  382.    file = OpenArg(wa);
  383.  
  384.    if (file) {
  385.       iffp = ReadPicture(file, &iFrame);
  386.       Close(file);
  387.       }
  388.  
  389.    if (iffp == IFF_DONE)
  390.       DisplayPic(&iFrame);
  391.  
  392.    PrintS(IFFPMessages[-iffp]);
  393.    PrintS("\n");
  394.  
  395.    if (window) CloseWindow(window);
  396.    if (screen) CloseScreen(screen);
  397. }
  398.  
  399. /*** main() *****/
  400.  
  401. void
  402. main(argc, argv)
  403. int argc;
  404. char **argv;
  405. {
  406.    struct WBArg wbArg, *wbArgs;
  407.    long olddir;
  408.  
  409.    PrintS("\n*** Vedi - IFF File Viewer - Ver. 1.18 ***\n\n");
  410.    PrintS("Copyright (c) 1989, QUEST Software - Verona - IT\n");
  411.    PrintS("All rights reserved\n");
  412.  
  413.    if (!(IntuitionBase = (struct IntuitionBase *)
  414.       OpenLibrary("intuition.library",LIBRARY_VERSION)))
  415.       GoodBye("No Intuition Library!");
  416.    if (!(GfxBase = (struct GfxBase *)
  417.       OpenLibrary("graphics.library",LIBRARY_VERSION)))
  418.       GoodBye("No Graphics Library!");
  419.  
  420.    NormalCols = GfxBase->NormalDisplayColumns;
  421.    NormalRows = GfxBase->NormalDisplayRows;
  422.  
  423.    Prefs = (struct Preferences *)AllocMem
  424.                 ((long)sizeof(struct Preferences),0L);
  425.    GetPrefs(Prefs,(long)sizeof(struct Preferences));
  426.  
  427.    if (GfxBase->DisplayFlags & PAL) ScreenNTSC = 0;
  428.    else ScreenNTSC = 1;
  429.  
  430.    if (!argc) {
  431.       wbStartup = WBenchMsg;
  432.       wbArgs = wbStartup->sm_ArgList;
  433.       argc = wbStartup->sm_NumArgs;
  434.       while (argc > 1) {
  435.          olddir = (long)CurrentDir(wbArgs[1].wa_Lock);
  436.          main0(&wbArgs[1]);
  437.          argc--;
  438.          wbArgs = &wbArgs[1];
  439.          }
  440.  
  441.       if (argc < 2) {
  442.          PrintS ("\nUsage from Workbench:\n");
  443.          PrintS ("Click left mouse button on Vedi, hold 'SHIFT' key\n");
  444.          GoodBye("pressed while double-clicking on the picture icon");
  445.          }
  446.  
  447.       }
  448.    else {
  449.       if ((argc < 2) || (*argv[1] == '?'))
  450.          GoodBye("\nUsage from CLI: Vedi <filename>");
  451.       wbArg.wa_Lock = NULL;
  452.       while (argc > 1) {
  453.          wbArg.wa_Name = argv[1];
  454.          PrintS("\nReading file ");
  455.          PrintS(wbArg.wa_Name);
  456.          PrintS("...\n\n");
  457.          PrintS("Press ESC to exit...\n\n");
  458.          main0(&wbArg);
  459.          PrintS("\n");
  460.          argc--;
  461.          argv = &argv[1];
  462.          }
  463.       }
  464.  
  465.    FreeMem(Prefs, (long)sizeof(struct Preferences));
  466.  
  467.    CloseLibrary(GfxBase);
  468.    CloseLibrary(IntuitionBase);
  469.  
  470.    exit(0);
  471. }
  472.