/* ** BETATRON high level library for platform and action arcade games. ** Copyright (C) 1997 Liouros Thanasis, liouros@hotmail.com ** ** GRID.CC: This file is part of the BETATRON library and can be used ** and/or distributed only under the terms of the GNU Library ** General Public License. See doc/readme.1st for details. */ #include "world.h" #include #include "grid.h" #include TOobject *Tclustergrid::gridcollision(TOobject *o) { unsigned short x1,y1,x2,y2; register unsigned short i,j; unsigned short gridstep; register TPobjptrlist l; register TPobjptrlist *g; x1 = o->x >> l2; x2 = (o->x+o->slen-1) >> l2; y1 = o->y >> h2; y2 = (o->y + o->shei -1 ) >> h2; gridstep=len-(x2-x1+1); g=grid+y1*len+x1; for (i=y1;i<=y2;i++,g+=gridstep) for (j=x1;j<=x2;j++,g++) { for (l=(*g);l;l=l->next) if (world->collision(l->obj,o)) return l->obj; } return NULL; // no collision found } void Tclustergrid::clusterize() { TOobject *o; short i; unsigned short x1,y1,x2,y2; unsigned short step,k,j; TPobjptrlist *grid0; TPobjptrlist entry; // midenise to grid memset(grid,0, len*hei*sizeof(TPobjptrlist) ); if (!listsno) return; zerobuffer(); // midenise to buffer for (i=0;iobjs[lists[i]];o;o=o->Pnext) { x1=o->x >> l2; x2= (o->x+o->slen-1) >> l2; y1=o->y >> h2; y2=(o->y+o->shei-1) >> h2; step=len - (x2-x1+1); // poso tha aukisoume to grid0 grid0=grid+y1*len+x1; for (j=y1;j<=y2;j++,grid0+=step) for (k=x1;k<=x2;k++,grid0++) { if ( !(entry=(TPobjptrlist)getmem(sizeof(Tobjptrlist))) ) return; // teleiose i mnimi stamata ti diadikasia // vale to stoixeio stin korifi tis listas entry->obj=o; entry->next= (*grid0); (*grid0)=entry; }// for 4 }//for 2 }//for 1 } short Tclustergrid::makegrid(unsigned short length,unsigned short height,TOworld *w) { short s; if (grid) return ERR_GRIDMADE; // ipologise tis diastaseis tou grid len=length >> l2; if (length << (16-l2)) len++; hei=height >> h2; if (height << (16-h2)) hei++; // desmeuse mnimi gia to buffer if (s=initbuffer(maxobjsno*sizeof(Tobjptrlist)) ) return s; // desmeuse mnimi gia to grid kai to grid indexes if ( !(grid=(TPobjptrlist *) malloc(len*hei*sizeof(TPobjptrlist))) ) { freebuffer(); return ERR_OUTOFMEM; } world=w; return ERR_NOERR; } void *Tclustergrid::getmem(unsigned short size0) { void *res; if ( (!size0) || (nowpos+size0>bufsize) ) return NULL; res=(void *)(data + nowpos); nowpos+=size0; return res; } short Tclustergrid::initbuffer(long size0) { if (!size0) return ERR_ZEROMEMALLOC; if (! (data=(char *)malloc(size0)) ) return ERR_OUTOFMEM; bufsize=size0; nowpos=0; return ERR_NOERR; } void Tclustergrid::freebuffer() { free(data); bufsize=0; nowpos=0; data=NULL; } // constructor Tclustergrid::Tclustergrid() { bufsize=0; nowpos=0; data=NULL; element=NULL; l2=DEFCELLL; h2=DEFCELLH; maxobjsno=DEFMAXOBJSNO; grid=NULL; listsno=0; } short Tclustergrid::setparameters(unsigned char l20,unsigned char h20, unsigned short maxobjsno0) { if (grid) return ERR_GRIDMADE; if ( l20 > MAXGRIDCELLL || h20 > MAXGRIDCELLH || maxobjsno0 > MAXMAXOBJSNO) return ERR_OUTOFRANGE; l2=l20; h2=h20; maxobjsno=maxobjsno0; return ERR_NOERR; } short Tclustergrid::addfirstlist(short list) { listsno=0; return addlist(list); } short Tclustergrid::addlist(short list) { if (listsno>=MAXLISTS) return ERR_TOOMANYLISTS; lists[listsno++]=list; return ERR_NOERR; } Tclustergrid::~Tclustergrid() { done(); } void Tclustergrid::done() { freebuffer(); free(grid); grid=NULL; listsno=0; element=NULL; }