/* saveblocks.m */

#include "idbsp.h"

short   datalist[0x10000], *data_p;
/*
short *datalist;
short *data_p;
*/
float   orgx, orgy;

#define BLOCKSIZE       128


float           xl, xh, yl, yh;

boolean LineContact (worldline_t *wl)
{
        NXPoint         *p1, *p2, pt1, pt2;
        float           lxl, lxh, lyl, lyh;
        divline_t       ld;
        int                     s1,s2;

        p1 = &wl->p1;
        p2 = &wl->p2;
        ld.pt.x = p1->x;
        ld.pt.y = p1->y;
        ld.dx = p2->x - p1->x;
        ld.dy = p2->y - p1->y;

        if (p1->x < p2->x)
        {
                lxl = p1->x;
                lxh = p2->x;
        }
        else
        {
                lxl = p2->x;
                lxh = p1->x;
        }
        if (p1->y < p2->y)
        {
                lyl = p1->y;
                lyh = p2->y;
        }
        else
        {
                lyl = p2->y;
                lyh = p1->y;
        }

        if (lxl >= xh || lxh < xl || lyl >= yh || lyh < yl)
                return false;   /* no bbox intersections */

        if ( ld.dy / ld.dx > 0)
        {       /* positive slope */
                pt1.x = xl;
                pt1.y = yh;
                pt2.x = xh;
                pt2.y = yl;
        }
        else
        {       /* negetive slope */
                pt1.x = xh;
                pt1.y = yh;
                pt2.x = xl;
                pt2.y = yl;
        }

        s1 = PointOnSide (&pt1, &ld);
        s2 = PointOnSide (&pt2, &ld);

        return s1 != s2;
}


/*
================
=
= GenerateBlockList
=
================
*/

void GenerateBlockList (int x, int y)
{
        NXRect          r;
        worldline_t     *wl;
        int                     count, i;

        *data_p++ = 0;          /* leave space for thing links */

        xl = orgx + x*BLOCKSIZE;
        xh = xl+BLOCKSIZE;
        yl = orgy + y*BLOCKSIZE;
        yh = yl+BLOCKSIZE;

        r.origin.x = xl;
        r.origin.y = yl;
        r.size.width = r.size.height = BLOCKSIZE;
/*
        if (draw)
                NXEraseRect (&r);
*/
/*
        count = [linestore_i count];
        wl = [linestore_i elementAt: 0];
*/
        count = linestore_i->count;
        wl = linestore_i->data;
        for (i=0 ; i<count ; i++,wl++)
        {
                if (wl->p1.x == wl->p2.x)
                {       /* vertical */
                        if (wl->p1.x < xl || wl->p1.x >= xh)
                                continue;
                        if (wl->p1.y < wl->p2.y)
                        {
                                if (wl->p1.y >= yh || wl->p2.y < yl)
                                        continue;
                        }
                        else
                        {
                                if (wl->p2.y >= yh || wl->p1.y < yl)
                                        continue;
                        }
                    /*    *data_p++ = SHORT(i); */
                        *data_p++ = i;
                        continue;
                }
                if (wl->p1.y == wl->p2.y)
                {       /* horizontal */
                        if (wl->p1.y < yl || wl->p1.y >= yh)
                                continue;
                        if (wl->p1.x < wl->p2.x)
                        {
                                if (wl->p1.x >= xh || wl->p2.x < xl)
                                        continue;
                        }
                        else
                        {
                                if (wl->p2.x >= xh || wl->p1.x < xl)
                                        continue;
                        }
                 /*       *data_p++ = SHORT(i); */
                        *data_p++ = i;
                        continue;
                }
                /* diagonal */
                if (LineContact (wl) )
                  /*      *data_p++ = SHORT(i); */
                          *data_p++ = i;
        }

        *data_p++ = -1;         /* end of list marker */
}


/*
================
=
= SaveBlocks
=
block lump holds:
orgx
orgy
blockwidth
blockheight
listoffset[blockwidth*blockheight]
lists
        one short left blank for thing list
        linedef numbers
        -1 terminator

================
*/

void SaveBlocks (void)
{
        int             blockwidth, blockheight;
        int             x,y, len;
        short   *pointer_p;

        blockwidth = (worldbounds.size.width+BLOCKSIZE-1)/BLOCKSIZE;
        blockheight = (worldbounds.size.height+BLOCKSIZE-1)/BLOCKSIZE;
        orgx = worldbounds.origin.x;
        orgy = worldbounds.origin.y;

        pointer_p = datalist;
/*
        *pointer_p++ = SHORT(orgx);
        *pointer_p++ = SHORT(orgy);
        *pointer_p++ = SHORT(blockwidth);
        *pointer_p++ = SHORT(blockheight);
*/
        *pointer_p++ = orgx;
        *pointer_p++ = orgy;
        *pointer_p++ = blockwidth;
        *pointer_p++ = blockheight;

        data_p = pointer_p + blockwidth*blockheight;

        for (y=0 ; y<blockheight ; y++)
                for (x=0 ; x<blockwidth ; x++)
                {
                        len = data_p - datalist;
                    /*    *pointer_p++ = SHORT(len); */
                        *pointer_p++ = len;
                        GenerateBlockList (x,y);
                }

        len = 2*(data_p-datalist);

        printf ("blockmap: (%i, %i) = %i\n",blockwidth, blockheight, len);

#if 0
{
        int     outhandle;

        outhandle = SafeOpenWrite ("blockmap.lmp");
        SafeWrite (outhandle, datalist, len);
        close (outhandle);
}
#endif
/*      [wad_i addName: "blockmap" data:datalist size:len]; */
        addName("blockmap", datalist, len);

}

