home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 125.lha / PhotonSlide.c < prev    next >
C/C++ Source or Header  |  1986-11-20  |  10KB  |  601 lines

  1. /* Photon SlideShow, by Oren Peli.
  2.     Copyright (c) 1988 BazboSoft! and (c) 1988 MicroIllusions. */
  3.  
  4. /* This program may be freely distributed and used for non-commercial
  5.    purposes. Any changed versions of this program must retain the original
  6.    copyright notices */
  7.  
  8. #include <libraries/dos.h>
  9. #include <graphics/gfxbase.h>
  10. #include <stdio.h>
  11.  
  12. void *OpenLibrary() , *OpenScreen() , *OpenWindow();
  13. struct Window *MyOpenWindow();
  14. LONG Write();
  15.  
  16. void *FindTask();
  17.  
  18. void *GetDiskObject() , *FindToolType();
  19.  
  20. void *Open() , *AllocMem();
  21.  
  22. #define MAXWIDTH    376
  23. #define MAXHEIGHT    242
  24. #define MAXCOLORS    32
  25.  
  26. #define MakeID(a , b , c , d) ( (a) << 24L | (b) << 16L | (c) << 8 | (d) )
  27.  
  28. #define ID_FORM MakeID('F' , 'O' , 'R' , 'M')
  29. #define ID_ILBM MakeID('I' , 'L' , 'B' , 'M')
  30. #define ID_BMHD MakeID('B' , 'M' , 'H' , 'D')
  31. #define ID_CAMG MakeID('C' , 'A' , 'M' , 'G')
  32. #define ID_CMAP MakeID('C' , 'M' , 'A' , 'P')
  33. #define ID_BODY MakeID('B' , 'O' , 'D' , 'Y')
  34.  
  35. #define cmpByteRun1 1
  36.  
  37. #define ROUNDODDUP(a) ( ( (a) + 1) & (~1L) )
  38.  
  39. typedef struct
  40. {
  41.     LONG ckID , ckSize;
  42. } Chunk;
  43.  
  44. typedef struct
  45. {
  46.     short w , h , x , y;
  47.     char    nPlanes , masking , compression , pad1;
  48.     short transparentColor;
  49.     char    xAspect ,  yAspect;
  50.     short pageWidth , pageHeight;
  51. } BitMapHeader;
  52.  
  53. #define SafeRead(a , b , c) if (Read(a , b , c) == -1L) { Close(a); return(NULL); }
  54.  
  55. void *IntuitionBase;
  56.  
  57. struct GfxBase *GfxBase;
  58.  
  59. BitMapHeader bmhd;
  60. char *bufstart;
  61. Chunk header;
  62.  
  63. void *ReadILBM(fspec)
  64. REGISTER char *fspec;
  65. {
  66.     REGISTER struct NewScreen NewScreen;
  67.     REGISTER struct Screen *screen;
  68.     REGISTER struct FileHandle *fp;
  69.     REGISTER char colormap[MAXCOLORS][3] , *sourcebuf;
  70.     REGISTER short colorcount;
  71.     LONG id , ViewModes = 0L;
  72.  
  73.     if ( (fp = Open(fspec , MODE_OLDFILE) ) == 0L)
  74.         return(NULL);
  75.  
  76.     SafeRead(fp , &header , (LONG) sizeof(header) );
  77.  
  78.     if (header.ckID != ID_FORM)
  79.     {
  80.         Close(fp);
  81.         return(NULL);
  82.     }
  83.  
  84.     SafeRead(fp , &id , (LONG) sizeof(id) );
  85.  
  86.     if (id != ID_ILBM)
  87.     {
  88.         Close(fp);
  89.         return(NULL);
  90.     }
  91.  
  92.     for (;;)
  93.     {
  94.         SafeRead(fp , &header , (LONG) sizeof(header) );
  95.  
  96.         if (header.ckID == ID_BODY)
  97.             break;
  98.  
  99.         switch(header.ckID)
  100.         {
  101.             case ID_BMHD:    SafeRead(fp , &bmhd , (LONG) sizeof(bmhd) );
  102.                             break;
  103.  
  104.             case ID_CMAP:    SafeRead(fp , &colormap[0] [0] , (LONG) header.ckSize);
  105.                             colorcount = header.ckSize / 3;
  106.  
  107.                             break;
  108.  
  109.             case ID_CAMG:    SafeRead(fp , &ViewModes , (LONG) header.ckSize);
  110.                             break;
  111.  
  112.             default:        Seek(fp , ROUNDODDUP(header.ckSize) , OFFSET_CURRENT);
  113.         }
  114.     }
  115.  
  116.     sourcebuf = bufstart = AllocMem( (LONG) header.ckSize , MEMF_PUBLIC);
  117.  
  118.     if (sourcebuf == 0L)
  119.     {
  120.         Close(fp);
  121.  
  122.         return(NULL);
  123.     }
  124.  
  125.     SafeRead(fp , sourcebuf , (LONG) header.ckSize);
  126.     Close(fp);
  127.  
  128.     NewScreen.LeftEdge = 0;
  129.     NewScreen.TopEdge = GfxBase->NormalDisplayRows;
  130.     NewScreen.Width = bmhd.w;
  131.     NewScreen.Height = bmhd.h;
  132.     NewScreen.Depth = bmhd.nPlanes;
  133.  
  134.     if (NOT (NewScreen.ViewModes = ViewModes) )
  135.     {
  136.         if (bmhd.w > MAXWIDTH)
  137.             NewScreen.ViewModes |= HIRES;
  138.  
  139.         if (bmhd.h > MAXHEIGHT)
  140.             NewScreen.ViewModes |= LACE;
  141.     }
  142.  
  143.     if (NewScreen.ViewModes & LACE)
  144.         NewScreen.TopEdge *= 2;
  145.  
  146.     NewScreen.Type = CUSTOMSCREEN | SCREENQUIET | SCREENBEHIND;
  147.     NewScreen.Font = 0L;
  148.     NewScreen.Gadgets = 0L;
  149.  
  150.     if (screen = OpenScreen(&NewScreen) )
  151.     {
  152.         if (NewScreen.ViewModes & HIRES)
  153.             screen->LeftEdge += (640 - screen->Width) / 2;
  154.         else
  155.             screen->LeftEdge += (320 - screen->Width) / 2;
  156.  
  157.         if (NewScreen.ViewModes & LACE)
  158.             screen->ViewPort.DyOffset += (400 - screen->Height) / 2;
  159.         else
  160.             screen->ViewPort.DyOffset += (200 - screen->Height) / 2;
  161.  
  162.         screen->ViewPort.DxOffset = screen->LeftEdge;
  163.  
  164.         MakeScreen(screen);
  165.  
  166.         RethinkDisplay();
  167.  
  168.         while (colorcount--)
  169.             SetRGB4(&screen->ViewPort , (LONG) colorcount , colormap[colorcount][0] >>
  170.                     4L , colormap[colorcount][1] >> 4L , colormap[colorcount][2] >> 4L);
  171.     }
  172.  
  173.     return(screen);
  174. }
  175.  
  176. Expand(screen , bmhd , sourcebuf)
  177. struct Screen *screen;
  178. BitMapHeader *bmhd;
  179. register char *sourcebuf;
  180. {
  181.     register char n , *destbuf;
  182.     register short plane , linelen , rowbytes , i;
  183.  
  184.     linelen = bmhd->w / 8;
  185.  
  186.     for (i = 0 ; i < bmhd->h ; i++)
  187.         for (plane = 0 ; plane < bmhd->nPlanes ; plane++)
  188.         {
  189.             destbuf = (char *) (screen->BitMap.Planes[plane]) + linelen * i;
  190.  
  191.             if (bmhd->compression == cmpByteRun1)
  192.             {
  193.                 rowbytes = linelen;
  194.  
  195.                 while (rowbytes)
  196.                 {
  197.                     n = *sourcebuf++;
  198.  
  199.                     if (n >= 0)
  200.                     {
  201.                         CopyMem(sourcebuf , destbuf , (LONG) ++n);
  202.  
  203.                         rowbytes -= n;
  204.  
  205.                         destbuf += n;
  206.  
  207.                         sourcebuf += n;
  208.                     }
  209.  
  210.                     else
  211.                     {
  212.                         n = -n + 1;
  213.  
  214.                         rowbytes -= n;
  215.  
  216.                         setmem(destbuf , (WORD) n , (WORD) *sourcebuf++);
  217.  
  218.                         destbuf += n;
  219.                     }
  220.  
  221.                 }
  222.             }
  223.  
  224.             else
  225.             {
  226.                 CopyMem(sourcebuf , destbuf , (LONG) linelen);
  227.  
  228.                 sourcebuf += linelen;
  229.  
  230.                 destbuf += linelen;
  231.             }
  232.         }
  233. }
  234.  
  235. USHORT dummydata[] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
  236.  
  237. struct Window *
  238. load_pic(name , otherwindow)
  239. REGISTER BYTE *name;
  240. REGISTER struct Window *otherwindow;
  241. {
  242.     REGISTER struct Screen *screen;
  243.     REGISTER struct Window *window;
  244.     REGISTER struct NewWindow nw;
  245.  
  246.     setmem(&nw , sizeof(nw) , 0);
  247.  
  248.     if (NOT (screen = ReadILBM(name) ) )
  249.         return(NULL);
  250.  
  251.     nw.IDCMPFlags = VANILLAKEY;
  252.     nw.Flags = SIMPLE_REFRESH | BORDERLESS | RMBTRAP | ACTIVATE;
  253.     nw.Screen = screen;
  254.     nw.Type = CUSTOMSCREEN;
  255.     nw.Height = bmhd.h;
  256.     nw.Width = bmhd.w;
  257.  
  258.     if (NOT (window = MyOpenWindow(&nw , otherwindow) ) )
  259.     {
  260.         CloseScreen(screen);
  261.  
  262.         return(NULL);
  263.     }
  264.  
  265.     SetPointer(window , dummydata , 2L , 2L , NULL , NULL);
  266.  
  267.     Expand(screen , &bmhd , bufstart);
  268.  
  269.     FreeMem(bufstart , (LONG) header.ckSize);
  270.  
  271.     return(window);
  272. }
  273.  
  274. static BYTE str_buf[1000];
  275.  
  276. extern WORD Enable_Abort = 0;
  277.  
  278. WORD abort = 0;
  279.  
  280. main(argc , argv)
  281. REGISTER WORD argc;
  282. REGISTER BYTE *argv[];
  283. {
  284.     REGISTER WORD i = 0 , cnt = 1;
  285.     REGISTER struct Window *win[2];
  286.     REGISTER struct Screen *scr[2];
  287.  
  288.     REGISTER FILE *fopen() , *fp;
  289.  
  290.     REGISTER BYTE file_name[500];
  291.  
  292.     REGISTER WORD method , arg1 , arg2 , wait;
  293.  
  294.     scr[0] = scr[1] = NULL;
  295.     win[0] = win[1] = NULL;
  296.  
  297.     IntuitionBase = OpenLibrary("intuition.library" , 0L);
  298.     GfxBase = OpenLibrary("graphics.library" , 0L);
  299.  
  300.     if (NOT GfxBase || NOT IntuitionBase)
  301.         goto end;
  302.  
  303.     puts("\nPhoton SlideShow, by Oren Peli.\n\
  304. Copyright (c) 1988 BazboSoft! and (c) 1988 MicroIllusions.\n");
  305.  
  306.     if (argc == 1)
  307.         fp = fopen("script" , "r");
  308.  
  309.     else if (argc == 2)
  310.         fp = fopen(argv[1] , "r");
  311.     
  312.     else
  313.     {
  314.         puts("Bad args.");
  315.  
  316.         goto end;
  317.     }
  318.  
  319.     if (NOT fp)
  320.     {
  321.         puts("Can't open script file ... aborting!");
  322.         goto end;
  323.     }
  324.  
  325. forever:
  326.     while (fgets(str_buf , 990 , fp) )
  327.     {
  328.         REGISTER WORD len = strlen(str_buf) - 1;
  329.         REGISTER WORD t , p = 0;
  330.  
  331.         for (t = 0 ; t != len ; t++)
  332.             if (str_buf[t] == ',')
  333.             {
  334.                 str_buf[t] = '\0';
  335.                 
  336.                 p++;
  337.             }
  338.  
  339.         if (p != 4)
  340.         {
  341.             puts("Bad script file: wrong number of arguments ... aborting!");
  342.  
  343.             goto end;
  344.         }
  345.  
  346.         p = 0;
  347.  
  348.         strncpy(file_name , str_buf , 490);
  349.  
  350.         p += strlen(&str_buf[p]);
  351.  
  352.         p++;
  353.  
  354.         method = atoi(&str_buf[p]);
  355.  
  356.         p += strlen(&str_buf[p]);
  357.  
  358.         p++;
  359.  
  360.         arg1 = atoi(&str_buf[p]);
  361.  
  362.         p += strlen(&str_buf[p]);
  363.  
  364.         p++;
  365.  
  366.         arg2 = atoi(&str_buf[p]);
  367.  
  368.         p += strlen(&str_buf[p]);
  369.  
  370.         p++;
  371.  
  372.         wait = atoi(&str_buf[p]);
  373.  
  374.         i = 1 - i;
  375.  
  376.         if (win[i])
  377.         {
  378.             chk_abort(win[i]);
  379.  
  380.             CloseWindowSafely(win[i]);
  381.             CloseScreen(scr[i]);
  382.             
  383.             win[i] = NULL;
  384.             scr[i] = NULL;
  385.         }
  386.         
  387.         if (abort)
  388.             goto bye;
  389.  
  390.         if (NOT (win[i] = load_pic(file_name , win[1 - i] ) ) )
  391.         {
  392.             puts("Can't read file or not enough memory ... aborting!");
  393.  
  394.             goto end;
  395.         }
  396.  
  397.         scr[i] = win[i]->WScreen;
  398.  
  399.         chk_abort(win[i]);
  400.  
  401.         if (abort)
  402.             goto bye;
  403.  
  404.         show_screen(scr[i] , win[i] , method , arg1 , arg2);
  405.  
  406.         if (wait > 0)
  407.         {
  408.             for (t = 0 ; t <= wait ; t++)
  409.             {
  410.                 if (chk_abort(win[i]) )
  411.                     break;
  412.                 
  413.                 if (abort)
  414.                     goto bye;
  415.  
  416.                 Delay(50L);
  417.             }
  418.         }
  419.  
  420.         if (abort)
  421.             goto bye;
  422.  
  423.     }
  424.  
  425.     rewind(fp);
  426.  
  427.     goto forever;
  428.  
  429. bye:
  430.     fclose(fp);
  431.  
  432.     i = 1 - i;
  433.  
  434. end:
  435.  
  436.     if (win[i])
  437.     {
  438.         CloseWindowSafely(win[i]);
  439.         CloseScreen(scr[i]);
  440.         
  441.         win[i] = NULL;
  442.         scr[i] = NULL;
  443.     }
  444.  
  445.     i = 1 - i;
  446.         
  447.     if (win[i])
  448.     {
  449.         CloseWindowSafely(win[i]);
  450.         CloseScreen(scr[i]);
  451.         
  452.         win[i] = NULL;
  453.         scr[i] = NULL;
  454.     }
  455.  
  456.     if (IntuitionBase);
  457.         CloseLibrary(IntuitionBase);
  458.  
  459.     if (GfxBase)
  460.         CloseLibrary(GfxBase);
  461.  
  462.     exit(0);
  463. }
  464.  
  465. chk_abort(win)
  466. REGISTER struct Window *win;
  467. {
  468.     REGISTER struct IntuiMessage *msg , *GetMsg();
  469.  
  470.     REGISTER WORD code , was_pause = 0 , pausing = 0;
  471.  
  472. forever:
  473.  
  474.     if (msg = GetMsg(win->UserPort) )
  475.     {
  476.         code = msg->Code;
  477.         
  478.         ReplyMsg(msg);
  479.         
  480.         if (code == '' || code == 'q' || code == 'Q')
  481.         {
  482.             abort = 1;
  483.             
  484.             return(was_pause);
  485.         }
  486.         
  487.         was_pause = 1;
  488.  
  489.         pausing = NOT pausing;
  490.  
  491.         if (pausing)
  492.             WaitPort(win->UserPort);
  493.  
  494.         else
  495.             return(was_pause);
  496.     }
  497.  
  498.     else
  499.         return(was_pause);
  500.  
  501.     goto forever;
  502. }
  503.  
  504. show_screen(scr , win , method , arg1 , arg2)
  505. REGISTER struct Screen *scr;
  506. REGISTER struct Window *win;
  507. REGISTER WORD method , arg1 , arg2;
  508. {
  509.     switch(method)
  510.     {
  511.         case 1:    scrollup(scr , win , arg1);
  512.                 break;
  513.  
  514.         default:
  515.                 scrollup(scr , win , -1);
  516.                 break;
  517.     }
  518. }
  519.  
  520. scrollup(scr , win , jump)
  521. REGISTER struct Screen *scr;
  522. REGISTER struct Window *win;
  523. REGISTER WORD jump;
  524. {
  525.     REGISTER WORD i , is_lace = (NOT (NOT (scr->ViewPort.Modes & LACE) ) ) + 1;
  526.  
  527.     REGISTER WORD prev_pri = SetTaskPri(FindTask(NULL) , 9L);
  528.  
  529.     if (jump < 1)
  530.         MoveScreen(scr , 0L , -9999L);
  531.  
  532.     ScreenToFront(scr);
  533.  
  534.     while (scr->TopEdge)
  535.     {
  536.         MoveScreen(scr , 0L , - (LONG) jump * is_lace);
  537.         
  538.         chk_abort(win);
  539.         
  540.         if (abort)
  541.             return;
  542.     }
  543.  
  544.     SetTaskPri(FindTask(NULL) , (LONG) prev_pri);
  545. }
  546.  
  547.  
  548. struct Window *
  549. MyOpenWindow(newwin , otherwin)
  550. REGISTER struct NewWindow *newwin;
  551. REGISTER struct Window *otherwin;
  552. {
  553.     REGISTER struct Window *t_win;
  554.  
  555.     if (NOT otherwin)
  556.         return(OpenWindow(newwin) );
  557.  
  558.     newwin->IDCMPFlags = NULL;
  559.  
  560.     if (NOT (t_win = OpenWindow(newwin) ) )
  561.         return(NULL);
  562.  
  563.     t_win->UserPort = otherwin->UserPort;
  564.  
  565.     ModifyIDCMP(t_win , otherwin->IDCMPFlags);
  566.  
  567.     return(t_win);
  568. }
  569.  
  570. CloseWindowSafely(p_wind)
  571. REGISTER struct Window *p_wind;
  572. {
  573.     REGISTER struct IntuiMessage *msg , *succ;
  574.     REGISTER struct Window *window = p_wind;
  575.     REGISTER struct MsgPort *mp = (struct MsgPort *) window->UserPort;
  576.  
  577.     Forbid();
  578.  
  579.     msg = (struct IntuiMessage *) mp->mp_MsgList.lh_Head;
  580.  
  581.     while (succ = (struct IntuiMessage *) msg->ExecMessage.mn_Node.ln_Succ)
  582.     {
  583.         if (msg->IDCMPWindow == window)
  584.         {
  585.             Remove(msg);
  586.  
  587.             ReplyMsg(msg);
  588.         }
  589.  
  590.         msg = succ;
  591.     }
  592.  
  593.     window->UserPort = NULL;
  594.  
  595.     ModifyIDCMP(window , NULL);
  596.  
  597.     Permit();
  598.  
  599.     CloseWindow(window);
  600. }
  601.