home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $VER: graphics3D2d.c 10.01 (01.11.97)
- **
- ** External functions for graphics3D.library
- **
- ** (C) Copyright 97 Patrizio Biancalani
- ** All Rights Reserved.
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <proto/exec.h>
- #include <proto/intuition.h>
- #include <intuition/intuition.h>
- #include <intuition/screens.h>
-
- #include <graphics/rastport.h>
- #include <graphics/clip.h>
- #include <graphics/regions.h>
- #include <graphics/gfx.h>
- #include <graphics/gfxmacros.h>
- #include <graphics/layers.h>
-
- #include "graphics3Dc.h"
- #include "graphics3D.h"
- #include "graphics3D2d_proto.h"
-
- /* Please note, that &Graphics3DBase always resides in register __a6
- as well, but if we don't need it, we need not reference it here.
-
- Also note, that registers a0, a1, d0, d1 always are scratch registers,
- so you usually should only *pass* parameters there, but make a copy
- directly after entering the function. To avoid problems of kind
- "implementation defined behaviour", you should make a copy of A6 too,
- when it is actually used.
-
- In this example case, scratch register saving would not have been
- necessary (since there are no other function calls inbetween), but we
- did it nevertheless.
- */
-
- /************ prototipi solo locali ******/
- struct RastPort *InitNBuff(struct grafica *graf,struct Screen *screen,
- struct Window *window);
-
- void FreeNBuff(struct grafica *graf,
- struct Screen *screen, struct RastPort *rp);
-
- /************ macro solo locali *******/
- #define SMARG 16
- #define SMARGM 8
- #define LTMP 1000
- #define ATMP 1000
-
- /**********************************************************/
-
- /****************************************************
- ** Routin per la gestione della grafica, in stile **
- ** 2.0 **
- ** (c) 1994 BIANCA HARD&SOFT Vers:1.00 **
- ****************************************************/
-
- /********* FUNZIONI 2D ********************************/
-
- /***********************************
- ** INIZIALIZZO STRUTTURE PER USO **
- ** CON ROUTIN DI AREA FILL **
- ***********************************
- **** INPUT : **
- ** win -> puntatore a finestra **
- ** su cui lavorare. **
- ** mxv -> n# massimo vertici da **
- ** usare. **
- **** OUTPUT : **
- ** ris >0 - tutto ok. **
- ** ris =<0 - errore, ini.fallita.**
- ***********************************/
- struct grafica *ini_g(REG(a0)struct Window *win,REG(d0)long int mxv)
- {
- struct grafica *ris;
- struct Screen *scr;
- struct RastPort *rw;
- struct RastPort *r;
- struct Layer *la;
- long int i;
-
- ris=(struct grafica *)AllocMem(sizeof(Sgrafica),NULL);
- if (ris==NULL) return (0);
-
- ris->vpor=0;
- ris->rast=0;
- ris->rast1=0;
- ris->rast2=0;
- ris->fdouble=1;
- ris->b_af=0;
- ris->pras=0;
-
- /** default si single buffer **/
- ris->clipx=0;
- ris->clipy=0;
- ris->clipdx=0;
- ris->clipdy=0;
- ris->NB_rinfo=0;
- ris->NB_bmap=0;
- ris->NB_layerinfo=0;
- ris->NB_layer=0;
-
- /* se per buffer richiesto meno di 1 vertice e' meglio evitare */
- if (mxv<=1) {
- close_g(ris);
- return(0);
- }
- /* faccio in modo di allineare alle words la dimensione dell'area */
- i=mxv;
- if (((mxv>>1)<<1)!=mxv) i++;
- ris->b_af=AllocMem(MAXVER(i),NULL);
- if (ris->b_af==NULL) {
- close_g(ris);
- return(0);
- }
- ris->lb_af=i;
-
- rw=win->RPort;
- scr=win->WScreen;
- ris->vpor=&(scr->ViewPort);
- la=win->WLayer;
- ris->wind=win;
- ris->larg=LTMP;
- ris->alte=ATMP;
-
- r=InitNBuff(ris,scr,win);
- if ((long int)r==NULL) {
- close_g(ris);
- return(0);
- }
- ris->rast1=rw;
- ris->rast2=r;
- ris->rast=r;
- ris->o_ai=r->AreaInfo;
- ris->o_tr=r->TmpRas;
-
- InitArea(&ris->n_ai,ris->b_af,mxv);
- r->AreaInfo=&ris->n_ai;
-
- ris->pras=(char *)AllocRaster(ris->larg,ris->alte);
- if (ris->pras==NULL) {
- close_g(ris);
- return (0);
- }
-
- InitTmpRas(&ris->n_tr,ris->pras,RASSIZE(ris->larg,ris->alte));
-
- r->TmpRas=&ris->n_tr;
-
- return(ris);
- }
-
- /***********************************
- ** CHIUDO TUTTE LE STRUTTURE **
- ** APERTE CON LA FUNZIONE PRECE- **
- ** DENTE. **
- ***********************************
- **** INPUT : **
- ** graf -> valore >0 ritornato **
- ** dalla funzione d'ini- **
- ** zializzazione **
- ***********************************/
- void close_g(REG(a0)struct grafica *graf)
- {
- struct RastPort *r;
- struct Layer *la;
- long int c;
-
- if ((long int)graf != NULL)
- {
- la=graf->wind->WLayer;
- if (graf->fdouble!=NULL) la=graf->NB_layer;
- if (la->ClipRegion!=NULL)
- {
- c=InstallClipRegion(la,NULL);
- DisposeRegion(c);
- }
- r=graf->rast;
- if ((long int)r > NULL)
- {
- r->AreaInfo=graf->o_ai;
- r->TmpRas=graf->o_tr;
- }
- if (graf->b_af!=NULL) FreeMem(graf->b_af,MAXVER(graf->lb_af));
- if (graf->pras!=NULL) FreeRaster(graf->pras,graf->larg,graf->alte);
- if (graf->fdouble!=NULL) FreeNBuff(graf,graf->wind->WScreen,
- graf->rast2);
- FreeMem(graf,sizeof(Sgrafica));
- }
- }
-
- /************************************
- ** FUNZIONE PER VISUALIZZARE LA **
- ** RASTPORT NASCOSTA SULLA **
- ** FINESTRA. **
- ************************************
- **** INPUT : **
- ** graf -> valore >0 ritornato **
- ** dalla funzione d'ini- **
- ** zializzazione. **
- **** OUTPUT: **
- ************************************/
- void switch_rp(graf)
- REG(a0)struct grafica *graf;
- {
-
- ClipBlit(graf->rast2,graf->clipx,graf->clipy,graf->rast1,graf->clipx,
- graf->clipy,graf->clipdx,graf->clipdy,0xc0);
- /**
- con questa e' un po' piu' rapido ma puo' risultare piu' instabile
- (forse)
- **/
- /*
- BltBitMap(graf->rast2->BitMap,graf->clipx,graf->clipy,graf->rast1->BitMap,
- graf->wind->LeftEdge+graf->clipx,graf->wind->TopEdge+graf->clipy,
- graf->clipdx,graf->clipdy,0xC0,0xFF,0);
- */
-
- WaitBlit();
-
- }
-
- /************************************
- ** FUNZIONE PER DEFINIRE UN BOX **
- ** DI CLIP SULLA FINESTRA **
- ************************************
- **** INPUT : **
- ** graf -> valore >0 ritornato **
- ** dalla funzione d'ini- **
- ** zializzazione. **
- ** minx - valore minimo x box. **
- ** miny - valore minimo y box. **
- ** dx - larghezza box. **
- ** dy - altezza box. **
- **** OUTPUT: **
- ** > 0 tutto ok. **
- ** = 0 errore. **
- **** NOTA: **
- ** elimina eventuali clip region **
- ** preesistenti. **
- ************************************/
- long int clipbox(REG(a0)struct grafica *graf,REG(d0)long int minx,
- REG(d1)long int miny,REG(d2)long int dx,REG(d3)long int dy)
- {
- struct Layer *la;
- struct Region *clipr;
- struct Rectangle rect;
- struct ClipRect *clrt;
- long int esi;
- long int i;
-
- #ifdef DEBUG
- char dbg[80];
- #endif
-
- graf->clipx=minx;
- graf->clipy=miny;
- graf->clipdx=dx;
- graf->clipdy=dy;
-
- #ifdef DEBUG
- sprintf(dbg,"mx=%ld my=%ld dx=%ld dy=%ld \n",minx,miny,dx,dy);
- write_dbg(dbg);
- #endif
-
- la=graf->wind->WLayer;
- if (graf->fdouble) la=graf->NB_layer;
-
- /*
- if (minx==0 AND miny==0 AND dx==0 AND dy==0)
- {
- if (graf->fdouble)
- {
- }
- else
- {
- clipr=(struct Region *)InstallClipRegion(la,NULL);
- if (clipr) DisposeRegion(clipr);
- return (0);
- }
- }
- if (graf->fdouble==NULL)
- {
- wn=graf->wind;
- la=wn->WLayer;
- }
- */
-
- /** elimino eventuali clipregion preesistenti **/
- clipr=(struct Region *)InstallClipRegion(la,NULL);
- if (clipr) DisposeRegion(clipr);
-
- /** inizializzo una nuova clip region vuota **/
- clipr=(struct Region *)NewRegion();
- if (clipr==NULL) return (0);
-
- rect.MinX=0;
- rect.MinY=0;
- if(graf->fdouble==NULL)
- {
- rect.MinX=graf->clipx;
- rect.MinY=graf->clipy;
- }
- rect.MaxX=graf->clipdx;
- rect.MaxY=graf->clipdy;
-
- OrRectRegion(clipr,&rect);
- InstallClipRegion(la,clipr);
-
- return (1);
- }
-
- /************************************
- ** FUNZIONE PER VISUALIZZARE UN **
- ** POLIGONO MA SOLO NEI CONTORNI. **
- ************************************
- **** INPUT : **
- ** graf -> valore >0 ritornato da **
- ** ini_g(). **
- ** nvert-> n# di vertici poligono.**
- ** pvert-> puntatore ad array di **
- ** int con elenco vertici **
- **** OUTPUT: **
- ** nessuno. **
- ************************************/
- void polw(REG(a0)struct grafica *graf,REG(d0)long int nvert,
- REG(a1)short int *pvert)
- {
- if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0);
-
- Move(graf->rast,pvert[0],pvert[1]);
- PolyDraw(graf->rast,nvert+1,pvert);
- }
-
-
- /************************************
- ** FUNZIONE PER VISUALIZZARE POL. **
- ** PIENO **
- ************************************
- **** INPUT : **
- ** graf -> valore >0 ritornato da **
- ** ini_g(). **
- ** nvert-> n# di vertici poligono.**
- ** pvert-> puntatore ad array di **
- ** int con elenco vertici **
- **** OUTPUT: **
- ** nessuno. **
- ************************************/
- void polf(REG(a0)struct grafica *graf,REG(d0)long int nvert,
- REG(a1)short int *pvert)
- {
- long int i,np;
-
- if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0);
-
- np=nvert<<1;
- AreaMove(graf->rast,pvert[0],pvert[1]);
-
- for (i=2 ;i<np ;i=i+2) AreaDraw(graf->rast,pvert[i],pvert[i+1]);
-
- AreaEnd(graf->rast);
-
- }
-
- /************************************
- ** FUNZIONE PER VISUALIZZARE POL. **
- ** PIENO CON BORDO **
- ************************************
- **** INPUT : **
- ** graf -> valore >0 ritornato da **
- ** ini_g(). **
- ** nvert-> n# di vertici poligono.**
- ** pvert-> puntatore ad array di **
- ** int con elenco vertici **
- ** colb -> colore da assegnare al **
- ** bordo. **
- **** OUTPUT: **
- ** nessuno. **
- ************************************/
- void polwf(REG(a0)struct grafica *graf,REG(d0)long int nvert,
- REG(a1)short int *pvert,REG(d1)long int colb)
- {
- long int i,np,x0,y0;
-
- if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0);
-
- x0=pvert[0];
- y0=pvert[1];
-
- SetOutlinePen(graf->rast,colb);
-
- np=nvert<<1;
- AreaMove(graf->rast,x0,y0);
-
- for(i=2; i<np; i=i+2) AreaDraw(graf->rast,pvert[i],pvert[i+1]);
-
- AreaEnd(graf->rast);
-
- }
-
- /*************************************
- ** FUNZIONE PER CANCELLARE UN BOX **
- ** NELLA FINESTRA . **
- *************************************
- **** INPUT : **
- ** graf -> valore >0 ritornato da **
- ** ini_g(). **
- ** x0 -> coord. x punto in alto **
- ** a sinistra box. **
- ** y0 -> coord. y punto in alto **
- ** a sinistra box. **
- ** x1 -> coord. x punto in basso **
- ** a destra box. **
- ** y1 -> coord. y punto in basso **
- ** a destra box. **
- **** NOTA : **
- ** usa il colore dello sfondo, e **
- ** non influenza le altre funzioni **
- *************************************/
- void cls_b(REG(a0)struct grafica *graf,REG(d0)long int x0,
- REG(d1)long int y0,REG(d2)long int x1,REG(d3)long int y1)
- {
- if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0);
-
- EraseRect(graf->rast,x0,y0,x1,y1);
- }
-
- /*************************************
- ** FUNZIONE PER CAMBIARE IL MODO **
- ** VIDEO DI TRACCIAMENTO. **
- *************************************
- **** INPUT : **
- ** graf -> valore >0 ritornato da **
- ** ini_g(). **
- ** mod -> nuovo modo video. **
- **** NOTA : **
- ** valori per mod : **
- ** 0 > JAM1 (over 2) **
- ** 1 > JAM2 (over 0) (def.) **
- ** 2 > COMPLEMENT (over 1) **
- ** 4 > INVERSVID (inverse 1) **
- *************************************/
- void over(REG(a0)struct grafica *graf,REG(d0)long int mod)
- {
- if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0);
-
- SetDrMd(graf->rast,mod);
- }
-
- /********* ROUTIN INTERNE PER PSEUDO DOUBLE BUFFERING ***************/
- /*********************************************
- ** INIZIALIZZO NUOVA RASTPORT PER USARLA **
- ** COME AREA DI RENDERING NASCOSTA. **
- *********************************************
- **** INPUT : **
- **** OUTPUT: **
- ** se > 0 allora puntatore a nuova rastport**
- *********************************************
- ** nota: inizializzo una bitmap uguale **
- ** alla finestra usata per visualizzare la **
- ** scena effettivamente. **
- *********************************************/
- struct RastPort *InitNBuff(struct grafica *graf,struct Screen *screen,
- struct Window *window)
- {
- struct RastPort *rport = NULL;
- struct Window *win;
- short int err = 0;
- unsigned char depth;
-
- win=graf->wind;
- depth=screen->BitMap.Depth;
-
- if (!(graf->NB_layerinfo = (struct Layer_Info *)NewLayerInfo()))
- return (NULL);
-
- if (!(graf->NB_bmap =(struct BitMap *)AllocBitMap(win->Width+SMARG,
- win->Height+SMARG,depth,BMF_CLEAR|BMF_DISPLAYABLE,
- graf->rast1->BitMap))) {
- err = 3;
- goto NBInit_done;
- }
-
- if (!(graf->NB_layer = (struct Layer *)CreateBehindLayer(graf->NB_layerinfo,
- graf->NB_bmap,SMARGM,SMARGM, window->Width-1, window->Height-1,
- LAYERSIMPLE|LAYERBACKDROP, NULL))) {
- err = 4;
- goto NBInit_done;
- }
- rport = graf->NB_layer->rp;
-
- SetRast(rport, 0);
-
- NBInit_done:
- if (err) FreeNBuff(graf,screen, rport);
- return (rport);
- }
-
- void FreeNBuff(struct grafica *graf,struct Screen *screen,
- struct RastPort *rp)
- {
- unsigned char depth;
-
- depth=screen->BitMap.Depth;
-
- if (graf->NB_layer) DeleteLayer(0L, graf->NB_layer);
- if (graf->NB_layerinfo) DisposeLayerInfo(graf->NB_layerinfo);
-
- if (graf->NB_bmap)
- {
- WaitBlit();
- FreeBitMap(graf->NB_bmap);
- }
- }
-
- /***********************************************************/
-
-