Quantcast

Mycal's Experimental Homepage Software

Menu
Home
Login

Jump To
  • My Projects
  • Basic Archive
  • Clearlake
  • Archive
  • Articles
  • Links
  • Sandbox
    Search
  • You are at /Archive/

    Parent DirectorySoftware Polygon Rendering Source Code


    I rescued this off a 5 1/4" floppy the other day. Some software only polygon code I wrote for making games in 1988. Props to "Foley VanDam"

    #define demo 1
    
    
    /************************************************************/
    /* Polygon code by          Mike Johnson            9/9/88  */
    /*                                                          */
    /* True concave polygones. Very hi-preformance. Portable.   */
    /* For highest performance it calles hline,line, and point  */
    /* routines, though you could just use a line routine.      */
    /*----------------------------------------------------------*/
    /*                          mycal@netacsys.com              */
    /*                         All Rights Reserved (c)1988      */
    /************************************************************/
    
    
    #include 
    
    #define     MAXEDGES    12              /* maximum edges in polygon */
    #define     DRAW_EDGES  0               /* set to draw poly edges   */
    #define     CONCAVE     1               /* set for concave polygons */
    
    unsigned int lines[200];                /* Array of line start addresses */
    
    struct points
    {
        short x,y;
    };
    
    /*                                      */
    /* structure for the edges of a polygon */
    /*                                      */
    //    union REGS regs;
    
    
    struct edge
    {
       /* end points */
          short     xstart;
          short     ystart;
          short     xend;
          short     yend;
       /* DDA vars */
          short     dx;         /* deltaX xend-xstart   */
          short     dy;         /* deltaY yend-ystart   */
          short     error;      /*                      */
          short     incS;       /* increment error      */
          short     incSE;      /* reset increment      */
          short     x;          /* current x            */
          short     y;          /* current y            */
          short     xdir;       /* x direction -1 or 1  */
          struct    edge *ptr;  /* pointer to next in active list */
    };
    
    /****************************************************************/
    /* Poly(verts,num) -                                            */
    /*      verts is a pointer to an array of polygon vertices.     */
    /*      num   is the number of vertices in the array.           */
    /*      color is set before this call.                          */
    /*--------------------------------------------------------------*/
    /*                                                              */
    /****************************************************************/
    poly(verts,num,color)
    struct points *verts;
    int num;
    int color;
    {
        struct edge edges[MAXEDGES];/* edge table */
        struct edge tedge;
        struct edge *ptr,*nptr,*tptr,*lptr; /* pointer to an edge table */
        int i,j;                    /* counter */
        int flag;
        int ypos;                   /* ypos = scanline */
        int eypos;                  /* end of the polygon */
        int next;                   /* next value to recalc the active list */
        int len;
        int xst;
    
        ypos = 32767;
        eypos= 0;
        i=0;
      switch(num){
        /* polygon is just a point */
        case 1:
            i=2;
            i=1;
            i=0;
    //        polyline(verts[0].y,verts[0].x,verts[0].x);
            return;
        /* polygon is just a line, nothing to fill */
        case 2:
            i=0;
            i=1;
            i=2;
    //        evgaline_640/*polyline1*/(verts[0].x,verts[0].y,verts[1].x,verts[1].y,color);
            return;
        default:
        /* this is a real polygon, so lets do it  */
    
        /* copy first vert to last for wraparound */
            verts[num] = verts[0];
        /* we can only do MAXEDGES */
            if (num>MAXEDGES)
                num = MAXEDGES;
    
        /* build edge table */
            i=0;                    /* edge number */
            j=0;                    /* vert number */
    
            while ( i<= num-1) {
            /* always have a positive dy */
                if (verts[j].y < verts[j+1].y) {
                    edges[i].y = edges[i].ystart = verts[j].y;
                    edges[i].x = edges[i].xstart = verts[j].x;
                    edges[i].yend   = verts[j+1].y;
                    edges[i].xend   = verts[j+1].x;
                }else{
                    edges[i].y = edges[i].ystart = verts[j+1].y;
                    edges[i].x = edges[i].xstart = verts[j+1].x;
                    edges[i].yend   = verts[j].y;
                    edges[i].xend   = verts[j].x;
                } /* end if */
    
            /* find start and end pos of polygon */
                if (ypos>edges[i].ystart)   /* find smallest y */
                    ypos=edges[i].ystart;
                if (eypos= edges[i].ystart) &&
                        (ypos < edges[i].yend))
                        {
                            if (ptr==0) {
                                ptr = &edges[i];
                                edges[i].ptr = 0;
                                nptr = ptr;
                            }else {
                                if(ptr->x > edges[i].x) {   // insert at head of list
                                    edges[i].ptr = ptr;
                                    ptr = &edges[i];
                                } else {
                                    flag = 0;
                                    lptr = ptr;
                                    tptr = ptr->ptr;
                                    while(!flag){
                                        if(tptr==0) {       // insert at end of list
                                            nptr->ptr=&edges[i];
                                            edges[i].ptr=0;
                                            nptr=nptr->ptr;
                                            flag=1;
                                        }else if(tptr->x > edges[i].x) {
                                            edges[i].ptr = tptr;
                                            lptr->ptr = &edges[i];
                                            flag = 1;
                                        } else {
                                            lptr= tptr;
                                            tptr = tptr->ptr;
                                        }
                                    }/*while*/
                                }/*else*/
                            }/*else*/
                            if(next>edges[i].yend)      // next calc at edge end?
                                next = edges[i].yend ;  // yes save ypos
                        }else
                        /* see if next edge recalc occures on new edge */
                            if ((yposedges[i].ystart))
                                next = edges[i].ystart;
                } /*end for*/
               } /*endif*/
            /**********************/
            /* draw the scan line */
            /**********************/
                nptr = ptr;
                while (nptr) {
                    xst = nptr->x;
                    len = nptr->ptr->x - xst;
                    
    //                evgaline_640(nptr->x,ypos,nptr->ptr->x,ypos,color);
    asm {
    		mov	ax, 0A000H	// Video adapter is at A0000H
    		mov	es, ax
    		mov	al, byte ptr color
    		mov	ah, al
    		mov	di, ypos	// Lookup (200 - y) * 320
    		shl	di, 1
    		mov	di, word ptr lines[di]
    		add	di, xst		// add starting x coordinate
    		mov	cx, len
    		cld			// Clear direction flag
    		inc	cx		// Always at least one byte
    		test	di, 1		// If odd address, set one byte
    		jz	Set_Even
    		stosb
    		dec	cx
    		jz	Set_Done
    }
    Set_Even:
    asm {
    		shr	cx, 1		// Set rest as words
    		rep	stosw
    		adc	cx, cx		// Set any last byte
    		rep	stosb
    }
    Set_Done:
    
    //                printf("Y = %5d, X = %5d to %5d\n",ypos,nptr->x,nptr->ptr->x);
                    nptr = nptr->ptr->ptr;
                }
    
            /****************************************/
            /* Update DDA variables in active edges */
            /****************************************/
                nptr = ptr;
                while (nptr) {
                    if (nptr->dy < nptr->dx) {
                        if (nptr->error > 0){
                            nptr->error = nptr->error + nptr->incSE;
                            nptr->x = nptr->x + nptr->xdir;
                              //nptr->y = nptr->y + 1;
                        } /*endif*/
                        while(nptr->error <= 0) {
                                nptr->error = nptr->error + nptr->incS;
                                nptr->x = nptr->x + nptr->xdir;
                            } /*endwhile*/
                    }else{
                        if (nptr->error>0){
                            nptr->error = nptr->error + nptr->incSE;
                            nptr->x = nptr->x + nptr->xdir;
                              //nptr->y = nptr->y + 1;
                        } /*endif*/
                        else {
                                nptr->error = nptr->error + nptr->incS;
                                //nptr->y = nptr->y + 1;
                            } /*endelse*/
                        }/*endelse*/
                    nptr = nptr->ptr;
                }  /*endwhile*/
    
                ypos = ypos + 1;            /* set to next scan line */
            /****************************************************/
            /* scan through active edge list and see if there   */
            /* has been an edge order change. if so set recalc  */
            /* flag. NOTE: not needed for non concave polys     */
            /****************************************************/
    #if CONCAVE
                nptr = ptr;
                while (nptr->ptr) {    // check to see if edges are in correct order
                    if((nptr->ptr->x <= nptr->x))
                        next=ypos;                          // force recalc
                    nptr = nptr->ptr;
                }
    #endif
        } /*endwhile*/
    
      }/*endswitch*/
    } /* end of poly render */
    
    #if 1
    main()
    {
        struct points verts[20];
        long stime,etime,dtime;
        float sdtime;
        int temp;
        int i, y,j;
        union REGS regs;
    
    /* Initialize the table of lines */
    
    asm {
    
    		mov	ax, ds
    		mov	es, ax
    		cld
    		mov	di, offset lines
    		mov	ax, 320 * (200 - 1)	// 200 lines of 320 bytes each
    }
    Init_Loop:
    asm {		
    		stosw				// Put in value
    		sub	ax, 320			// Move to next line
    		jnc	Init_Loop		// Do all the lines
    }
    
        regs.x.ax =0x0013;
        int86(0x10, ®s, ®s);
    
    //for(i=1;i<100;i++) {
    
    verts[0].x =10;
    verts[0].y =10;
    verts[1].x =50;
    verts[1].y =40;
    verts[2].x =30;
    verts[2].y =30;
    verts[3].x =40;
    verts[3].y =70;
    for (i=1; i < 20000; i++) poly(verts,4,(i >> 8) & 0xF);
    
    /*
    verts[1].x =100;
    verts[1].y =100;
    verts[2].x =200;
    verts[2].y =200;
    verts[3].x =200;
    verts[3].y =100;
    verts[4].x =100;
    verts[4].y =200;
    verts[1].x =100;
    verts[1].y =100;
    verts[2].x =200;
    verts[2].y =200;
    verts[3].x =150;
    verts[3].y =225;
    verts[4].x =100;
    verts[4].y =150;
    verts[5].x =125;
    verts[5].y =175;
    */
    
    //    stime = get_tick();
    /*    for(i=1;i<500;i++){
           for(j=0;j<10;j++) {
                verts[j].x = (rand()%600+20);
                verts[j].y = (rand()%400+20);
            }
            poly(verts,(rand()%7+3),(rand()%14+1));
              /* vert array, # of verts, color */
    //    }
    
    //    etime = get_tick();
    //    dtime = etime-stime;
    //    sdtime = (dtime/18.2);
    
    //    text();
    
    //    printf("Poly draw test (500) = %f seconds, %d ticks\n",sdtime,dtime);
    
    
    /*
    for(j=1;j<301;j++){
    for(i=1;i<25;i++) {
        verts[i].x = (rand()%639);
        verts[i].y = (rand()%479);
    }
        poly(verts,(rand()%20+4),(rand()%14+1));
          /* vert array, # of verts, color */
    //}
    
    //    etime = regs.x.dx-stime;
    
    //    int86(0x1a, ®s, ®s);
    //    stime = regs.x.dx;
    
    
    
    //    scanf("%c",&temp);
    
        regs.x.ax = 0x0003;
        int86(0x10,®s,®s);
    
    //printf("poly = %d  rect = %d \n",etime,stime);
    
    }
    #endif
    





    Sponsership

    Connect to anyting, anywhere anytime with yoics.







    Last Update at 05-18-2017 7:41 pm
    Copyright 1994-2006 mycal, All Rights Reserved