home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 643b.lha / 2View_v1.50 / Source.LZH / Source / Misc.c < prev   
Encoding:
C/C++ Source or Header  |  1992-05-15  |  14.4 KB  |  561 lines

  1.  
  2. #include <exec/types.h>
  3. #include <dos/rdargs.h>
  4. #include <devices/printer.h>
  5. #include <devices/prtgfx.h>
  6. #include <intuition/screens.h>
  7. #include <intuition/intuition.h>
  8. #include <exec/memory.h>
  9. #include <dos/dos.h>
  10.  
  11. #include <graphics/gfxmacros.h>
  12. #include <graphics/copper.h>
  13. #include <hardware/custom.h>
  14.  
  15. #include "iff.h"
  16. #include "2View.h"
  17. #include "arexx.h"
  18.  
  19. /*Prototypes*/
  20. #include <clib/exec_protos.h>
  21. #include <clib/intuition_protos.h>
  22. #include <clib/graphics_protos.h>
  23. #include <clib/iffparse_protos.h>
  24. #include <clib/dos_protos.h>
  25. #include <clib/alib_protos.h>
  26.  
  27. /*Pragmas*/
  28. #include <pragmas/exec_pragmas.h>
  29. #include <pragmas/intuition_pragmas.h>
  30. #include <pragmas/graphics_pragmas.h>
  31. #include <pragmas/iffparse_pragmas.h>
  32. #include <pragmas/dos_pragmas.h>
  33.  
  34. BPTR StdErr=NULL;   /*'Standard error' for AmigaDOS IO functions*/
  35.  
  36. /*These are defined in 2View.c, but this file needs to reference them*/
  37.  
  38. extern struct NewScreen newScreen;
  39. extern struct NewWindow newWindow;
  40.  
  41. extern struct IFFHandle *iff;    /*IFF handle*/
  42. extern BPTR pL;         /*Playlist file pointer*/
  43. extern BOOL masking,print,toFront,printPics;
  44.  
  45. /*A true here indicates the current ILBM file is compressed*/
  46. extern BYTE Compression;
  47.  
  48. extern char trashBuf[512];     /* A place to dump mask information */
  49.  
  50. extern struct Screen *screen;
  51. extern struct Window *window;
  52.  
  53. /*The previous screen and window*/
  54. extern struct Window *prevWindow;
  55. extern struct Screen *prevScreen;
  56.  
  57. /*Libraries we'll need*/
  58. extern struct Library *IFFParseBase;
  59. extern struct Library *IntuitionBase;
  60. extern struct Library *GfxBase;
  61.  
  62. /*Provided by the compiler*/
  63. extern struct Library *SysBase;
  64. extern struct Library *DOSBase;
  65.  
  66. extern BOOL cycle;
  67. extern UBYTE numColors;
  68. UWORD colorTable[32];
  69. extern UWORD destMap[32];
  70.  
  71. extern struct Custom custom;
  72.  
  73. /*Convert the CMAP information into a color map, then set the colors*/
  74. /*of the screen according to that colormap*/
  75. void setScreenColors(struct Screen *scr, UBYTE *colorMap, UBYTE depth,
  76.              UWORD *destColorMap,UBYTE *colors)
  77. {
  78.    int i,numColors;
  79.  
  80.    numColors=1<<depth;    /*Get the number of colors (generally 2^depth)*/
  81.  
  82.    if(newScreen.ViewModes & HAM)    /*There are, of course, 2 exceptions*/
  83.       numColors=16;
  84.    if(newScreen.ViewModes & EXTRA_HALFBRITE)
  85.       numColors=32;
  86.  
  87.       /*For each color, convert it from CMAP to Amiga form and*/
  88.       /*store it (both in an unchanging table (colorTable) and in a "work" */
  89.       /*table (destColorMap), where the values are free to change during */
  90.       /*color cycling, etc.*/
  91.    for(i=0;i<numColors;i++)
  92.       colorTable[i]=destColorMap[i]=
  93.         (15 & (colorMap[i*3])>>4)<<8 | (15 & (colorMap[i*3+1])>>4)<<4 |
  94.            (15 & (colorMap[i*3+2]>>4));
  95.  
  96.       /*Store the color table*/
  97.    LoadRGB4(&(scr->ViewPort),destColorMap,numColors);
  98.  
  99.       /*Return the number of colors*/
  100.    *colors=numColors;
  101.  
  102.    return;
  103. }
  104.  
  105. /*Make a newScreen structure using the BMHD chunk*/
  106. void getBMHD(struct BitMapHeader *bmhd)
  107. {
  108.                        /*Define the screen as hires if*/
  109.    if(bmhd->PageWidth > 400 && bmhd->PageWidth <=704 && bmhd->nplanes < 5)
  110.       newScreen.ViewModes|=HIRES;      /*wider than 400 pixels and not */
  111.                        /*deeper than 4 bitplanes*/
  112.  
  113.    if(bmhd->PageHeight > 300 && bmhd->PageHeight <=512)  /*Define the screen as interlaced*/
  114.       newScreen.ViewModes|=LACE;       /*if the height is > 300 pixels*/
  115.  
  116.    newScreen.Width=bmhd->w;           /*Store the rest of the values*/
  117.    newScreen.Height=bmhd->h;
  118.  
  119.    newScreen.LeftEdge=bmhd->x;
  120.    newScreen.TopEdge=bmhd->y;
  121.    newScreen.Depth=bmhd->nplanes;
  122.  
  123.    masking=(bmhd->Masking == 1);
  124.  
  125.    Compression=bmhd->Compression;   /*Compression flag.  Store for*/
  126.                     /*later use*/
  127.    return;
  128. }
  129.  
  130. /*Data structures for ReadArgs()*/
  131. struct RDArgs ra=
  132. {
  133.    {NULL,0,0},
  134.    NULL,
  135.    trashBuf,
  136.    512,
  137.    "FILE/A/M,SECS=SECONDS/K/N,TICKS/K/N,LOOP/S,FROM/K,PRINT/S"
  138. };
  139.  
  140. /*Parse the argument list, using ReadArgs()*/
  141. void ParseArgs(ULONG *args)
  142. {
  143.    ReadArgs("FILE/A/M,SECS=SECONDS/K/N,TICKS/K/N,LOOP/S,FROM/K,PRINT/S",
  144.         args,&ra);
  145.    return;
  146. }
  147.  
  148. /*Check to see which mouse buttons have been pressed*/
  149. ButtonTypes checkButton(void)
  150. {
  151.    struct IntuiMessage *mesg;
  152.    ButtonTypes Button=none;
  153.    static justActivated=FALSE;
  154.  
  155.       /*This function disregards a select (left) mouse button click*/
  156.       /*if the window's just been activated.  This is so that a user*/
  157.       /*can click on another window, then make this one active again,*/
  158.       /*without advancing to the next picture*/
  159.  
  160.      /*While there are messages to be read...*/
  161.    while((mesg=(struct IntuiMessage *)GetMsg(prevWindow->UserPort))!=NULL)
  162.    {
  163.      /*Interpret them*/
  164.       switch(mesg->Class)
  165.       {
  166.      case ACTIVEWINDOW:   /*Set the appropriate flag if the window*/
  167.         justActivated=TRUE;  /*was just activated*/
  168.         break;
  169.      case VANILLAKEY:
  170.         switch(mesg->Code)
  171.         {
  172.            case 16:       /*CTRL-P - Print (if this picture hasn't been*/
  173.           if(print)   /*printed;  this is designed in case the user*/
  174.           {          /*holds down CTRL-P: we don't want 10-20     */
  175.                   /*print requests to get queued up        */
  176.              dumpRastPort(&(prevScreen->RastPort),
  177.                   &(prevScreen->ViewPort));
  178.              print=FALSE;
  179.           }
  180.           break;
  181.            case 4:          /*CTRL-D - Abort everything*/
  182.           Button=menu;
  183.           break;
  184.            case 3:
  185.           Button=select; /*CTRL-C - Advance to next picture*/
  186.           break;
  187.            case 9:          /*TAB:  Switch color cycling on/off*/
  188.           toggleCycling();
  189.           break;
  190.  
  191.         }
  192.         break;
  193.      case MOUSEBUTTONS:   /*Interpret a button click*/
  194.         if(mesg->Code==SELECTDOWN) /*If the left button was pushed,*/
  195.            if(justActivated)       /*and not so as to activate the*/
  196.            {               /*window, advance to the next*/
  197.           justActivated=FALSE;         /*screen*/
  198.           break;
  199.            }
  200.            else
  201.           Button=select;
  202.         else if(mesg->Code == MENUDOWN)  /*If the right button was*/
  203.            Button=menu;             /*pushed, we'll want to*/
  204.         break;                 /*abort*/
  205.       }
  206.       ReplyMsg((struct Message *)mesg);      /*Reply to the message*/
  207.    }
  208.    return(Button);                           /*Return the results*/
  209. }
  210.  
  211. /*Toggle color cycling on and off*/
  212. void toggleCycling(void)
  213. {
  214.    int c;
  215.  
  216.    cycle=(cycle) ? FALSE : TRUE;    /*Toggle the color cycling lag*/
  217.    LoadRGB4(&(prevScreen->ViewPort),colorTable,numColors);
  218.    for(c=0;c<numColors;c++)
  219.       destMap[c]=colorTable[c];
  220. }
  221.  
  222.  
  223. struct EasyStruct erError2Line =
  224. {
  225.    sizeof(struct EasyStruct),
  226.    0,
  227.    "Program error:  2View",
  228.    "%s\n%s\n%s",
  229.    "Ok"
  230. };
  231.  
  232. struct EasyStruct erError1Line =
  233. {
  234.    sizeof(struct EasyStruct),
  235.    0,
  236.    "Program error:  2View",
  237.    "%s\n%s",
  238.    "Ok"
  239. };
  240.  
  241. /*This prints an error to the console, if we were run from the CLI*/
  242. /*This is done instead of using Output() so as to get around any redirection*/
  243. /*that may be in place (just like the standard C stderr)*/
  244. /*If we can't open a StdErr or 2View was run from Workbench, a requester */
  245. /*is put up*/
  246. void printError(char *error1,char *error2)
  247. {
  248.    if(StdErr==NULL)
  249.       StdErr=Open("CONSOLE:",MODE_OLDFILE);
  250.  
  251.    /* If we can't open StdErr, or Output()==NULL (meaning we're running */
  252.    /* Workbench), put up a requester */
  253.    if(StdErr==NULL || Output()==NULL)
  254.    {
  255.       if(error2==NULL || error2[0]==NULL)
  256.      EasyRequest(NULL,&erError1Line,NULL,error1,"Exiting...");
  257.       else
  258.      EasyRequest(NULL,&erError2Line,NULL,error1,error2,"Exiting...");
  259.    }
  260.    else
  261.    {
  262.       FPuts(StdErr,error1);
  263.       FPuts(StdErr,error2);
  264.       FPuts(StdErr,"\nExiting\n");
  265.    }
  266.    return;
  267. }
  268.  
  269. /*Free allocated resources in anticipation of quitting*/
  270. void cleanup()
  271. {
  272.       /*Close the ARexx port*/
  273.    dnRexxPort();
  274.  
  275.       /*Close the standard-error file if opened*/
  276.    if(StdErr!=NULL)
  277.       Close(StdErr);
  278.  
  279.       /*Close a previous screen and window, if open*/
  280.    if(prevWindow!=NULL)
  281.       CloseWindow(prevWindow);
  282.    if(prevScreen!=NULL)
  283.       CloseScreen(prevScreen);
  284.  
  285.       /*Close a current screen and window, if open*/
  286.    if(window!=NULL)
  287.       CloseWindow(window);
  288.    if(screen!=NULL)
  289.       CloseScreen(screen);
  290.  
  291.    if(iff!=NULL)
  292.       FreeIFF(iff);
  293.  
  294.    if(pL!=NULL)
  295.       Close(pL);
  296.  
  297.    if(IFFParseBase!=NULL)
  298.       CloseLibrary(IFFParseBase);
  299.  
  300.    if(IntuitionBase!=NULL)
  301.       CloseLibrary(IntuitionBase);
  302.  
  303.    if(GfxBase!=NULL)
  304.       CloseLibrary(GfxBase);
  305. }
  306.  
  307. /*Print the specified RastPort (whose ViewPort is pointed to by vp*/
  308. BOOL dumpRastPort(struct RastPort *rp,struct ViewPort *vp)
  309. {
  310.    struct IODRPReq *printerMsg;
  311.    struct MsgPort *printerPort;
  312.    static BOOL ableToPrint=TRUE;
  313.  
  314.    if(ableToPrint)
  315.    {
  316.       ableToPrint=FALSE;
  317.       printerPort=CreatePort("2View.print.port",0);
  318.       if(printerPort!=NULL)
  319.       {
  320.      printerMsg=(struct IORequest *)CreateExtIO(printerPort,
  321.                        (long)sizeof(struct IODRPReq));
  322.  
  323.      if(printerMsg != NULL)
  324.      {
  325.         /*Open the printer device*/
  326.         if(OpenDevice("printer.device",0,printerMsg,0)==0)
  327.         {
  328.            /*Set up the IODRPReq structure*/
  329.            printerMsg->io_Command=PRD_DUMPRPORT;
  330.            printerMsg->io_RastPort=rp;
  331.            printerMsg->io_ColorMap=vp->ColorMap;
  332.            printerMsg->io_Modes=vp->Modes;
  333.            printerMsg->io_SrcX=0;
  334.            printerMsg->io_SrcY=0;
  335.            printerMsg->io_SrcWidth=vp->DWidth;
  336.            printerMsg->io_SrcHeight=vp->DHeight;
  337.            printerMsg->io_Special=SPECIAL_ASPECT|SPECIAL_FULLROWS|
  338.                       SPECIAL_FULLCOLS;
  339.  
  340.            /*Do it*/
  341.            if(DoIO(printerMsg)==0)
  342.           ableToPrint=TRUE;
  343.  
  344.            CloseDevice(printerMsg);
  345.         }
  346.         DeleteExtIO(printerMsg);
  347.      }
  348.      DeletePort(printerPort);
  349.       }
  350.       return(ableToPrint);
  351.    }
  352. }
  353.  
  354. /*Determine which colors to cycle, for a CRNG*/
  355. UBYTE interpretCRNG(UBYTE *cycleTable,CRNG *crng,UBYTE *rate)
  356. {
  357.    UBYTE length=0;
  358.    UBYTE pos,color;
  359.  
  360.       /*If the rate is zero, colors won't cycle anyway, so return 0*/
  361.    if(crng->rate==0)
  362.       return(0);
  363.  
  364.       /*Get the cycle rate*/
  365.    *rate=16384/crng->rate;
  366.  
  367.       /*If the colors are actually suppossed to be cycling...*/
  368.    if(crng->active!=0)
  369.    {
  370.      /*Get the number of colors to cycle*/
  371.       length=crng->high-crng->low+1;
  372.  
  373.      /*If there are colors to cycle*/
  374.       if(length!=0)
  375.      if(crng->active==1)
  376.            /*Forward cycling*/
  377.         for(pos=0,color=crng->low;pos<length;pos++,color++)
  378.            cycleTable[pos]=color;
  379.      else
  380.            /*Backward cycling*/
  381.         for(pos=0,color=crng->high;pos<length;pos++,color--)
  382.            cycleTable[pos]=color;
  383.    }
  384.    return(length);
  385. }
  386.  
  387. UBYTE interpretDRNG(UBYTE *cycleTable,DRNG *drng,UBYTE *rate)
  388. {
  389.    UBYTE pos;
  390.    DIndex *index;
  391.  
  392.       /*Skip past true-color values*/
  393.    index=(DIndex *)((ULONG)drng+sizeof(DRNG)+4*drng->ntrue);
  394.  
  395.       /*Colors won't cycle if rate is zero, so return 0*/
  396.    if(drng->rate==0)
  397.       return(0);
  398.  
  399.    *rate=16384/drng->rate;
  400.  
  401.       /*If flags==0, there is no color cycling, so return*/
  402.    if(drng->flags==0)
  403.       return(0);
  404.  
  405.       /*Get the color registers to cycle*/
  406.    for(pos=0;pos<drng->nregs;pos++)
  407.    {
  408.       cycleTable[pos]=index->index;
  409.       index=(DIndex *)((ULONG)index+sizeof(DIndex));
  410.    }
  411.  
  412.       /*Return the number of colors that are cycling*/
  413.    return(drng->nregs);
  414. }
  415.  
  416. /*Cycle a screen's colors according to the manner specified in cycleTable*/
  417. void cycleColors(UBYTE *cycleTable,UWORD *colorTable,UBYTE length,
  418.          UBYTE numColors)
  419. {
  420.    UWORD tempColor;
  421.    BYTE color;
  422.  
  423.       /*Get the first color in the cycle list*/
  424.    tempColor=colorTable[cycleTable[length-1]];
  425.  
  426.       /*Shift each color in the list to its next place in the color table*/
  427.    for(color=length-2;color>=0;color--)
  428.       colorTable[cycleTable[color+1]]=colorTable[cycleTable[color]];
  429.  
  430.       /*The first color in the list became the last color */
  431.    colorTable[cycleTable[0]]=tempColor;
  432.  
  433.  
  434.    LoadRGB4(&(prevScreen->ViewPort),colorTable,numColors);
  435. }
  436.  
  437. /*Setup the copper list for dynamic hires images (as output by Macro Paint;*/
  438. /*Digi-View dynamic hires images aren't supported yet).*/
  439. void setupDynHires(struct Screen *scr,UWORD *colorBuf)
  440. {
  441.    UBYTE color;
  442.  
  443.       /*Get the first visible line on the screen*/
  444.    UWORD line=(scr->TopEdge < 0) ? -(scr->TopEdge) : 0;
  445.  
  446.    struct UCopList *cl,*oldCl;
  447.  
  448.    LoadRGB4(&(scr->ViewPort),colorBuf,16);
  449.  
  450.    if(line > 10)
  451.       line-=10;
  452.    else
  453.       line=0;
  454.  
  455.       /*Allocate the copper list header*/
  456.    cl=(struct UCopList *)AllocMem(sizeof(struct UCopList),
  457.                   MEMF_PUBLIC|MEMF_CHIP|MEMF_CLEAR);
  458.  
  459.       /*Return if there was no memory*/
  460.    if(cl==NULL)
  461.       return;
  462.  
  463.       /*Initialize the number of  copper list entries */
  464.    CINIT(cl,17*2*scr->Height);
  465.  
  466.       /*If the image is interlaced, only get the colors for every other*/
  467.       /*scan line (if we were to try to setup every scan line, the image*/
  468.       /*wouldn't come out)*/
  469.    if(scr->ViewPort.Modes & LACE)
  470.       for(;line<scr->Height/2;line++)
  471.       {
  472.      CWAIT(cl,(line-1)<<1,112);
  473.  
  474.         /*Macro Paint only changes colors 4-16*/
  475.      for(color=4;color<16;color++)
  476.         CMOVE(cl,custom.color[color],colorBuf[(line<<5)+color]);
  477.       }
  478.    else
  479.       for(;line<scr->Height;line++)
  480.       {
  481.      CWAIT(cl,(line-1),112)
  482.  
  483.      for(color=4;color<16;color++)
  484.         CMOVE(cl,custom.color[color],colorBuf[(line<<4)+color]);
  485.       }
  486.  
  487.       /*Terminate the copper list*/
  488.    CEND(cl);
  489.  
  490.       /*Install the new copper list, storing the previous one (if any)*/
  491.    oldCl=scr->ViewPort.UCopIns;
  492.    scr->ViewPort.UCopIns=cl;
  493.    RethinkDisplay();
  494.  
  495.       /*If there was a previous copper list, free its memory*/
  496.    if(oldCl!=NULL)
  497.    {
  498.       if(oldCl->FirstCopList != NULL)
  499.      FreeCopList(oldCl->FirstCopList);
  500.       FreeMem(oldCl,sizeof(struct UCopList));
  501.    }
  502.  
  503.    return;
  504. }
  505.  
  506. /*Setup the copper list for a SHAM image*/
  507. void setupSHAM(struct Screen *scr,UWORD *sham)
  508. {
  509.    int posInBuf=17;
  510.    UBYTE color;
  511.  
  512.       /*Get the first visible line on the screen*/
  513.    UWORD line=(scr->TopEdge < 0) ? -(scr->TopEdge) : 0;
  514.    struct UCopList *cl,*oldCl;
  515.  
  516.       /*Start at a line before the first visible line
  517.    if(line > 10)
  518.       line-=10;
  519.    else
  520.       line=0;
  521.  
  522.       /*Allocate the memory for the copper list header*/
  523.    cl=(struct UCopList *)AllocMem(sizeof(struct UCopList),
  524.                   MEMF_PUBLIC|MEMF_CHIP|MEMF_CLEAR);
  525.  
  526.    if(cl==NULL)
  527.       return;
  528.  
  529.       /*Skip past the colors for the first line (which are the same */
  530.       /*as the contents of the CMAP chunk*/
  531.    posInBuf+=(16*line);
  532.  
  533.       /*Create the copper list*/
  534.    for(;line<scr->Height;line++)
  535.    {
  536.       CWAIT(cl,line,200)
  537.       for(color=0;color<16;color++)
  538.      CMOVE(cl,custom.color[color],sham[posInBuf++]);
  539.    }
  540.  
  541.       /*Terminate it*/
  542.    CEND(cl);
  543.  
  544.       /*Install it*/
  545.    oldCl=scr->ViewPort.UCopIns;
  546.    scr->ViewPort.UCopIns=cl;
  547.    RethinkDisplay();
  548.  
  549.       /*Free the memory of the old copper list, if one existed*/
  550.    if(oldCl!=NULL)
  551.    {
  552.       if(oldCl->FirstCopList != NULL)
  553.      FreeCopList(oldCl->FirstCopList);
  554.       FreeMem(oldCl,sizeof(struct UCopList));
  555.    }
  556.  
  557.    return;
  558. }
  559.  
  560. /*End of Misc.c*/
  561.