home *** CD-ROM | disk | FTP | other *** search
/ The Best of Mecomp Multimedia 2 / MECOMP-CD-II.iso / amiga / tools / libs / graphics3d / src / library / graphics3d2d.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-13  |  13.1 KB  |  523 lines

  1. /*
  2. **      $VER: graphics3D2d.c 10.01 (01.11.97)
  3. **
  4. **      External functions for graphics3D.library
  5. **    
  6. **      (C) Copyright 97 Patrizio Biancalani
  7. **      All Rights Reserved.
  8. */
  9.  
  10. #include <exec/types.h>
  11. #include <exec/memory.h>
  12. #include <proto/exec.h>
  13. #include <proto/intuition.h>
  14. #include <intuition/intuition.h>
  15. #include <intuition/screens.h>
  16.  
  17. #include <graphics/rastport.h>
  18. #include <graphics/clip.h>
  19. #include <graphics/regions.h>
  20. #include <graphics/gfx.h>
  21. #include <graphics/gfxmacros.h>
  22. #include <graphics/layers.h>
  23.  
  24. #include "graphics3Dc.h"
  25. #include "graphics3D.h"
  26. #include "graphics3D2d_proto.h"
  27.  
  28.  /* Please note, that &Graphics3DBase always resides in register __a6 
  29.     as well, but if we don't need it, we need not reference it here.
  30.  
  31.     Also note, that registers a0, a1, d0, d1 always are scratch registers,
  32.     so you usually should only *pass* parameters there, but make a copy
  33.     directly after entering the function. To avoid problems of kind
  34.     "implementation defined behaviour", you should make a copy of A6 too,
  35.     when it is actually used.
  36.  
  37.     In this example case, scratch register saving would not have been 
  38.     necessary (since there are no other function calls inbetween), but we 
  39.     did it nevertheless.
  40.   */
  41.  
  42. /************ prototipi solo locali ******/
  43. struct RastPort *InitNBuff(struct grafica *graf,struct Screen *screen,
  44.        struct Window *window);
  45.  
  46. void FreeNBuff(struct grafica *graf,
  47.     struct Screen *screen, struct RastPort *rp);
  48.  
  49. /************ macro solo locali *******/
  50. #define SMARG  16 
  51. #define SMARGM 8
  52. #define LTMP 1000
  53. #define ATMP 1000
  54.  
  55. /**********************************************************/
  56.  
  57. /****************************************************
  58.  ** Routin per la gestione della grafica, in stile **
  59.  ** 2.0                                            ** 
  60.  ** (c) 1994 BIANCA HARD&SOFT Vers:1.00            **
  61.  ****************************************************/
  62.  
  63. /********* FUNZIONI 2D ********************************/
  64.  
  65. /***********************************
  66.  ** INIZIALIZZO STRUTTURE PER USO **
  67.  ** CON ROUTIN DI AREA FILL       **
  68.  ***********************************
  69.  **** INPUT :              **
  70.  ** win -> puntatore a finestra   **
  71.  **        su cui lavorare.       **
  72.  ** mxv -> n# massimo vertici da  **
  73.  **        usare.          **
  74.  **** OUTPUT :                    **
  75.  ** ris >0  - tutto ok.           **
  76.  ** ris =<0 - errore, ini.fallita.**
  77.  ***********************************/
  78. struct grafica *ini_g(REG(a0)struct Window *win,REG(d0)long int mxv)
  79. {
  80. struct grafica *ris;
  81. struct Screen *scr;
  82. struct RastPort *rw;
  83. struct RastPort *r;
  84. struct Layer *la;
  85. long int i;
  86.  
  87. ris=(struct grafica *)AllocMem(sizeof(Sgrafica),NULL);
  88. if (ris==NULL) return (0);
  89.  
  90. ris->vpor=0;
  91. ris->rast=0;
  92. ris->rast1=0;
  93. ris->rast2=0;
  94. ris->fdouble=1;
  95. ris->b_af=0;
  96. ris->pras=0;
  97.  
  98. /** default si single buffer **/
  99. ris->clipx=0;
  100. ris->clipy=0;
  101. ris->clipdx=0;
  102. ris->clipdy=0;
  103. ris->NB_rinfo=0;       
  104. ris->NB_bmap=0;        
  105. ris->NB_layerinfo=0;   
  106. ris->NB_layer=0;       
  107.  
  108. /* se per buffer richiesto meno di 1 vertice e' meglio evitare */
  109. if (mxv<=1) {
  110.     close_g(ris);
  111.     return(0);
  112.     }
  113. /* faccio in modo di allineare alle words la dimensione dell'area */
  114. i=mxv;
  115. if (((mxv>>1)<<1)!=mxv) i++;
  116. ris->b_af=AllocMem(MAXVER(i),NULL);
  117. if (ris->b_af==NULL) {
  118.     close_g(ris);
  119.     return(0);    
  120.     }
  121. ris->lb_af=i;
  122.         
  123. rw=win->RPort;
  124. scr=win->WScreen;
  125. ris->vpor=&(scr->ViewPort);
  126. la=win->WLayer;
  127. ris->wind=win;
  128. ris->larg=LTMP;
  129. ris->alte=ATMP;
  130.  
  131. r=InitNBuff(ris,scr,win);
  132. if ((long int)r==NULL) {
  133.     close_g(ris);
  134.     return(0);
  135.     }
  136. ris->rast1=rw;
  137. ris->rast2=r;
  138. ris->rast=r;
  139. ris->o_ai=r->AreaInfo;
  140. ris->o_tr=r->TmpRas;
  141.  
  142. InitArea(&ris->n_ai,ris->b_af,mxv);
  143. r->AreaInfo=&ris->n_ai;
  144.  
  145. ris->pras=(char *)AllocRaster(ris->larg,ris->alte);
  146. if (ris->pras==NULL) {
  147.     close_g(ris);
  148.     return (0);
  149.     }
  150.  
  151. InitTmpRas(&ris->n_tr,ris->pras,RASSIZE(ris->larg,ris->alte));
  152.  
  153. r->TmpRas=&ris->n_tr;
  154.  
  155. return(ris);
  156. }
  157.  
  158. /***********************************
  159.  ** CHIUDO TUTTE LE STRUTTURE     **
  160.  ** APERTE CON LA FUNZIONE PRECE- **
  161.  ** DENTE.                        **
  162.  ***********************************
  163.  **** INPUT :                     **
  164.  ** graf -> valore >0 ritornato   **
  165.  **         dalla funzione d'ini- **
  166.  **         zializzazione         **
  167.  ***********************************/
  168. void close_g(REG(a0)struct grafica *graf)
  169. {
  170. struct RastPort *r;
  171. struct Layer *la;
  172. long int c;
  173.  
  174. if ((long int)graf != NULL)
  175.     {
  176.     la=graf->wind->WLayer;
  177.     if (graf->fdouble!=NULL) la=graf->NB_layer;
  178.     if (la->ClipRegion!=NULL)
  179.         {
  180.         c=InstallClipRegion(la,NULL);
  181.         DisposeRegion(c);
  182.         }
  183.     r=graf->rast;
  184.     if ((long int)r > NULL)
  185.         {
  186.         r->AreaInfo=graf->o_ai;
  187.         r->TmpRas=graf->o_tr;
  188.         }
  189.     if (graf->b_af!=NULL) FreeMem(graf->b_af,MAXVER(graf->lb_af));
  190.     if (graf->pras!=NULL) FreeRaster(graf->pras,graf->larg,graf->alte);
  191.     if (graf->fdouble!=NULL) FreeNBuff(graf,graf->wind->WScreen,
  192.                  graf->rast2);
  193.     FreeMem(graf,sizeof(Sgrafica));
  194.     }
  195. }
  196.  
  197. /************************************
  198.  ** FUNZIONE PER VISUALIZZARE LA   **
  199.  ** RASTPORT NASCOSTA SULLA        **
  200.  ** FINESTRA.               **
  201.  ************************************
  202.  **** INPUT :               **
  203.  ** graf -> valore >0 ritornato    **
  204.  **         dalla funzione d'ini-  **
  205.  **         zializzazione.         **
  206.  **** OUTPUT:               **
  207.  ************************************/
  208. void switch_rp(graf)
  209. REG(a0)struct grafica *graf;
  210. {
  211.  
  212. ClipBlit(graf->rast2,graf->clipx,graf->clipy,graf->rast1,graf->clipx,
  213.     graf->clipy,graf->clipdx,graf->clipdy,0xc0);
  214. /** 
  215. con questa e' un po' piu' rapido ma puo' risultare piu' instabile 
  216. (forse)
  217. **/
  218. /*
  219. BltBitMap(graf->rast2->BitMap,graf->clipx,graf->clipy,graf->rast1->BitMap,
  220.       graf->wind->LeftEdge+graf->clipx,graf->wind->TopEdge+graf->clipy,
  221.       graf->clipdx,graf->clipdy,0xC0,0xFF,0);
  222. */
  223.  
  224. WaitBlit();
  225.  
  226. }
  227.  
  228. /************************************
  229.  ** FUNZIONE PER DEFINIRE UN BOX   **
  230.  ** DI CLIP SULLA FINESTRA         **
  231.  ************************************
  232.  **** INPUT :               **
  233.  ** graf -> valore >0 ritornato    **
  234.  **         dalla funzione d'ini-  **
  235.  **         zializzazione.         **
  236.  ** minx - valore minimo x box.    **
  237.  ** miny - valore minimo y box.    **
  238.  ** dx - larghezza box.           **
  239.  ** dy - altezza box.           **
  240.  **** OUTPUT:               **
  241.  ** > 0 tutto ok.           ** 
  242.  ** = 0 errore.               **
  243.  **** NOTA:               **
  244.  ** elimina eventuali clip region  **
  245.  ** preesistenti.              **
  246.  ************************************/
  247. long int clipbox(REG(a0)struct grafica *graf,REG(d0)long int minx,
  248.            REG(d1)long int miny,REG(d2)long int dx,REG(d3)long int dy)
  249. {
  250. struct Layer *la;
  251. struct Region *clipr;
  252. struct Rectangle rect;
  253. struct ClipRect *clrt;
  254. long int esi;
  255. long int i;
  256.  
  257. #ifdef DEBUG
  258. char dbg[80];
  259. #endif
  260.  
  261. graf->clipx=minx;
  262. graf->clipy=miny;
  263. graf->clipdx=dx;
  264. graf->clipdy=dy;
  265.  
  266. #ifdef DEBUG
  267. sprintf(dbg,"mx=%ld my=%ld dx=%ld dy=%ld \n",minx,miny,dx,dy);
  268. write_dbg(dbg);
  269. #endif
  270.  
  271. la=graf->wind->WLayer;
  272. if (graf->fdouble) la=graf->NB_layer;
  273.  
  274. /*
  275. if (minx==0 AND miny==0 AND dx==0 AND dy==0)
  276.     {
  277.     if (graf->fdouble)
  278.         {
  279.         }
  280.     else
  281.         {
  282.         clipr=(struct Region *)InstallClipRegion(la,NULL);
  283.         if (clipr) DisposeRegion(clipr);
  284.         return (0);
  285.         }
  286.     }
  287. if (graf->fdouble==NULL)
  288.     {
  289.     wn=graf->wind;
  290.     la=wn->WLayer;
  291.     }
  292. */
  293.  
  294. /** elimino eventuali clipregion preesistenti **/
  295. clipr=(struct Region *)InstallClipRegion(la,NULL);
  296. if (clipr) DisposeRegion(clipr);
  297.  
  298. /** inizializzo una nuova clip region vuota **/
  299. clipr=(struct Region *)NewRegion();
  300. if (clipr==NULL) return (0);
  301.  
  302. rect.MinX=0;
  303. rect.MinY=0;
  304. if(graf->fdouble==NULL) 
  305.     {
  306.     rect.MinX=graf->clipx;
  307.     rect.MinY=graf->clipy;
  308.     }
  309. rect.MaxX=graf->clipdx;
  310. rect.MaxY=graf->clipdy;
  311.  
  312. OrRectRegion(clipr,&rect);
  313. InstallClipRegion(la,clipr);
  314.     
  315. return (1);
  316. }
  317.  
  318. /************************************
  319.  ** FUNZIONE PER VISUALIZZARE UN   **
  320.  ** POLIGONO MA SOLO NEI CONTORNI. **
  321.  ************************************
  322.  **** INPUT :               **
  323.  ** graf -> valore >0 ritornato da **
  324.  **         ini_g().               **
  325.  ** nvert-> n# di vertici poligono.**
  326.  ** pvert-> puntatore ad array di  **
  327.  **         int con elenco vertici **
  328.  **** OUTPUT:               **
  329.  ** nessuno.               **
  330.  ************************************/
  331. void polw(REG(a0)struct grafica *graf,REG(d0)long int nvert,
  332.         REG(a1)short int *pvert)
  333. {
  334. if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0); 
  335.  
  336. Move(graf->rast,pvert[0],pvert[1]);
  337. PolyDraw(graf->rast,nvert+1,pvert);
  338. }
  339.  
  340.  
  341. /************************************
  342.  ** FUNZIONE PER VISUALIZZARE POL. **
  343.  ** PIENO               **
  344.  ************************************
  345.  **** INPUT :               **
  346.  ** graf -> valore >0 ritornato da **
  347.  **         ini_g().               **
  348.  ** nvert-> n# di vertici poligono.**
  349.  ** pvert-> puntatore ad array di  **
  350.  **         int con elenco vertici **
  351.  **** OUTPUT:               **
  352.  ** nessuno.               **
  353.  ************************************/
  354. void polf(REG(a0)struct grafica *graf,REG(d0)long int nvert,
  355.         REG(a1)short int *pvert)
  356. {
  357. long int i,np;
  358.  
  359. if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0); 
  360.  
  361. np=nvert<<1;
  362. AreaMove(graf->rast,pvert[0],pvert[1]);
  363.  
  364. for (i=2 ;i<np ;i=i+2) AreaDraw(graf->rast,pvert[i],pvert[i+1]);
  365.  
  366. AreaEnd(graf->rast);
  367.  
  368. }
  369.  
  370. /************************************
  371.  ** FUNZIONE PER VISUALIZZARE POL. **
  372.  ** PIENO CON BORDO           **
  373.  ************************************
  374.  **** INPUT :               **
  375.  ** graf -> valore >0 ritornato da **
  376.  **         ini_g().               **
  377.  ** nvert-> n# di vertici poligono.**
  378.  ** pvert-> puntatore ad array di  **
  379.  **         int con elenco vertici **
  380.  ** colb -> colore da assegnare al **
  381.  **         bordo.           **
  382.  **** OUTPUT:               **
  383.  ** nessuno.               **
  384.  ************************************/
  385. void polwf(REG(a0)struct grafica *graf,REG(d0)long int nvert,
  386.     REG(a1)short int *pvert,REG(d1)long int colb)
  387. {
  388. long int i,np,x0,y0;
  389.  
  390. if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0); 
  391.  
  392. x0=pvert[0];
  393. y0=pvert[1];
  394.  
  395. SetOutlinePen(graf->rast,colb);
  396.  
  397. np=nvert<<1;
  398. AreaMove(graf->rast,x0,y0);
  399.  
  400. for(i=2; i<np; i=i+2) AreaDraw(graf->rast,pvert[i],pvert[i+1]);
  401.  
  402. AreaEnd(graf->rast);
  403.  
  404. }
  405.  
  406. /*************************************
  407.  ** FUNZIONE PER CANCELLARE UN BOX  **
  408.  ** NELLA FINESTRA .            **
  409.  *************************************
  410.  **** INPUT :                       **
  411.  ** graf -> valore >0 ritornato da  **
  412.  **         ini_g().                **
  413.  ** x0   -> coord. x punto in alto  **
  414.  **         a sinistra box.         **
  415.  ** y0   -> coord. y punto in alto  **
  416.  **         a sinistra box.         **
  417.  ** x1   -> coord. x punto in basso **
  418.  **         a destra box.        **
  419.  ** y1   -> coord. y punto in basso **
  420.  **        a destra box.        **
  421.  **** NOTA :                **
  422.  ** usa il colore dello sfondo, e   **
  423.  ** non influenza le altre funzioni **
  424.  *************************************/
  425. void cls_b(REG(a0)struct grafica *graf,REG(d0)long int x0,
  426.     REG(d1)long int y0,REG(d2)long int x1,REG(d3)long int y1)
  427. {
  428. if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0); 
  429.  
  430. EraseRect(graf->rast,x0,y0,x1,y1);
  431. }
  432.  
  433. /*************************************
  434.  ** FUNZIONE PER CAMBIARE IL MODO   **
  435.  ** VIDEO DI TRACCIAMENTO.          **
  436.  *************************************
  437.  **** INPUT :                       **
  438.  ** graf -> valore >0 ritornato da  **
  439.  **         ini_g().                **
  440.  ** mod  -> nuovo modo video.       **
  441.  **** NOTA :                **
  442.  ** valori per mod :            **
  443.  ** 0 > JAM1 (over 2)            **
  444.  ** 1 > JAM2 (over 0) (def.)        **
  445.  ** 2 > COMPLEMENT (over 1)         **
  446.  ** 4 > INVERSVID  (inverse 1)      **
  447.  *************************************/
  448. void over(REG(a0)struct grafica *graf,REG(d0)long int mod)
  449. {
  450. if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0); 
  451.  
  452. SetDrMd(graf->rast,mod);
  453. }
  454.  
  455. /********* ROUTIN INTERNE PER PSEUDO DOUBLE BUFFERING ***************/
  456. /*********************************************
  457.  ** INIZIALIZZO NUOVA RASTPORT PER USARLA   **
  458.  ** COME AREA DI RENDERING NASCOSTA.        **
  459.  *********************************************
  460.  **** INPUT :                    **
  461.  **** OUTPUT:                    **
  462.  ** se > 0 allora puntatore a nuova rastport**
  463.  *********************************************
  464.  ** nota: inizializzo una bitmap uguale     **
  465.  ** alla finestra usata per visualizzare la **
  466.  ** scena effettivamente.                **
  467.  *********************************************/
  468. struct RastPort *InitNBuff(struct grafica *graf,struct Screen *screen,
  469.           struct Window *window)
  470. {
  471. struct RastPort *rport = NULL;  
  472. struct Window *win;
  473. short int err = 0;
  474. unsigned char depth;
  475.  
  476. win=graf->wind;
  477. depth=screen->BitMap.Depth;
  478.  
  479. if (!(graf->NB_layerinfo = (struct Layer_Info *)NewLayerInfo())) 
  480.     return (NULL);
  481.  
  482. if (!(graf->NB_bmap =(struct BitMap *)AllocBitMap(win->Width+SMARG,
  483.     win->Height+SMARG,depth,BMF_CLEAR|BMF_DISPLAYABLE,
  484.     graf->rast1->BitMap))) {
  485.    err = 3;
  486.    goto NBInit_done;
  487.    }
  488.  
  489. if (!(graf->NB_layer = (struct Layer *)CreateBehindLayer(graf->NB_layerinfo,
  490.         graf->NB_bmap,SMARGM,SMARGM, window->Width-1, window->Height-1,
  491.         LAYERSIMPLE|LAYERBACKDROP, NULL))) {
  492.    err = 4;
  493.    goto NBInit_done;
  494.    }
  495. rport = graf->NB_layer->rp;
  496.  
  497. SetRast(rport, 0);   
  498.  
  499. NBInit_done:
  500. if (err) FreeNBuff(graf,screen, rport);
  501. return (rport);
  502. }
  503.  
  504. void FreeNBuff(struct grafica *graf,struct Screen *screen, 
  505.     struct RastPort *rp)
  506. {
  507. unsigned char depth;
  508.  
  509. depth=screen->BitMap.Depth;
  510.  
  511. if (graf->NB_layer) DeleteLayer(0L, graf->NB_layer);
  512. if (graf->NB_layerinfo) DisposeLayerInfo(graf->NB_layerinfo);
  513.  
  514. if (graf->NB_bmap) 
  515.     {
  516.     WaitBlit();
  517.     FreeBitMap(graf->NB_bmap);  
  518.     }
  519. }
  520.  
  521. /***********************************************************/
  522.  
  523.