/* ** BETATRON high level library for platform and action arcade games. ** Copyright (C) 1997 Liouros Thanasis, liouros@hotmail.com ** ** BITMAPS.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 "plvga.h" #include #include #include //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- short TOworld::destroybitmaps() { unsigned short i; if (!bitmaps) return ERR_BITMAPSNOTMADE; if (internalbitmapsloader) // esoterikos fortotis ? for (i=0;i=bitmapsno) return NULL; tmp=bitmaps[i].data; switch (drfr) { case DRFR_SRAW: bitmaps[i].drawmethod=DR_SOLID; bitmaps[i].format=FR_RAW; break; case DRFR_S4PLANES: bitmaps[i].drawmethod=DR_SOLID; bitmaps[i].format=FR_4PLANES; break; case DRFR_TRAW: bitmaps[i].drawmethod=DR_THRU; bitmaps[i].format=FR_RAW; break; case DRFR_RLE: bitmaps[i].drawmethod=DR_RLE; bitmaps[i].format=FR_RLE; break; default: return NULL; } bitmaps[i].data = newmap; bitmaps[i].len=l; bitmaps[i].hei=h; return tmp; // epestrepse deikti sto bitmap pou vriskotan ekei } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- //desmeuei mnimi gia bitmapsno0 deiktes se frames //DEN desmeuei mnimi gia ta idia ta frames // Epistrefei: // 1: An epitixei (bitmaps=1 , internalbitmapsloader = 0 ) // 0: an apotixei na desmeusei mnimi // -1: o fortotis exei idi kathoristei short TOworld::makebitmaps(unsigned short bitmapsno0) { if (bitmaps) return ERR_BITMAPSMADE; if (!bitmapsno0) return ERR_ZEROMEMALLOC; bitmaps = (Tbitmap *) calloc (bitmapsno0,sizeof(Tbitmap)); if (!bitmaps) return ERR_OUTOFMEM; bitmapsno = bitmapsno0; // mou efage arketi ora gia na to vro o malakas for (int i=0;i= framedescrno) return ERR_OUTOFRANGE; d=framesdescr[descrno]; if (!d) return ERR_NULLDESCR; if (descrsubbitmapno >= d->bitmapsno) return ERR_SUBBITMAPRANGE; // out of subframe range // elegkse an to subbitmap xoraei mes sto frame if (bitmaps[bitmapno].data) // an iparxei to bitmapno if ( (bitx+bitmaps[bitmapno].len > d->len) || (bity+bitmaps[bitmapno].hei > d->hei) ) return ERR_BITMAPNOTFIT; // i proti parametros einai i dieuthinsi stin opoia prepei na grafei to neo frameno memcpy(d->data+descrsubbitmapno*6,&bitx,2); memcpy(d->data+descrsubbitmapno*6+2,&bity,2); memcpy(d->data+descrsubbitmapno*6+4,&bitmapno,2); return ERR_NOERR; // epitixia; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // epistrefei deikti stin proigoumeni collidemask kai thetei ti nea isi me mask // NULL epistrefetai se dio periptoseis: // a) an apotixei giati einai lathos to descrno // b) an epitixei alla den ipirxe proigoumeni collide mask opote epistrefei NULL char *TOworld::setcolidemask(unsigned short descrno,char *mask) { char *oldmask; // deiktis stin palia colide mask if (!framesdescr) return NULL; if ((descrno >= framedescrno) || (!framesdescr[descrno]) ) return NULL; // out of descr range oldmask = framesdescr[descrno]->colidemask; framesdescr[descrno]->colidemask = mask; return oldmask; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- short TOworld::getdescrmem(unsigned short descrno,unsigned short len0,unsigned short hei0, unsigned short subbitmapsno,unsigned char xdisplacement, unsigned char ydisplacement) { if (!framesdescr) return ERR_DESCRSNOTMADE; if (descrno >= framedescrno) return ERR_OUTOFRANGE; if (framesdescr[descrno] ) return ERR_NOTNULLDESCR; // exei idi desmeuthei mnimi if ( !(framesdescr[descrno] = (TPframedescr) malloc(6+4+2+6*subbitmapsno)) ) return ERR_OUTOFMEM; // den mporesa na desmeuso mnimi framesdescr[descrno]->len=len0; framesdescr[descrno]->hei=hei0; framesdescr[descrno]->bitmapsno=subbitmapsno; framesdescr[descrno]->xdispl=xdisplacement; framesdescr[descrno]->ydispl=ydisplacement; framesdescr[descrno]->colidemask=NULL; return ERR_NOERR; //epitixia } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- short TOworld::freedescrmem(unsigned short descrno) { if (!framesdescr) return ERR_DESCRSNOTMADE; if (descrno >= framedescrno) return ERR_OUTOFRANGE; if ( !framesdescr[descrno] ) return ERR_NULLDESCR; // einai idi NULL free(framesdescr[descrno]); framesdescr[descrno]=NULL; return ERR_NOERR; // epitixia } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // Desmeuei mnimi gia ena descriptor me arithmo descrno, kai theorei oti // apoteleitai apo ena mono bitmap auto me arithmo frameno // An colidmask=true desmeuei mnimi kai dimiourgei kai tin collide mask // tou descriptora // I routina einai mia sintmisi gia polles idies entoles pou tha ekanan // auti ti douleia // i routina theorei oti dimiurgeitai kainourgios descriptor , oti den ipirxe // diladi apo prin short TOworld::make1bitmapdescr(unsigned short descrno, unsigned short bitmapno, char colidmask, unsigned char xdispl, unsigned char ydispl) { short res; // apotelesma short sl,sh; char *mask; char *bdata; long errc; char *raw=NULL; if (!(bitmaps[bitmapno].data)) return ERR_NULLBITMAP; sl=bitmaps[bitmapno].len; sh=bitmaps[bitmapno].hei; if ( res=getdescrmem(descrno,sl,sh,1,xdispl,ydispl) ) return res; // subframe,bitmapno,x,y setsubbitmap(descrno,0,bitmapno,0,0); if (colidmask ) { if ( !(mask=(char *) malloc((sl+sh)<<1)) ) { freedescrmem(descrno); return ERR_OUTOFMEM; // apotixia desmeusis mnimis } bdata=bitmaps[bitmapno].data; switch (bitmaps[bitmapno].format) { case FR_RLE: if (! (raw=pl_rle2raw(bdata,sl,sh)) ) { free(mask); freedescrmem(descrno); return ERR_OUTOFMEM; } bdata=raw; case FR_RAW: pl_makecolidmask( bdata, sl,sh, mask); setcolidemask(descrno,mask); if (raw) free(raw); break; case FR_4PLANES: setcolidemask(descrno,NULL); break; } // switch } // if colidmask else setcolidemask(descrno,NULL); return ERR_NOERR; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- short TOworld::setframedisplacement(unsigned short frameno,unsigned char dx, unsigned char dy) { if (!framesdescr) return ERR_DESCRSNOTMADE; if (frameno>=framedescrno) return ERR_OUTOFRANGE; if (!framesdescr[frameno]) return ERR_NULLDESCR; framesdescr[frameno]->xdispl=dx; framesdescr[frameno]->ydispl=dy; return ERR_NOERR; } //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- /* %z set base bitmap number (relative bitmap number zero) %b absolute bitmapno (corresponds to TOworld::bitmaps[%b]) %B relative bitmapno (corresponds to TOworld::bitmaps[%b+%z]) %x set x coordinate %y set y coordinate ( x,y are relative to the upper left corner of the descr) %X relative x coordinate (add the number to the current x coordinate) %Y relative y coordinate (add the number to the current y coordinate) %h horizontal spacing between bitmaps %v vertical spacing between bitmaps \n next line, return %% % character ' ' dont plot anything any char relative bitmapno (TOworld::bitmaps[%z+any char]) */ // make sure that struct takes up 6 bytes exactly struct Tsubbitmap { unsigned short sbx __attribute__ ((packed)); unsigned short sby __attribute__ ((packed)); unsigned short bitmapno __attribute__ ((packed)); }; short TOworld::dprintf(unsigned short descrno,char *st,...) { unsigned short curx=0,cury=0; unsigned short startx=0; unsigned char *ch; Tsubbitmap data[80]; // desmeuse sti stoiva xoro gia to poli 80 subbitmaps unsigned char subbitcounter=0; signed long cursubbit=0; static signed long basebit=0; static unsigned short xspace=3; static unsigned short yspace=2; unsigned short maxx=0,maxy=0,maxh=0; unsigned short tmp; short err; va_list v; if (!framesdescr) return ERR_DESCRSNOTMADE; if (descrno >= framedescrno) return ERR_OUTOFRANGE; va_start(v,st); #define va_ret(val) { va_end(v); return (val); } #define CONTROLCHAR '%' ch=(unsigned char *)st; for (;(*ch) && (subbitcounter<80);ch++) { if ( (*ch)==CONTROLCHAR) { ch++; if (!(*ch)) // check if we came to the end of the string va_ret((char *)ch-st); // if yes,syntax error, return the number // of the character in the string. switch (*ch) { case 'z':// set base bitmap number basebit=va_arg(v,short); continue; case 'b':// absolute bitmap number cursubbit=va_arg(v,unsigned short); break; case 'B': // a relative subbitmap cursubbit= va_arg(v,short)+basebit; break; case 'x': // x coordinate curx = va_arg(v,unsigned short); startx=curx; continue; case 'y': // y coordinate cury = va_arg(v,unsigned short); continue; case 'X': // move to horizontal direction (relative x coordinate) curx+= va_arg(v,short); continue; case 'Y': // move to vertical direction (relative y coordinate) cury+= va_arg(v,short); continue; case 'h': //x-spacing between subbitmaps xspace = va_arg(v,short); continue; case 'v': //y-spacing between subbitmaps yspace = va_arg(v,short); continue; case CONTROLCHAR: // % character cursubbit=(*ch)+basebit; break; default: //ignore anything else continue; } //switch } // if *ch != % else { switch (*ch) { case '\n': // return curx=startx; cury+=(yspace+maxh); maxh=0; continue; case ' ': // space, just skip the pos curx+=xspace; continue; default: // a simple character cursubbit=(*ch)+basebit; break; }// switch } // else data[subbitcounter].sbx=curx; data[subbitcounter].sby=cury; if ( (cursubbit<0) || (cursubbit>=bitmapsno)) va_ret(ERR_OUTOFRANGE); data[subbitcounter].bitmapno=cursubbit; if (bitmaps[cursubbit].data) { if ( (tmp=bitmaps[cursubbit].len+curx) > maxx) maxx=tmp; if ( (tmp=bitmaps[cursubbit].hei) >maxh) maxh=tmp; tmp+=cury; if ( tmp > maxy) maxy=tmp; curx+=bitmaps[cursubbit].len; } subbitcounter++; curx+=xspace; } //for // eleutherose tixon mnimi pou katalamvanei o frame descriptoras if (framesdescr[descrno]) { free(framesdescr[descrno]); framesdescr[descrno]=NULL; } if ( err=getdescrmem(descrno,maxx,maxy,subbitcounter)) va_ret(err); memmove(framesdescr[descrno]->data,data,subbitcounter*6); va_ret(ERR_NOERR); }