home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Extras / IFF / Old_IFF_Packages / April_1987 / EXAMPLES / Display / Display.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-04-03  |  19.1 KB  |  715 lines

  1. /*
  2.  * Display.c
  3.  *   Read an ILBM file and display as a screen/window until closed.
  4.  *   Simulated close gadget in upper left corner of window.
  5.  *   Clicking below title bar area toggles screen bar for dragging.
  6.  *   Handles normal and HAM ILBM's
  7.  *   Does automatic color cycling (see note below)
  8.  *   Accepts optional 2nd CLI arg for display time in seconds
  9.  *
  10.  *  By Carolyn Scheppner   CBM  03/15/86
  11.  *
  12.  *  Modified 09/02/86 - Only global frame is iFrame
  13.  *                      Use message->MouseX and Y
  14.  *                      Wait() for IDCMP
  15.  *  Modified 10/15/86 - For HAM
  16.  *                      Name changed from SeeILBM to ViewILBM
  17.  *  Modified 11/01/86 - Revised for linkage with myreadpict.c
  18.  *  Modified 11/18/86 - For Astartup ... Amiga.lib, LC.lib linkage
  19.  *  Modified 12/12/86 - Added color cycling at request of Mimetics
  20.  *  Modified 01/06/87 - Tab toggles cycling
  21.  *  Modified 03/03/87 - Recognizes RNG_NORATE (36) as non-active DP CRNG
  22.  *                      Changed name to Display
  23.  *  Modified 03/13/87 - Accepts display time in seconds as 2nd CLI arg
  24.  *
  25.  *     This viewer automatically cycles any ILBM that contains cycling
  26.  *     chunks (CCRT or CRNG) which are marked as active and do not
  27.  *     have a CRNG cycle rate of 36. (To DPaint, rate 36 = don't cycle)
  28.  *     Note that by default, DPaint saves its pics with CRNG (cycling)
  29.  *     chunks flagged as active and with a rate not equal to 36.
  30.  *     This can cause this viewer to cycle DPaint pics which were
  31.  *     not meant to be cycled.  To de-activate the CRNG chunks in
  32.  *     a DPaint pic, either resave the pic after setting the cycle
  33.  *     speed for each range to the lowest position, or use the
  34.  *     "uncycle" program. (usage:  uncycle DPaintPicName)
  35.  *
  36.  *
  37.  * Based on ShowILBM.c, readpict.c    1/86
  38.  *  By Jerry Morrison, Steve Shaw, and Steve Hayes, Electronic Arts.
  39.  *  This software is in the public domain.
  40.  *
  41.  * >>NOTE<<: This example must be linked with additional IFF rtn files.
  42.  *           See linkage information below.
  43.  *
  44.  * The display portion is specific to the Commodore Amiga computer.
  45.  *
  46.  * Linkage Information:
  47.  *  (NOTE: All modules including iff stuff compiled with -v on LC2)
  48.  *
  49.  * FROM     AStartup.obj,Display.o,myreadpict.o,iffr.o,ilbmr.o,unpacker.o
  50.  * TO       Display
  51.  * LIBRARY  Amiga.lib, LC.lib
  52.  * 
  53.  */
  54.  
  55. #include <exec/types.h>
  56. #include <exec/memory.h>
  57. #include <exec/tasks.h>
  58. #include <libraries/dos.h>
  59. #include <libraries/dosextens.h>
  60. #include <workbench/startup.h>
  61. #include <intuition/intuition.h>
  62. #include <graphics/gfxbase.h>
  63.  
  64. #include "iff/ilbm.h"
  65. #include "myreadpict.h"
  66.  
  67.  
  68. /* For wbStdio rtns */
  69. extern LONG stdin, stdout, stderr;  /* in Astartup.obj */
  70. char conSpec[] = "CON:0/40/640/140/";
  71. BOOL wbHasStdio = NULL;
  72.  
  73.  
  74. /* general usage pointers */
  75. struct GfxBase       *GfxBase;
  76. struct IntuitionBase *IntuitionBase;
  77. struct IntuiMessage  *message;
  78.  
  79. /* Globals for displaying an image */
  80. struct Screen   *screen1;
  81. struct Window   *window1;
  82. struct RastPort *rport1;
  83. struct ViewPort *vport1;
  84.  
  85. struct BitMap   tBitMap;      /* Temp BitMap struct for small pics  */
  86.  
  87. /* For WorkBench startup */    
  88. extern struct WBStartup *WBenchMsg;
  89. BOOL   fromWB;
  90. struct FileLock *startLock, *newLock;
  91.  
  92. /* Other globals */
  93. int   i, error;
  94. BYTE  c;
  95. BOOL  TBtoggle, Done;
  96. ULONG signals, wSig, class, code, pBytes;
  97. SHORT mouseX, mouseY;
  98.  
  99. char u1[]  = "\n>>> Display <<<   v1  C. Scheppner  CBM  03/87\n";
  100. char u2a[] = "\nUsage: Display ilbmfile [time]\n";
  101. char u2b[] = "\nUsage: Click this icon, SHIFT and DoubleClick on pic\n";
  102. char u3[]  = "Click toggles bar, Tab toggles cycling, Close upper left\n";
  103.  
  104. /* Structures for new Screen, new Window */
  105.  
  106. struct   TextAttr       TextFont = {
  107.    "topaz.font",                    /* Font Name   */
  108.    TOPAZ_EIGHTY,                    /* Font Height */
  109.    FS_NORMAL,                       /* Style       */
  110.    FPF_ROMFONT,                     /* Preferences */
  111.    };
  112.  
  113. struct   NewScreen      ns = {
  114.    0, 0,                                  /* LeftEdge and TopEdge   */
  115.    0, 0,                                  /* Width and Height       */
  116.    0,                                     /* Depth                  */
  117.    1, 0,                                  /* DetailPen and BlockPen */
  118.    NULL,                                  /* Special display modes  */
  119.    CUSTOMSCREEN,                          /* Screen Type            */
  120.    &TextFont,                             /* Use my font            */
  121.    " <- Close here after clicking below",                  /* Title */
  122.    NULL,                                  /* No gadgets yet         */
  123.    NULL,                                  /* Ptr to CustomBitmap    */
  124.    };
  125.  
  126. struct   NewWindow      nw = {
  127.    0, 0,                                  /* LeftEdge and TopEdge */
  128.    0, 0,                                  /* Width and Height */
  129.    -1, -1,                                /* DetailPen and BlockPen */
  130.    MOUSEBUTTONS|VANILLAKEY,               /* IDCMP Flags */
  131.    ACTIVATE
  132.    |BACKDROP
  133.    |BORDERLESS,                           /* Flags */
  134.    NULL, NULL,                            /* Gadget and Image pointers */
  135.    NULL,                                  /* Title string */
  136.    NULL,                                  /* Put Screen ptr here */
  137.    NULL,                                  /* SuperBitMap pointer */
  138.    0, 0,                                  /* MinWidth and MinHeight */
  139.    0, 0,                                  /* MaxWidth and MaxHeight */
  140.    CUSTOMSCREEN,                          /* Type of window */
  141.    };
  142.  
  143. USHORT  allBlack[maxColorReg] = {0};
  144.  
  145. /* For alloc to define new pointer */
  146. #define PDATASZ 12
  147. UWORD   *pdata;
  148.  
  149. #ifndef MIN
  150. #define MIN(a,b) ((a)<(b)?(a):(b))
  151. #endif  MIN
  152.  
  153. extern char *IFFPMessages[];
  154. ILBMFrame   iFrame;       /* my global frame */
  155.  
  156.  
  157. /* Cycle Task stuff */
  158. #define CYCLETIME  16384L
  159. #define REVERSE    0x02
  160. #define ACTIVE     0x01
  161.  
  162. extern VOID cycleTask();
  163. char *cyTaskName = "v2cyTask";
  164. struct Task *cyTask;
  165.  
  166. /* Data shared with cycleTask */
  167. CrngChunk       *cyCrngs;
  168. struct ViewPort *cyVport;
  169. int    cyRegs, cyCnt;
  170. USHORT cyMap[maxColorReg];
  171. LONG   cyClocks[maxCycles];
  172. LONG   cyRates[maxCycles];
  173. BOOL   CycleOn, PrepareToDie;
  174.  
  175. /* For optional time delay */
  176. struct Task *mainTask;
  177. BOOL   TimerOn;
  178. LONG   tSigNum = -1;
  179. ULONG  tSig, dTimer;
  180.  
  181.  
  182. /*****************************************************************/
  183. main(argc, argv)
  184. int argc;
  185. char **argv;
  186.    {
  187.    LONG            file;
  188.    IFFP            iffp = NO_FILE;
  189.    struct WBArg    *arg;  
  190.    char            *filename;
  191.  
  192.    fromWB = (argc==0) ? TRUE : FALSE;
  193.    TimerOn = FALSE;
  194.  
  195.    if((argc>1)&&(*argv[1] != '?'))  /* Passed filename via command line  */
  196.       {
  197.       filename = argv[1];
  198.       if(argc==3)
  199.          {
  200.          TimerOn = TRUE;
  201.          dTimer = 60 * atoi(argv[2]);
  202.          }
  203.       }
  204.    else if ((argc==0)&&(WBenchMsg->sm_NumArgs > 1))
  205.       {                        /* Passed filename via  WorkBench */
  206.       arg = WBenchMsg->sm_ArgList;
  207.       arg++;
  208.       filename   = (char *)arg->wa_Name;
  209.       newLock    = (struct FileLock *)arg->wa_Lock;
  210.       startLock  = (struct FileLock *)CurrentDir(newLock);
  211.       }
  212.    else            /* From WB or CLI, no filename or ? */
  213.       {
  214.       usage();
  215.       cleanexit(" "); /* Space forces my wait for keypress on WB exit */
  216.       }
  217.  
  218.    if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0)))
  219.       cleanexit("Can't open graphics");
  220.  
  221.    if(!(IntuitionBase=
  222.           (struct IntuitionBase *)OpenLibrary("intuition.library",0)))
  223.       cleanexit("Can't open intuition");
  224.  
  225.    if(!(file = Open(filename, MODE_OLDFILE)))
  226.       cleanexit("Picture file not found");
  227.  
  228.    iffp = myReadPicture(file,&iFrame);
  229.    Close(file);
  230.  
  231.    if (!(iffp == IFF_DONE))
  232.       cleanexit("Not an IFF ILBM");
  233.  
  234.  
  235.    error = DisplayPic(&iFrame);
  236.    if(error)  cleanexit("Can't open screen or window");
  237.  
  238.    if(pdata = (UWORD *)AllocMem(PDATASZ,MEMF_CHIP|MEMF_CLEAR))
  239.       {
  240.       pdata[2] = 0x8000;  /* 1 pixel */
  241.       SetPointer(window1,pdata,1,16,0,0);
  242.       }
  243.  
  244.    /* Set up cycle/timer task */
  245.  
  246.    mainTask = (struct Task *)FindTask(NULL);
  247.    if((tSigNum = AllocSignal(-1)) == -1)  cleanexit("Can't alloc timerSig");
  248.    tSig = 1 << tSigNum;
  249.  
  250.    initCycle(&iFrame,vport1);
  251.    cyTask = (struct Task *)CreateTask(cyTaskName,0,cycleTask,4000);
  252.    if(!cyTask)  cleanexit("Can't create cycling task");
  253.    CycleOn = TRUE;
  254.  
  255.    TBtoggle   = FALSE;      /* Title bar toggle */
  256.    Done       = FALSE;      /* Close flag       */
  257.  
  258.    wSig = 1<<window1->UserPort->mp_SigBit;
  259.    tSig = 1<<tSigNum;
  260.  
  261.    while (!Done)
  262.       {
  263.       signals = Wait(wSig|tSig);
  264.       if (signals & wSig)  chkmsg();
  265.       if (signals & tSig)  Done = TRUE;
  266.       }
  267.    cleanup();
  268.    }
  269.  
  270.  
  271. initCycle(ptFrame,vp)
  272. ILBMFrame *ptFrame;
  273. struct ViewPort *vp;
  274.    {
  275.    int k;
  276.  
  277.    CycleOn  = FALSE;
  278.    PrepareToDie = FALSE;
  279.    cyCrngs  = ptFrame->crngChunks;
  280.    cyVport  = vp;
  281.    cyRegs   = ptFrame->nColorRegs;
  282.    cyCnt    = ptFrame->cycleCnt;
  283.  
  284.    for(k=0; k<cyRegs; k++)
  285.       {
  286.       cyMap[k] = ptFrame->colorMap[k];
  287.       }
  288.  
  289.    /* Init Rates and Clocks */
  290.    for(k=0; k<cyCnt; k++)
  291.       {
  292.       /* In DPaint CRNG, rate = RNG_NORATE (36) means don't cycle */
  293.       if(cyCrngs[k].rate == RNG_NORATE)
  294.          {
  295.          cyCrngs[k].rate = 0;
  296.          cyCrngs[k].active &= ~ACTIVE;
  297.          }
  298.  
  299.       if((cyCrngs[k].active & ACTIVE)&&(cyCrngs[k].rate))
  300.          {
  301.          cyRates[k] = cyCrngs[k].rate;
  302.          }
  303.       else
  304.          {
  305.          cyRates[k] = 0;  /* Means don't cycle to my cycleTask */
  306.          }
  307.       cyClocks[k] = 0;
  308.       }
  309.    }
  310.  
  311.  
  312. VOID cycleTask()
  313.    {
  314.    int    k, i, j;
  315.    UBYTE  low, high;
  316.    USHORT cyTmp;
  317.    BOOL   Cycled;
  318.  
  319.    while(!PrepareToDie)
  320.       {
  321.       WaitTOF();
  322.       if(CycleOn)
  323.          {
  324.          Cycled = FALSE;
  325.          for(k=0; k<cyCnt; k++)
  326.             {
  327.             if(cyRates[k])  /* cyRate 0 = inactive */
  328.                {
  329.                cyClocks[k] += cyRates[k];
  330.                if(cyClocks[k] >= CYCLETIME)
  331.                   {
  332.                   Cycled = TRUE;
  333.                   cyClocks[k] -= CYCLETIME;
  334.                   low = cyCrngs[k].low;
  335.                   high= cyCrngs[k].high;
  336.                   if(cyCrngs[k].active & REVERSE)  /* Reverse cycle */
  337.                      {
  338.                      cyTmp = cyMap[low];
  339.                      for(i=low,j=low+1; i < high; i++,j++)
  340.                         {
  341.                         cyMap[i] = cyMap[j];
  342.                         }
  343.                      cyMap[high] = cyTmp;
  344.                      }
  345.                   else     /* Forward cycle */
  346.                      {
  347.                      cyTmp = cyMap[high];
  348.                      for(i=high,j=high-1; i > low; i--,j--)
  349.                         {
  350.                         cyMap[i] = cyMap[j];
  351.                         }
  352.                      cyMap[low] = cyTmp;
  353.                      }
  354.                   }
  355.                }
  356.             }
  357.          if(Cycled)
  358.             {
  359.             LoadRGB4(cyVport,cyMap,cyRegs);
  360.             }
  361.          }
  362.       if(TimerOn)
  363.          {
  364.          if(--dTimer == 0)  Signal(mainTask,tSig);
  365.          }
  366.       }
  367.    PrepareToDie = FALSE;
  368.    while(TRUE);  /* Busy wait to die */
  369.    }
  370.  
  371.  
  372. chkmsg()
  373.    {
  374.    while(message=(struct IntuiMessage *)GetMsg(window1->UserPort))
  375.       {
  376.       class = message->Class;
  377.       code  = message->Code;
  378.       mouseX = message->MouseX;
  379.       mouseY = message->MouseY;
  380.  
  381.       ReplyMsg(message);
  382.       switch(class)
  383.          {
  384.          case MOUSEBUTTONS:
  385.             if ((code == SELECTDOWN)&&
  386.                   (mouseX < 10)&&(mouseY<10))
  387.                {
  388.                Done = TRUE;
  389.                }
  390.             else if ((code == SELECTDOWN)&&
  391.                        ((mouseY>10)||(mouseX>10))&&
  392.                           (TBtoggle==FALSE))
  393.                {
  394.                TBtoggle = TRUE;
  395.                ShowTitle(screen1,TRUE);
  396.                ClearPointer(window1);
  397.                }
  398.             else if ((code == SELECTDOWN)&&
  399.                        (mouseY>10)&&(TBtoggle==TRUE))
  400.                {
  401.                TBtoggle = FALSE;
  402.                ShowTitle(screen1,FALSE);
  403.                SetPointer(window1,pdata,1,16,0,0);
  404.                }
  405.             break;
  406.          case VANILLAKEY:
  407.             if(code==0x09)  /* Tab toggles Cycle */
  408.                {
  409.                if(CycleOn)
  410.                   {
  411.                   CycleOn = FALSE;
  412.                   WaitTOF();        /* Make sure cyTask saw FALSE */
  413.                   WaitBOVP(vport1);
  414.                   LoadRGB4(vport1,iFrame.colorMap,maxColorReg);
  415.                   }
  416.                else
  417.                   {
  418.                   initCycle(&iFrame,vport1);
  419.                   CycleOn = TRUE;
  420.                   }
  421.                }
  422.             break;
  423.          default:
  424.             break;
  425.          }
  426.       }
  427.    }
  428.  
  429.  
  430. usage()
  431.    {
  432.    if ((fromWB)&&(! wbHasStdio))  wbHasStdio = openStdio(conSpec);
  433.  
  434.    if ((!fromWB)||(wbHasStdio))
  435.       {
  436.       Write(stdout,u1,strlen(u1));
  437.       if(!fromWB)  Write(stdout,u2a,strlen(u2a));
  438.       else Write(stdout,u2b,strlen(u2b));
  439.       Write(stdout,u3,strlen(u3));
  440.       }
  441.    }
  442.  
  443. cleanexit(s)
  444.    char  *s;
  445.    {
  446.    if (*s)
  447.       {
  448.       if ((fromWB)&&(! wbHasStdio))  wbHasStdio = openStdio(conSpec);
  449.  
  450.       if ((!fromWB)||(wbHasStdio))
  451.          {
  452.          Write(stdout,s,strlen(s));
  453.          Write(stdout,"\n",1);
  454.          }
  455.       if (wbHasStdio)
  456.          {
  457.          Write(stdout,"\nPRESS RETURN TO EXIT\n",22);
  458.          while (getchar() != '\n');
  459.          }
  460.       }
  461.    cleanup();
  462.    if (wbHasStdio) closeStdio();
  463.    exit();
  464.    }
  465.  
  466.  
  467. cleanup()
  468.    {
  469.    if(cyTask)
  470.       {
  471.       CycleOn = FALSE;
  472.       PrepareToDie = TRUE;
  473.       while(PrepareToDie);
  474.       DeleteTask(cyTask);
  475.       }
  476.  
  477.    /* Free timer signal */
  478.    if (tSigNum > -1)  FreeSignal(tSigNum);
  479.  
  480.    /* Note - tBitMap planes were deallocated in DisplayPic() */
  481.    if (window1)
  482.       {
  483.       while(message=(struct IntuiMessage *)GetMsg(window1->UserPort))
  484.          {
  485.          ReplyMsg(message);
  486.          }
  487.       CloseWindow(window1);
  488.       }
  489.    if (screen1) CloseScreen(screen1);
  490.    if (pdata)   FreeMem(pdata,PDATASZ);
  491.    if (IntuitionBase) CloseLibrary(IntuitionBase);
  492.    if (GfxBase)       CloseLibrary(GfxBase);
  493.    if (newLock != startLock)  CurrentDir(startLock);
  494.    }
  495.  
  496.  
  497. strlen(s)
  498. char *s;
  499.    {
  500.    int i = 0;
  501.    while(*s++) i++;
  502.    return(i);
  503.    }
  504.  
  505.  
  506.  
  507. /** getBitMap() *********************************************************
  508.  *
  509.  * Open screen or temp bitmap.
  510.  *   Returns ptr destBitMap  or  0 = error
  511.  *
  512.  *************************************************************************/
  513. struct BitMap *getBitMap(ptilbmFrame)
  514.    ILBMFrame *ptilbmFrame;
  515.    {
  516.    int     i, nPlanes, plsize;
  517.    SHORT  sWidth, sHeight, dWidth, dHeight;
  518.    struct BitMap *destBitMap;
  519.  
  520.    sWidth  = ptilbmFrame->bmHdr.w;
  521.    sHeight = ptilbmFrame->bmHdr.h;
  522.    dWidth  = ptilbmFrame->bmHdr.pageWidth;
  523.    dHeight = ptilbmFrame->bmHdr.pageHeight;
  524.    nPlanes = MIN(ptilbmFrame->bmHdr.nPlanes, EXDepth);
  525.  
  526.    ns.Width  = dWidth;
  527.    ns.Height = dHeight;
  528.    ns.Depth  = nPlanes;
  529.  
  530.    if (ptilbmFrame->foundCAMG)
  531.       {
  532.       ns.ViewModes = ptilbmFrame->camgChunk.ViewModes;
  533.       }
  534.    else
  535.       {
  536.       if (ptilbmFrame->bmHdr.pageWidth <= 320)
  537.          ns.ViewModes = 0;
  538.       else
  539.          ns.ViewModes = HIRES;
  540.  
  541.       if (ptilbmFrame->bmHdr.pageHeight > 256)
  542.          ns.ViewModes |= LACE;
  543.       }
  544.  
  545.    if ((screen1 = (struct Screen *)OpenScreen(&ns))==NULL)    return(0);
  546.  
  547.    vport1 = &screen1->ViewPort;
  548.    LoadRGB4(vport1, &allBlack[0], ptilbmFrame->nColorRegs);
  549.  
  550.    if((ptilbmFrame->camgChunk.ViewModes)&(HAM))  setHam(screen1,FALSE);
  551.  
  552.    nw.Width  = dWidth;
  553.    nw.Height = dHeight;
  554.    nw.Screen = screen1;
  555.  
  556.    if ((window1 = (struct Window *)OpenWindow(&nw))==NULL)
  557.       {
  558.       CloseScreen(screen1);
  559.       screen1 = NULL;
  560.       return(0);
  561.       }
  562.  
  563.    ShowTitle(screen1, FALSE);
  564.  
  565.    if ((sWidth == dWidth) && (sHeight == dHeight))
  566.       {
  567.       destBitMap = (struct BitMap *)screen1->RastPort.BitMap;
  568.       }
  569.    else
  570.       {
  571.       InitBitMap( &tBitMap,
  572.                   nPlanes,
  573.                   sWidth,
  574.                   sHeight);
  575.  
  576.       plsize = RowBytes(ptilbmFrame->bmHdr.w) * ptilbmFrame->bmHdr.h;
  577.       if (tBitMap.Planes[0] =
  578.        (PLANEPTR)AllocMem(nPlanes * plsize, MEMF_CHIP))
  579.          {
  580.          for (i = 1; i < nPlanes; i++)
  581.             tBitMap.Planes[i] = (PLANEPTR)tBitMap.Planes[0] + plsize*i;
  582.          destBitMap = &tBitMap;
  583.          }
  584.       else
  585.          {
  586.          CloseWindow(window1);
  587.          window1 = NULL;
  588.          CloseScreen(screen1);
  589.          screen1 = NULL;
  590.          return(0);  /* can't allocate temp BitMap */
  591.          }
  592.       }
  593.    return(destBitMap);          /* destBitMap allocated */
  594.    }
  595.  
  596.  
  597. /** DisplayPic() *********************************************************
  598.  *
  599.  * Display loaded bitmap.  If tBitMap, first transfer to screen.
  600.  *
  601.  *************************************************************************/
  602. DisplayPic(ptilbmFrame)
  603.    ILBMFrame *ptilbmFrame;
  604.    {
  605.    int    i, row, byte, nrows, nbytes;
  606.    struct BitMap  *tbp, *sbp; /* temp and screen BitMap ptrs */
  607.    UBYTE  *tpp, *spp;         /* temp and screen plane ptrs  */
  608.  
  609.    if (tBitMap.Planes[0])     /* transfer from tBitMap if nec. */
  610.       {
  611.       tbp = &tBitMap;
  612.       sbp = screen1->RastPort.BitMap;
  613.       nrows  = MIN(tbp->Rows, sbp->Rows);
  614.       nbytes = MIN(tbp->BytesPerRow, sbp->BytesPerRow);
  615.  
  616.       for (i = 0; i < sbp->Depth; i++)
  617.          {
  618.          tpp = (UBYTE *)tbp->Planes[i];
  619.          spp = (UBYTE *)sbp->Planes[i];
  620.          for (row = 0; row < nrows; row++)
  621.             {
  622.             tpp = tbp->Planes[i] + (row * tbp->BytesPerRow);
  623.             spp = sbp->Planes[i] + (row * sbp->BytesPerRow);
  624.             for (byte = 0; byte < nbytes; byte++)
  625.                {
  626.                *spp++ = *tpp++;
  627.                }
  628.             }
  629.          }
  630.       /*  Can now deallocate the temp BitMap  */
  631.       FreeMem(tBitMap.Planes[0],
  632.                  tBitMap.BytesPerRow * tBitMap.Rows * tBitMap.Depth);
  633.       }
  634.  
  635.    vport1 = &screen1->ViewPort;
  636.    LoadRGB4(vport1, ptilbmFrame->colorMap, ptilbmFrame->nColorRegs);
  637.    if((ptilbmFrame->camgChunk.ViewModes)&(HAM))  setHam(screen1,TRUE);
  638.  
  639.    return(0);
  640.    }
  641.  
  642.  
  643. /* setHam --- For toggling HAM so HAM pic invisible while loading */
  644. setHam(scr,toggle)
  645. struct Screen *scr;
  646. BOOL   toggle;
  647.    {
  648.    struct ViewPort *vp;
  649.    struct View     *v;
  650.  
  651.    vp = &(scr->ViewPort);
  652.    v = (struct View *)ViewAddress();
  653.    Forbid();
  654.    if(toggle)
  655.       {
  656.       v->Modes  |= HAM;
  657.       vp->Modes |= HAM;
  658.       }
  659.    else
  660.       {
  661.       v->Modes  &= ~HAM;
  662.       vp->Modes &= ~HAM;
  663.       }
  664.    MakeScreen(scr);
  665.    RethinkDisplay();
  666.    Permit();
  667.    }
  668.  
  669.  
  670. /* wbStdio.c --- Open an Amiga stdio window under workbench
  671.  *               For use with AStartup.obj
  672.  */
  673.  
  674. openStdio(conspec)
  675. char *conspec;
  676.    {
  677.    LONG wfile;
  678.    struct Process *proc;
  679.    struct FileHandle *handle;
  680.  
  681.    if (wbHasStdio)  return(1);
  682.  
  683.    if (!(wfile = Open(conspec,MODE_NEWFILE)))  return(0);
  684.    stdin  = wfile;
  685.    stdout = wfile;
  686.    stderr = wfile;
  687.    handle = (struct FileHandle *)(wfile << 2);
  688.    proc = (struct Process *)FindTask(NULL);
  689.  
  690.    proc->pr_ConsoleTask = (APTR)(handle->fh_Type);
  691.    proc->pr_CIS = (BPTR)stdin;
  692.    proc->pr_COS = (BPTR)stdout;
  693.    return(1);
  694.    }
  695.  
  696. closeStdio()
  697.    {
  698.    struct Process *proc;
  699.    struct FileHandle *handle;
  700.  
  701.    if (! wbHasStdio) return(0);
  702.  
  703.    if (stdin > 0)  Close(stdin);
  704.    stdin  = -1;
  705.    stdout = -1;
  706.    stderr = -1;
  707.    handle = (struct FileHandle *)(stdin << 2);
  708.    proc = (struct Process *)FindTask(NULL);
  709.    proc->pr_ConsoleTask = NULL;
  710.    proc->pr_CIS = NULL;
  711.    proc->pr_COS = NULL;
  712.    wbHasStdio = NULL;
  713.    }
  714.  
  715.