home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 2000 April & May / AMIGA_2000_04.iso / patches / guigfxlib / guigfxlib.lha..lha / GuiGFXLib / examples / MystiCube / source / MystiCube.c < prev    next >
C/C++ Source or Header  |  1998-07-13  |  28KB  |  1,265 lines

  1. /*********************************************************************
  2. ----------------------------------------------------------------------
  3.  
  4.     MystiCube 1.3
  5.     © 1997 captain bifat / TEK neoscientists
  6.  
  7.     drag'n'drop picture viewer
  8.     a simple demonstration for guigfx.library
  9.  
  10.     many parameters are fixed, modify them
  11.     to suit your personal taste
  12.  
  13. ----------------------------------------------------------------------
  14. *********************************************************************/
  15.  
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <stdlib.h>
  19. #include <math.h>
  20.  
  21. #include <utility/tagitem.h>
  22. #include <workbench/startup.h>
  23. #include <workbench/workbench.h>
  24. #include <intuition/intuition.h>
  25. #include <guigfx/guigfx.h>
  26.  
  27. #include <clib/macros.h>
  28.  
  29. #include <proto/exec.h>
  30. #include <proto/intuition.h>
  31. #include <proto/graphics.h>
  32. #include <proto/utility.h>
  33. #include <proto/guigfx.h>
  34. #include <proto/wb.h>
  35. #include <proto/dos.h>
  36. #include <proto/intuition.h>
  37. #include <proto/guigfx.h>
  38.  
  39. #include "MystiCube.h"
  40.  
  41. #include "timer.h"
  42.  
  43. /*------------------------------------------------------------------*/
  44.  
  45. long __stack = 20000;
  46.  
  47. static char versionstring[] = "$VER: " PROGNAME __VERSION__ "";
  48.  
  49.  
  50. /*********************************************************************
  51. ----------------------------------------------------------------------
  52.  
  53.     global
  54.  
  55. ----------------------------------------------------------------------
  56. *********************************************************************/
  57.  
  58. void CloseGlobal(void)
  59. {
  60.     CloseLibrary(GuiGFXBase);
  61.     GuiGFXBase = NULL;
  62. }
  63.  
  64. BOOL InitGlobal(void)
  65. {
  66.     GuiGFXBase = OpenLibrary("guigfx.library", GUIGFX_VERSION);
  67.  
  68.     if (!GuiGFXBase)
  69.     {
  70.         GuiGFXBase = OpenLibrary("libs/guigfx.library", GUIGFX_VERSION);
  71.     }
  72.  
  73.     if (GuiGFXBase)
  74.     {
  75.         return TRUE;
  76.     }
  77.  
  78.     CloseGlobal();
  79. }
  80.  
  81.  
  82. /*********************************************************************
  83. ----------------------------------------------------------------------
  84.  
  85.     void UpdateWindowParameters(mvwindow)
  86.  
  87.     get current window parameters
  88.  
  89. ----------------------------------------------------------------------
  90. *********************************************************************/
  91.  
  92. void UpdateWindowParameters(struct mvwindow *win)
  93. {
  94.     win->winleft = win->window->LeftEdge;
  95.     win->wintop = win->window->TopEdge;
  96.     win->winwidth = win->window->Width;
  97.     win->winheight = win->window->Height;
  98.     win->innerleft = win->window->BorderLeft;
  99.     win->innertop = win->window->BorderTop;
  100.     win->innerwidth = win->winwidth - win->innerleft - win->window->BorderRight;
  101.     win->innerheight = win->winheight - win->innertop - win->window->BorderBottom;
  102. }
  103.  
  104.  
  105. /*********************************************************************
  106. ----------------------------------------------------------------------
  107.  
  108.     DeleteMVWindow (mvwindow)
  109.  
  110. ----------------------------------------------------------------------
  111. *********************************************************************/
  112.  
  113. void DeleteMVWindow (struct mvwindow *win)
  114. {
  115.     if (win)
  116.     {
  117.         if (win->window)
  118.         {
  119.             Forbid();
  120.  
  121.             if (win->appwindow && win->appmsgport)
  122.             {
  123.                 struct AppMessage *appmsg;
  124.             
  125.                 while (appmsg = (struct AppMessage *) GetMsg(win->appmsgport))
  126.                 {
  127.                     ReplyMsg((struct Message *) appmsg);
  128.                 }
  129.             
  130.                 RemoveAppWindow(win->appwindow);
  131.             }
  132.     
  133.             DeleteMsgPort(win->appmsgport);
  134.  
  135.             Permit();
  136.  
  137.             CloseWindow(win->window);
  138.         }
  139.         
  140.         free(win);
  141.     }
  142. }
  143.  
  144.  
  145.  
  146. /*********************************************************************
  147. ----------------------------------------------------------------------
  148.  
  149.     mvwindow = CreateMVWindow (screen)
  150.  
  151. ----------------------------------------------------------------------
  152. *********************************************************************/
  153.  
  154. #define inserttag(x,t,d) {(x)->ti_Tag=(t);((x)++)->ti_Data=(ULONG)(d);}
  155.  
  156. struct mvwindow *CreateMVWindow (struct Screen *scr)
  157. {
  158.     struct mvwindow *win;
  159.     
  160.     if (win = malloc(sizeof(struct mvwindow)))
  161.     {
  162.         BOOL success = FALSE;
  163.         struct TagItem *taglist;
  164.  
  165.         memset(win, 0, sizeof(struct mvwindow));
  166.  
  167.         win->screen = scr;
  168.  
  169.         if(win->appmsgport = CreateMsgPort())
  170.         {
  171.             win->appSignal = 1L << win->appmsgport->mp_SigBit;
  172.  
  173.             if(taglist = AllocateTagItems(20))
  174.             {
  175.                 UWORD visibleWidth, visibleHeight, visibleMidX, visibleMidY;
  176.                 UWORD visibleLeft, visibleTop;
  177.                 WORD winwidth, winheight, wintop, winleft;
  178.                 struct TagItem *tp = taglist;
  179.                 ULONG modeID;
  180.         
  181.                 visibleWidth = scr->Width;
  182.                 visibleHeight = scr->Height;
  183.         
  184.                 if ((modeID = GetVPModeID(&scr->ViewPort)) != INVALID_ID)
  185.                 {
  186.                     DisplayInfoHandle dih;
  187.             
  188.                     if(dih = FindDisplayInfo(modeID))
  189.                     {
  190.                         struct DimensionInfo di;    
  191.             
  192.                         if(GetDisplayInfoData(dih, (UBYTE*) &di, sizeof(di), DTAG_DIMS, modeID))
  193.                         {
  194.                             visibleWidth = di.TxtOScan.MaxX - di.TxtOScan.MinX;
  195.                             visibleHeight = di.TxtOScan.MaxY - di.TxtOScan.MinY;
  196.                         }
  197.                     }
  198.                 }
  199.         
  200.                 visibleLeft = -scr->ViewPort.DxOffset;
  201.                 visibleTop = -scr->ViewPort.DyOffset;
  202.  
  203.                 visibleMidX = visibleWidth/2 - scr->ViewPort.DxOffset;
  204.                 visibleMidY = visibleHeight/2 - scr->ViewPort.DyOffset;
  205.         
  206.                 winwidth = visibleWidth / 2;
  207.                 winheight = visibleHeight / 2;
  208.                 inserttag(tp, WA_Width, winwidth);
  209.                 inserttag(tp, WA_Height, winheight);
  210.         
  211.                 winleft = visibleMidX - winwidth/2;
  212.                 wintop = visibleMidY - winheight/2;
  213.                 inserttag(tp, WA_Left, winleft);
  214.                 inserttag(tp, WA_Top, wintop);
  215.     
  216.                 win->otherwinpos[0] = visibleLeft;
  217.                 win->otherwinpos[1] = visibleTop;
  218.                 win->otherwinpos[2] = visibleWidth;
  219.                 win->otherwinpos[3] = visibleHeight;
  220.  
  221.                 inserttag(tp, WA_Zoom, &win->otherwinpos);
  222.  
  223.                 inserttag(tp, WA_PubScreen, scr);
  224.         
  225.                 inserttag(tp, WA_Title, DEFAULT_WINTITLE);
  226.         
  227.                 inserttag(tp, WA_NewLookMenus, TRUE);
  228.         
  229.         
  230.                 inserttag(tp, WA_Flags, 
  231.                             WFLG_SIZEBBOTTOM | WFLG_DRAGBAR | WFLG_REPORTMOUSE |
  232.                             WFLG_SIZEGADGET | WFLG_DEPTHGADGET | WFLG_ACTIVATE |
  233.                             WFLG_CLOSEGADGET | WFLG_SIMPLE_REFRESH);
  234.  
  235.                 win->idcmp = IDCMP_CLOSEWINDOW | IDCMP_NEWSIZE |
  236.                             IDCMP_VANILLAKEY | IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS;
  237.  
  238.                 inserttag(tp, WA_IDCMP, win->idcmp);
  239.             
  240.                 inserttag(tp, WA_MinWidth, DEFAULT_MINWIDTH);
  241.                 inserttag(tp, WA_MinHeight, DEFAULT_MINHEIGHT);
  242.                 inserttag(tp, WA_MaxWidth, DEFAULT_MAXWIDTH);
  243.                  inserttag(tp, WA_MaxHeight, DEFAULT_MAXHEIGHT);
  244.  
  245.                 inserttag(tp, TAG_DONE, 0);
  246.         
  247.                 if(win->window = OpenWindowTagList(NULL, taglist))
  248.                 {
  249.                     win->idcmpSignal = 1L << win->window->UserPort->mp_SigBit;
  250.                     UpdateWindowParameters(win);
  251.  
  252.                     win->appwindow = AddAppWindow(0, 0, win->window, win->appmsgport, NULL);
  253.  
  254.                     success = TRUE;
  255.                 }
  256.         
  257.                 FreeTagItems(taglist);
  258.             }
  259.         }
  260.         
  261.         if (!success)
  262.         {
  263.             DeleteMVWindow(win);
  264.             win = NULL;
  265.         }
  266.     }
  267.  
  268.     return win;
  269. }
  270.  
  271. #undef inserttag
  272.  
  273.  
  274. /*********************************************************************
  275. ----------------------------------------------------------------------
  276.  
  277.     docube(cube, zoom, bufferpic, width, height, outside)
  278.  
  279.     calculate coordinates, draw faces
  280.  
  281. ----------------------------------------------------------------------
  282. *********************************************************************/
  283.  
  284. void docube(struct cube *cube, double zoom, PICTURE *bufferpic, int width, int height, BOOL outside)
  285. {
  286.     struct face *face;
  287.  
  288.     double xcosinus, xsinus;
  289.     double ycosinus, ysinus;
  290.     double zcosinus, zsinus;
  291.     double x, y, z, t;
  292.     BOOL visible;
  293.     int i;
  294.     
  295.  
  296.     if (bufferpic)
  297.     {
  298.         //    calculate 2d coordinates
  299.     
  300.         xcosinus = cos(cube->xrot);
  301.         xsinus = sin(cube->xrot);
  302.         ycosinus = cos(cube->yrot);
  303.         ysinus = sin(cube->yrot);
  304.         zcosinus = cos(cube->zrot);
  305.         zsinus = sin(cube->zrot);
  306.  
  307.         for (i = 0; i < 8; ++i)
  308.         {
  309.             x = cube->coords3d[i].x;
  310.             y = cube->coords3d[i].y;
  311.             z = cube->coords3d[i].z;
  312.             
  313.             t = y;
  314.             y = y * xcosinus - z * xsinus;
  315.             z = t * xsinus + z * xcosinus;
  316.     
  317.             t = x;
  318.             x = x * ycosinus + z * ysinus;
  319.             z = z * ycosinus - t * ysinus;
  320.         
  321.             t = x;
  322.             x = x * zcosinus - y * zsinus;
  323.             y = t * zsinus + y * zcosinus;
  324.         
  325.             z = (z + DISTANCE) / zoom;
  326.         
  327.             x /= z;
  328.             y /= z;
  329.         
  330.             cube->coords2d[i].x = x * width/2 + width/2;
  331.             cube->coords2d[i].y = y * width/2 + height/2;
  332.         }
  333.  
  334.  
  335.         //    clear background
  336.         
  337.         DoPictureMethod(bufferpic, PICMTHD_SET, cube->bgcolor, TAG_DONE);
  338.  
  339.  
  340.         //    draw faces
  341.  
  342.         for (i = 0; i < 6; ++i)
  343.         {
  344.             face = &cube->faces[i];
  345.     
  346.             face->edges[0] = cube->coords2d[face->a]; 
  347.             face->edges[1] = cube->coords2d[face->b]; 
  348.             face->edges[2] = cube->coords2d[face->c]; 
  349.             face->edges[3] = cube->coords2d[face->d]; 
  350.  
  351.             //    check visibility
  352.  
  353.             visible =    ((face->edges[1].x - face->edges[0].x) *
  354.                         (face->edges[2].y - face->edges[0].y) -
  355.                         (face->edges[2].x - face->edges[0].x) *
  356.                         (face->edges[1].y - face->edges[0].y)) > 0 ? outside : !outside;
  357.                     
  358.             if (visible)
  359.             {
  360.                 face->visible = TRUE;
  361.  
  362.                 //    draw texture-mapped face
  363.             
  364.                 if (face->mappedtexturepic)
  365.                 {
  366.                     DoPictureMethod(bufferpic, PICMTHD_TEXTURE,
  367.                         face->mappedtexturepic, face->edges, NULL);
  368.                 }
  369.                 else
  370.                 {
  371.                     if (cube->mappeddefaultpic)
  372.                     {
  373.                         DoPictureMethod(bufferpic, PICMTHD_TEXTURE,
  374.                             cube->mappeddefaultpic, face->edges, NULL);
  375.                     }
  376.                 }
  377.             }
  378.             else
  379.             {
  380.                 face->visible = FALSE;
  381.             }
  382.         }
  383.     }
  384. }
  385.  
  386.  
  387.  
  388. /*********************************************************************
  389. ----------------------------------------------------------------------
  390.  
  391.     rotatecube(cube, xstep, ystep, zstep, timescale)
  392.  
  393. ----------------------------------------------------------------------
  394. *********************************************************************/
  395.  
  396. void rotatecube(struct cube *cube, double xstep, double ystep, double zstep, double timescale)
  397. {
  398. //    static double pi2 = 6.283056;
  399.  
  400.     if (cube)
  401.     {
  402.         cube->xrot += xstep * timescale;
  403.         cube->yrot += ystep * timescale;
  404.         cube->zrot += zstep * timescale;
  405.     }
  406. }
  407.  
  408.  
  409. /*********************************************************************
  410. ----------------------------------------------------------------------
  411.  
  412.     setcuberotation(cube, xr, yr, zr)
  413.  
  414. ----------------------------------------------------------------------
  415. *********************************************************************/
  416.  
  417. void setcuberotation(struct cube *cube, double xr, double yr, double zr)
  418. {
  419.     if (cube)
  420.     {
  421.         cube->xrot = xr;
  422.         cube->yrot = yr;
  423.         cube->zrot = zr;
  424.     }
  425. }
  426.  
  427.  
  428. /*********************************************************************
  429. ----------------------------------------------------------------------
  430.  
  431.     is = pointinpoly(x,y, numedges, edges)
  432.  
  433.     check if a point is inside a polygon
  434.  
  435.     by Ken McElvain (slightly modified)
  436.  
  437. ----------------------------------------------------------------------
  438. *********************************************************************/
  439.  
  440. int __inline whichquad(point2d pt, point2d orig)
  441. {
  442.     if(pt.x < orig.x)
  443.     {
  444.         if (pt.y < orig.y)
  445.             return 2;
  446.         else
  447.             return 1;
  448.     }
  449.     else
  450.     {
  451.         if(pt.y < orig.y)
  452.             return 3;
  453.         else
  454.             return 0;
  455.     }
  456. }
  457.  
  458. BOOL pointinpoly(int x, int y, int cnt, point2d *polypts)
  459. {
  460.     int    oldquad, newquad;
  461.     point2d    pt, thispt, lastpt;
  462.     int    a, b, i;
  463.     int    wind = 0;       // current winding number
  464.  
  465.     pt.x = x;
  466.     pt.y = y;
  467.  
  468.     lastpt = polypts[cnt-1];
  469.     oldquad = whichquad(lastpt,pt); /* get starting angle */
  470.     for(i=0;i<cnt;i++) { /* for each point in the polygon */
  471.             thispt = polypts[i];
  472.             newquad = whichquad(thispt,pt);
  473.             if(oldquad!=newquad) { /* adjust wind */
  474.                     /*
  475.                      * use mod 4 comparsions to see if we have
  476.                      * advanced or backed up one quadrant 
  477.                      */
  478.                     if (((oldquad+1)&3)==newquad) wind++;
  479.                     else if (((newquad+1)&3)==oldquad) wind--;
  480.                     else {
  481.                             /*
  482.                              * upper left to lower right, or
  483.                              * upper right to lower left. Determine
  484.                              * direction of winding  by intersection
  485.                              *  with x==0.
  486.                              */
  487.                             a = lastpt.y - thispt.y;
  488.                             a *= (pt.x - lastpt.x);
  489.                             b = lastpt.x - thispt.x;
  490.                             a += lastpt.y * b;
  491.                             b *= pt.y;
  492.     
  493.                             if(a > b) wind += 2;
  494.                             else wind -= 2;
  495.                     }
  496.             }
  497.             lastpt = thispt;
  498.     oldquad = newquad;
  499.     }
  500.  
  501.     return (BOOL) (wind != 0);
  502.  
  503. }
  504.  
  505.  
  506. /*********************************************************************
  507. ----------------------------------------------------------------------
  508.  
  509.     nr = findface(cube, x, y)
  510.  
  511.     find the face that is hit throughout (x|y)
  512.  
  513. ----------------------------------------------------------------------
  514. *********************************************************************/
  515.  
  516. int findface(struct cube *cube, int x, int y)
  517. {
  518.     int facenr = -1;
  519.     struct face *face;
  520.     int i;
  521.  
  522.     if (cube)
  523.     {
  524.         for (i = 0; i < 6; ++i)
  525.         {
  526.             face = &cube->faces[i];
  527.  
  528.             if (face->visible)
  529.             {
  530.                 if (pointinpoly(x,y, 4, face->edges))
  531.                 {
  532.                     facenr = i;
  533.                     break;
  534.                 }
  535.             }
  536.         }
  537.     }
  538.  
  539.     return facenr;
  540. }
  541.  
  542.  
  543. /*********************************************************************
  544. ----------------------------------------------------------------------
  545.  
  546.     releasecube(cube)
  547.  
  548.     release the cube's drawhandle
  549.     and free mapped pictures
  550.  
  551. ----------------------------------------------------------------------
  552. *********************************************************************/
  553.  
  554. void releasecube(struct cube *cube)
  555. {
  556.     if (cube)
  557.     {
  558.         int i;
  559.     
  560.         ReleaseDrawHandle(cube->drawhandle);
  561.         cube->drawhandle = NULL;
  562.         
  563.         for (i = 0; i < 6; ++i)
  564.         {
  565.             DeletePicture(cube->faces[i].mappedtexturepic);
  566.             cube->faces[i].mappedtexturepic = NULL;
  567.         }
  568.  
  569.         DeletePicture(cube->mappeddefaultpic);
  570.         cube->mappeddefaultpic = NULL;
  571.     }
  572. }
  573.  
  574.  
  575.  
  576. /*********************************************************************
  577. ----------------------------------------------------------------------
  578.  
  579.     drawhandle = obtaincube(cube, screen, window)
  580.     
  581.     compose and obtain a drawhandle for the cube
  582.  
  583. ----------------------------------------------------------------------
  584. *********************************************************************/
  585.  
  586. APTR obtaincube(struct cube *cube, struct Screen *scr, struct Window *win)
  587. {
  588.     APTR drawhandle = NULL;
  589.  
  590.     if (cube)
  591.     {
  592.         int i;
  593.  
  594.         //    release old drawhandle and delete mapped pictures
  595.  
  596.         releasecube(cube);
  597.  
  598.         //    obtain new drawhandle
  599.         
  600.         if (drawhandle = cube->drawhandle = ObtainDrawHandle(cube->psm, win->RPort,
  601.             scr->ViewPort.ColorMap, OBP_Precision, PRECISION_IMAGE, TAG_DONE))
  602.         {
  603.             //    map pictures to the new drawhandle
  604.         
  605.             for (i = 0; i < 6; ++i)
  606.             {
  607.                 if (cube->faces[i].mappedtexturepic = ClonePicture(cube->faces[i].texturepic, NULL))
  608.                 {
  609.                     DoPictureMethod(cube->faces[i].mappedtexturepic,
  610.                         PICMTHD_MAPDRAWHANDLE, drawhandle, NULL);
  611.                 }
  612.             }
  613.  
  614.             //    map the default picture to the new drawhandle
  615.  
  616.             cube->mappeddefaultpic = ClonePicture(cube->defaultpic, NULL);
  617.             DoPictureMethod(cube->mappeddefaultpic, PICMTHD_MAPDRAWHANDLE, drawhandle, NULL);
  618.         }
  619.  
  620.     }
  621.  
  622.     return drawhandle;
  623. }
  624.  
  625.  
  626. /*********************************************************************
  627. ----------------------------------------------------------------------
  628.  
  629.     deletecube(cube)
  630.  
  631. ----------------------------------------------------------------------
  632. *********************************************************************/
  633.  
  634. void deletecube(struct cube *cube)
  635. {
  636.     if (cube)
  637.     {
  638.         releasecube(cube);
  639.         DeletePenShareMap(cube->psm);
  640.         free(cube);    
  641.     }
  642. }
  643.  
  644.  
  645. /*********************************************************************
  646. ----------------------------------------------------------------------
  647.  
  648.     createcube(defaulttexture, bgcolor)
  649.  
  650. ----------------------------------------------------------------------
  651. *********************************************************************/
  652.  
  653. struct cube *createcube(PICTURE *defaultpic, ULONG bgcolor)
  654. {
  655.     BOOL success = FALSE;
  656.  
  657.     static point3d coords[8] =
  658.     {
  659.         {-1,-1,1},    {1,-1,1},    {1,1,1},    {-1,1,1},
  660.         {-1,-1,-1}, {1,-1,-1},    {1,1,-1},    {-1,1,-1}
  661.     };
  662.  
  663.     static int faceedges[] =
  664.     {
  665.         2,1,0,3,
  666.         1,2,6,5,
  667.         0,1,5,4,
  668.         7,6,2,3,
  669.         4,5,6,7,
  670.         4,7,3,0
  671.     };
  672.  
  673.     struct cube *cube;
  674.     
  675.     if (cube = malloc(sizeof(struct cube)))
  676.     {
  677.         int i;
  678.  
  679.         memset(cube, 0, sizeof(struct cube));
  680.  
  681.  
  682.         //    init 3d coordinates
  683.         
  684.         for (i = 0; i < 8; ++i)
  685.         {
  686.             cube->coords3d[i] = coords[i];
  687.         }
  688.  
  689.         //    init edge indices
  690.         
  691.         for (i = 0; i < 6; ++i)
  692.         {
  693.             cube->faces[i].a = faceedges[i*4];
  694.             cube->faces[i].b = faceedges[i*4+1];
  695.             cube->faces[i].c = faceedges[i*4+2];
  696.             cube->faces[i].d = faceedges[i*4+3];
  697.         }
  698.  
  699.         cube->xrot = 0;
  700.         cube->yrot = 0;
  701.         cube->zrot = 0;
  702.  
  703.         cube->bgcolor = bgcolor;
  704.         cube->defaultpic = defaultpic;
  705.  
  706.         //    create pen-sharemap
  707.         
  708.         if (cube->psm = CreatePenShareMap(GGFX_HSType, HSTYPE_12BIT_TURBO, TAG_DONE))
  709.         {
  710.             //    add the default picture to the pen-sharemap
  711.         
  712.             if (AddPicture(cube->psm, cube->defaultpic, TAG_DONE))
  713.             {
  714.                 //    add the background color to the pen-sharemap
  715.             
  716.                 if (AddPalette(cube->psm, &cube->bgcolor,
  717.                     GGFX_NumColors, 1, TAG_DONE))
  718.                 {
  719.                     success = TRUE;
  720.                 }
  721.             }
  722.         }
  723.     }
  724.  
  725.     if (!success)
  726.     {
  727.         deletecube(cube);
  728.         cube = NULL;
  729.     }
  730.  
  731.     return cube;
  732. }
  733.  
  734.  
  735.  
  736. /*********************************************************************
  737. ----------------------------------------------------------------------
  738.  
  739.     setcubetexture(cube, facenr, picture)
  740.  
  741.     set a new picture for the specified face
  742.  
  743. ----------------------------------------------------------------------
  744. *********************************************************************/
  745.  
  746. void setcubetexture(struct cube *cube, int nr, PICTURE *pic)
  747. {
  748.     if (cube && (nr >= 0 && nr < 6))
  749.     {
  750.         //    remove the old picture's colorhandle from the cube's pen-sharemap    
  751.  
  752.         RemColorHandle(cube->faces[nr].colorhandle);
  753.         cube->faces[nr].colorhandle = NULL;
  754.  
  755.         //    delete the mapped picture
  756.  
  757.         DeletePicture(cube->faces[nr].mappedtexturepic);
  758.         cube->faces[nr].mappedtexturepic = NULL;
  759.  
  760.         if (pic)
  761.         {
  762.             cube->faces[nr].texturepic = pic;
  763.  
  764.             //    add the new picture to the cube's pen-sharemap
  765.         
  766.             cube->faces[nr].colorhandle = AddPicture(cube->psm, pic, GGFX_Weight, 10, TAG_DONE);
  767.         }
  768.     }
  769. }
  770.  
  771.  
  772. /*********************************************************************
  773. ----------------------------------------------------------------------
  774.  
  775.     makergbpics
  776.     
  777.     calculate faces for an RGB cube
  778.  
  779. ----------------------------------------------------------------------
  780. *********************************************************************/
  781.  
  782. void makergbpics(PICTURE **pics)
  783. {
  784.     int r, g, b;
  785.     ULONG *array;
  786.  
  787.     if (array = malloc(128*128*4))
  788.     {
  789.         DeletePicture(pics[0]);
  790.         pics[0] = NULL;
  791.         for (g = 0; g < 128; ++g)
  792.         {
  793.             for (b = 0; b < 128; ++b)
  794.             {
  795.                 array[b*128+g] = ((127-g) << 9) + ((127-b) << 1);
  796.             }
  797.         }
  798.         pics[0] = MakePicture(array, 128,128, 
  799.             GGFX_PixelFormat, PIXFMT_0RGB_32,
  800.             GGFX_Independent, TRUE, TAG_DONE); 
  801.         free(array);
  802.     }
  803.  
  804.     if (array = malloc(128*128*4))
  805.     {
  806.         DeletePicture(pics[1]);
  807.         pics[1] = NULL;
  808.         for (r = 0; r < 128; ++r)
  809.         {
  810.             for (g = 0; g < 128; ++g)
  811.             {
  812.                 array[r*128+g] = (r << 17) + (g << 9) + 255;
  813.             }
  814.         }
  815.         pics[1] = MakePicture(array, 128,128, 
  816.             GGFX_PixelFormat, PIXFMT_0RGB_32,
  817.             GGFX_Independent, TRUE, TAG_DONE); 
  818.         free(array);
  819.     }
  820.  
  821.     if (array = malloc(128*128*4))
  822.     {
  823.         DeletePicture(pics[2]);
  824.         pics[2] = NULL;
  825.         for (r = 0; r < 128; ++r)
  826.         {
  827.             for (b = 0; b < 128; ++b)
  828.             {
  829.                 array[r*128+b] = (r << 17) + (b << 1);
  830.             }
  831.         }
  832.         pics[2] = MakePicture(array, 128,128, 
  833.             GGFX_PixelFormat, PIXFMT_0RGB_32,
  834.             GGFX_Independent, TRUE, TAG_DONE); 
  835.         free(array);
  836.     }
  837.  
  838.     if (array = malloc(128*128*4))
  839.     {
  840.         DeletePicture(pics[3]);
  841.         pics[3] = NULL;
  842.         for (r = 0; r < 128; ++r)
  843.         {
  844.             for (b = 0; b < 128; ++b)
  845.             {
  846.                 array[(127-r)*128+b] = (r << 17) + (b << 1) + (255<<8);
  847.             }
  848.         }
  849.         pics[3] = MakePicture(array, 128,128, 
  850.             GGFX_PixelFormat, PIXFMT_0RGB_32,
  851.             GGFX_Independent, TRUE, TAG_DONE); 
  852.         free(array);
  853.     }
  854.  
  855.     if (array = malloc(128*128*4))
  856.     {
  857.         DeletePicture(pics[4]);
  858.         pics[4] = NULL;
  859.         for (g = 0; g < 128; ++g)
  860.         {
  861.             for (b = 0; b < 128; ++b)
  862.             {
  863.                 array[g*128+b] = (g << 9) + (b << 1) + (255<<16);
  864.             }
  865.         }
  866.         pics[4] = MakePicture(array, 128,128, 
  867.             GGFX_PixelFormat, PIXFMT_0RGB_32,
  868.             GGFX_Independent, TRUE, TAG_DONE); 
  869.         free(array);
  870.     }
  871.  
  872.     if (array = malloc(128*128*4))
  873.     {
  874.         DeletePicture(pics[5]);
  875.         pics[5] = NULL;
  876.         for (r = 0; r < 128; ++r)
  877.         {
  878.             for (g = 0; g < 128; ++g)
  879.             {
  880.                 array[(127-r)*128+g] = (r << 17) + (g << 9);
  881.             }
  882.         }
  883.         pics[5] = MakePicture(array, 128,128, 
  884.             GGFX_PixelFormat, PIXFMT_0RGB_32,
  885.             GGFX_Independent, TRUE, TAG_DONE); 
  886.         free(array);
  887.     }
  888. }
  889.  
  890.  
  891. /*********************************************************************
  892. ----------------------------------------------------------------------
  893.  
  894.     mysticube
  895.     mainloop
  896.  
  897. ----------------------------------------------------------------------
  898. *********************************************************************/
  899.  
  900. void mysticube(struct mvwindow *win, struct cube *cube)
  901. {
  902.     APTR timehandle = NULL;
  903.     int time;
  904.     char text[30];
  905.     BOOL timer = FALSE;
  906.     BOOL outside = TRUE;
  907.     double zoom = ZOOM;
  908.     
  909.     PICTURE *bufferpic = NULL;
  910.     APTR drawhandle;
  911.     struct AppMessage *appmsg;
  912.     BOOL finish = FALSE;
  913.     ULONG signals;
  914.     struct IntuiMessage *imsg;
  915.     int i;
  916.  
  917.     double xstep = YROT, ystep = XROT;
  918.     WORD startmx = 0, startmy = 0;
  919.     BOOL mousebutton = FALSE;
  920.     
  921.  
  922.     PICTURE *picture[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
  923.  
  924.  
  925.     SetABPenDrMd(win->window->RPort, 1,2, JAM2);
  926.  
  927.  
  928.     drawhandle = obtaincube(cube, win->screen, win->window);
  929.  
  930.  
  931.     do
  932.     {
  933.         //    allocate draw buffer
  934.     
  935.         if (!bufferpic && drawhandle)
  936.         {
  937.             UpdateWindowParameters(win);
  938.             if (bufferpic = MakePicture(NULL, win->innerwidth, win->innerheight, NULL))
  939.             {
  940.                 //    map the draw buffer to the current drawhandle
  941.             
  942.                 DoPictureMethod(bufferpic, PICMTHD_MAPDRAWHANDLE, drawhandle, NULL);
  943.             }
  944.  
  945.             RefreshWindowFrame(win->window);
  946.         }
  947.  
  948.  
  949.         //    get signals
  950.     
  951.         signals = SetSignal(0, win->idcmpSignal | win->appSignal);
  952.  
  953.  
  954.         //    IDCMP message loop
  955.  
  956.         if (signals & win->idcmpSignal)
  957.         {
  958.             while (imsg = (struct IntuiMessage *) GetMsg(win->window->UserPort))
  959.             {
  960.                 ULONG iclass = imsg->Class;
  961.                 ULONG icode = imsg->Code;
  962.                 WORD mx = imsg->MouseX, my = imsg->MouseY;
  963.         
  964.                 ReplyMsg((struct Message *) imsg);
  965.         
  966.                 switch (iclass)
  967.                 {
  968.                     case MOUSEMOVE:
  969.                         if (mousebutton)
  970.                         {
  971.                             xstep = (double)(mx-startmx) / (double) 100;
  972.                             ystep = (double)(my-startmy) / (double) 100;
  973.                             startmx = mx;
  974.                             startmy = my;
  975.                         }
  976.                         break;
  977.                     
  978.                     case MOUSEBUTTONS:
  979.                         switch (icode)
  980.                         {
  981.                             case SELECTUP:
  982.                                 ModifyIDCMP(win->window, win->idcmp);
  983.                                 mousebutton = FALSE;
  984.                                 xstep /= 2;
  985.                                 ystep /= 2;
  986.                                 break;
  987.     
  988.                             case SELECTDOWN:
  989.                                 ModifyIDCMP(win->window, win->idcmp | IDCMP_MOUSEMOVE);
  990.                                 mousebutton = TRUE;
  991.                                 startmx = mx;
  992.                                 startmy = my;
  993.                                 xstep = 0;
  994.                                 ystep = 0;
  995.                                 setcuberotation(cube,0,0,0);
  996.                                 break;
  997.                         }
  998.                         break;
  999.                 
  1000.                     case CLOSEWINDOW:
  1001.                         finish = TRUE;
  1002.                         break;
  1003.         
  1004.                     case NEWSIZE:
  1005.                         if ((win->window->Width != win->winwidth) ||
  1006.                             (win->window->Height != win->winheight))
  1007.                         {
  1008.                             DeletePicture(bufferpic);
  1009.                             bufferpic = NULL;
  1010.                         }
  1011.                         break;
  1012.  
  1013.                     case VANILLAKEY:
  1014.                         switch (icode)
  1015.                         {
  1016.                             case 27:
  1017.                                 finish = TRUE;
  1018.                                 break;
  1019.                             case 't':
  1020.                                 timer = timer ? FALSE : TRUE;
  1021.                                 break;
  1022.  
  1023.                             case 'i':
  1024.                                 outside = !outside;
  1025.                                 break;
  1026.  
  1027.                             case '+':
  1028.                                 zoom += .01;
  1029.                                 break;
  1030.  
  1031.                             case '-':
  1032.                                 zoom -= .01;
  1033.                                 break;
  1034.  
  1035.                             case 'r':
  1036.                             {
  1037.                                 makergbpics(picture);
  1038.  
  1039.                                 setcubetexture(cube, 0, picture[0]);
  1040.                                 setcubetexture(cube, 1, picture[1]);
  1041.                                 setcubetexture(cube, 2, picture[2]);
  1042.                                 setcubetexture(cube, 3, picture[3]);
  1043.                                 setcubetexture(cube, 4, picture[4]);
  1044.                                 setcubetexture(cube, 5, picture[5]);
  1045.         
  1046.                                 RectFill(win->window->RPort, win->innerleft, win->innertop, win->innerleft + win->innerwidth - 1, win->innertop + win->innerheight - 1);
  1047.                                 drawhandle = obtaincube(cube, win->screen, win->window);
  1048.                                 DeletePicture(bufferpic);
  1049.                                 bufferpic = NULL;
  1050.                                 if (timehandle) timerstop(timehandle);
  1051.                                 timehandle = NULL;
  1052.                                 break;
  1053.                             }
  1054.                         }
  1055.                 }
  1056.         
  1057.             }
  1058.         }
  1059.  
  1060.  
  1061.         //    check for pictures being dropped onto the main window
  1062.  
  1063.         if (signals & win->appSignal)
  1064.         {
  1065.             int x = -1, y = -1;
  1066.  
  1067.             while (appmsg = (struct AppMessage *) GetMsg(win->appmsgport))
  1068.             {
  1069.                 struct WBArg *argptr = appmsg->am_ArgList;
  1070.                 BOOL foundpic = FALSE;
  1071.                 char pathname[MAXPATHNAMELEN];
  1072.                 char filename[MAXFILENAMELEN];
  1073.         
  1074.                 for (i = 0; i < appmsg->am_NumArgs && foundpic == FALSE; i++)
  1075.                 {
  1076.                     if (NameFromLock(argptr->wa_Lock, pathname, MAXPATHNAMELEN))
  1077.                     {
  1078.                         if(strlen(argptr->wa_Name))
  1079.                         {
  1080.                             strncpy(filename, argptr->wa_Name, MAXFILENAMELEN);
  1081.                             foundpic = TRUE;
  1082.                             UpdateWindowParameters(win);
  1083.                             x = appmsg->am_MouseX - win->innerleft;
  1084.                             y = appmsg->am_MouseY - win->innertop;
  1085.                         }
  1086.                     }
  1087.                     argptr++;        // next argument
  1088.                 }
  1089.                 ReplyMsg((struct Message *) appmsg);
  1090.     
  1091.                 if (foundpic)
  1092.                 {
  1093.                     //    get the surface number that has been hit
  1094.                 
  1095.                     int nr = findface(cube, x, y);
  1096.                 
  1097.                     if (nr >= 0)
  1098.                     {
  1099.                         char fullname[MAXFILENAMELEN+MAXPATHNAMELEN];
  1100.                         PICTURE *newpic;
  1101.         
  1102.                         strcpy(fullname, pathname);
  1103.                         AddPart(fullname, filename, MAXFILENAMELEN+MAXPATHNAMELEN);
  1104.  
  1105.                         //    load and set new picture
  1106.         
  1107.                         if (newpic = LoadPicture(fullname, NULL))
  1108.                         {
  1109.                             DeletePicture(picture[nr]);
  1110.                             picture[nr] = newpic;
  1111.                             DoPictureMethod(picture[nr], PICMTHD_SCALE, 128, 128, NULL);
  1112.                             setcubetexture(cube, nr, picture[nr]);
  1113.                             RectFill(win->window->RPort, win->innerleft, win->innertop, win->innerleft + win->innerwidth - 1, win->innertop + win->innerheight - 1);
  1114.                             drawhandle = obtaincube(cube, win->screen, win->window);
  1115.                             DeletePicture(bufferpic);
  1116.                             bufferpic = NULL;
  1117.                             if (timehandle) timerstop(timehandle);
  1118.                             timehandle = NULL;
  1119.                         }
  1120.                     }
  1121.                 }
  1122.             }
  1123.         }
  1124.  
  1125.         //    get 1/1000 seconds since last frame
  1126.  
  1127.         if (timehandle)
  1128.         {
  1129.             time = timerstop(timehandle);
  1130.         }
  1131.         else
  1132.         {
  1133.             time = 0;
  1134.         }
  1135.  
  1136.  
  1137.         //    rotate cube
  1138.  
  1139.         if (mousebutton)
  1140.         {        
  1141.             rotatecube(cube, ystep, -xstep, 0, (double) time / 20);
  1142.         }
  1143.         else
  1144.         {
  1145.             rotatecube(cube, ystep, -xstep, ZROT, (double) time / 20);
  1146.         }
  1147.  
  1148.  
  1149.         //    start timer
  1150.  
  1151.         timehandle = timerstart();
  1152.  
  1153.  
  1154.         //    draw cube
  1155.  
  1156.         if (bufferpic)
  1157.         {
  1158.             docube(cube, zoom, bufferpic, win->innerwidth, win->innerheight, outside);
  1159.             DrawPicture(drawhandle, bufferpic, win->innerleft, win->innertop, NULL);
  1160.  
  1161.             if (timer)
  1162.             {
  1163.                 //    display frames per second
  1164.     
  1165.                 Move(win->window->RPort, win->innerleft, 
  1166.                     win->innertop + win->innerheight - win->window->RPort->TxHeight + win->window->RPort->TxBaseline);
  1167.                 sprintf(text, "fps: %ld", (ULONG) ((double) 1000 / (double) time));
  1168.                 Text(win->window->RPort, text, strlen(text));
  1169.             }
  1170.         }
  1171.  
  1172.  
  1173.     } while (finish == FALSE);
  1174.  
  1175.  
  1176.     //    free pictures
  1177.  
  1178.     for (i = 0; i < 6; ++i)
  1179.     {
  1180.         DeletePicture(picture[i]);
  1181.     }
  1182.  
  1183.     //    free cube
  1184.  
  1185.     DeletePicture(bufferpic);
  1186.     releasecube(cube);
  1187. }
  1188.  
  1189.  
  1190.  
  1191. /*********************************************************************
  1192. ----------------------------------------------------------------------
  1193.  
  1194.     main
  1195.  
  1196. ----------------------------------------------------------------------
  1197. *********************************************************************/
  1198.  
  1199. ULONG main (int argc, char **argv)
  1200. {
  1201.     ULONG result;
  1202.  
  1203.     if(InitGlobal())
  1204.     {
  1205.         struct mvwindow *window;
  1206.         struct Screen *defscreen;
  1207.         struct cube *cube;
  1208.         PICTURE *logopic;
  1209.  
  1210.         if (defscreen = LockPubScreen(NULL))
  1211.         {
  1212.             if (window = CreateMVWindow(defscreen))
  1213.             {
  1214.                 if (logopic = MakePicture(MysticLogo, LOGOWIDTH, LOGOHEIGHT,
  1215.                     GGFX_Palette, MysticLogoPalette,
  1216.                     GGFX_NumColors, LOGONUMCOLORS, TAG_DONE))
  1217.                 {
  1218.                     if (cube = createcube(logopic, BGCOLOR))
  1219.                     {
  1220.                         SetTaskPri(FindTask(NULL), TASKPRIO);
  1221.                         mysticube(window, cube);
  1222.                         deletecube(cube);
  1223.                         result = 0;
  1224.                     }
  1225.                     else
  1226.                     {
  1227.                         printf("*** out of memory\n");
  1228.                         result = 20;
  1229.                     }
  1230.                     
  1231.                     DeletePicture(logopic);
  1232.                 }
  1233.                 else
  1234.                 {
  1235.                     printf("*** out of memory\n");
  1236.                     result = 20;
  1237.                 }
  1238.  
  1239.                 DeleteMVWindow(window);
  1240.             }
  1241.             else
  1242.             {
  1243.                 printf("*** window could not be opened\n");
  1244.                 result = 20;
  1245.             }
  1246.  
  1247.             UnlockPubScreen(NULL, defscreen);
  1248.         }
  1249.         else
  1250.         {
  1251.             printf("*** pubscreen could not be locked\n");
  1252.             result = 20;
  1253.         }
  1254.         
  1255.         CloseGlobal();
  1256.     }
  1257.     else
  1258.     {
  1259.         printf("*** global initialization failed\n");
  1260.         result = 20;
  1261.     }
  1262.     
  1263.     return result;
  1264. }
  1265.