/* MAP.C Functions that deal with the level map. Most notably in here you'll find the 4-way scrolling engine. */ #include "keen.h" #include "CGraphics.h" unsigned long scroll_x = 0; // total amount of X scroll unsigned int scrollx_buf = 0; // amount the scroll buffer is scrolled(x) unsigned char scrollpix = 0; // (0-7) for tracking when to draw a stripe unsigned int mapx = 0; // map X location shown at scrollbuffer row 0 unsigned int mapxstripepos = 0; // X pixel position of next stripe row unsigned int scrolly_buf = 0; // amount the scroll buffer is scrolled(y) unsigned char scrollpixy = 0; // (0-7) for tracking when to draw a stripe unsigned int mapy = 0; // map Y location shown at scrollbuffer column 0 unsigned int mapystripepos = 0; // Y pixel position of next stripe column // note that the scroll buffer is 512x512, this is where all the 511 and 512 // numbers come from. // scrolls the map one pixel right void map_scroll_right(void) { scroll_x++; if(scrollx_buf>=511) scrollx_buf=0; else scrollx_buf++; scrollpix++; if (scrollpix>15) { // need to draw a new stripe map_draw_vstripe(mapxstripepos, mapx + 32); mapx++; mapxstripepos += 16; if (mapxstripepos >= 512) mapxstripepos = 0; scrollpix = 0; } } // scrolls the map one pixel left void map_scroll_left(void) { scroll_x--; if(scrollx_buf==0) scrollx_buf=511; else scrollx_buf--; if (scrollpix==0) { // need to draw a new stripe mapx--; if (mapxstripepos == 0) { mapxstripepos = (512 - 16); } else { mapxstripepos -= 16; } map_draw_vstripe(mapxstripepos, mapx); scrollpix = 15; } else scrollpix--; } void map_scroll_down(void) { scroll_y++; if(scrolly_buf>=511) scrolly_buf=0; else scrolly_buf++; scrollpixy++; if (scrollpixy>15) { // need to draw a new stripe map_draw_hstripe(mapystripepos, mapy + 32); mapy++; mapystripepos += 16; if (mapystripepos >= 512) mapystripepos = 0; scrollpixy = 0; } } void map_scroll_up(void) { scroll_y--; if(scrolly_buf==0) scrolly_buf=511; else scrolly_buf--; if (scrollpixy==0) { // need to draw a new stripe mapy--; if (mapystripepos == 0) { mapystripepos = (512 - 16); } else { mapystripepos -= 16; } map_draw_hstripe(mapystripepos, mapy); scrollpixy = 15; } else scrollpixy--; } // draws a vertical stripe from map position mapx to scrollbuffer position x void map_draw_vstripe(unsigned int x, unsigned int mpx) { int i,y,c; /*int xt=x>>4;*/ for(y=0;ydrawTile(x, ((y<<4)+mapystripepos)&511, c); if (AnimTileInUse[x>>4][(((y<<4)+mapystripepos)&511)>>4]) { // we just drew over an animated tile which we must unregister animtiles[AnimTileInUse[x>>4][(((y<<4)+mapystripepos)&511)>>4]].slotinuse = 0; AnimTileInUse[x>>4][(((y<<4)+mapystripepos)&511)>>4] = 0; } //if (tiles[c].isAnimated) if ( TileProperty[c][ANIMATION] > 1 ) { // we just drew an animated tile which we will now register for(i=1;i>4][((((y<<4)+mapystripepos)&511))>>4] = i; goto stop; // and drop out of the loop } } stop: ; } } } // draw a horizontal stripe, for vertical scrolling void map_draw_hstripe(unsigned int y, unsigned int mpy) { int i,x,c; /*int xt;*/ for(x=0;xdrawTile(((x<<4)+mapxstripepos)&511, y, c); if (AnimTileInUse[(((x<<4)+mapxstripepos)&511)>>4][y>>4]) { // we just drew over an animated tile which we must unregister animtiles[AnimTileInUse[(((x<<4)+mapxstripepos)&511)>>4][y>>4]].slotinuse = 0; AnimTileInUse[(((x<<4)+mapxstripepos)&511)>>4][y>>4] = 0; } if ( TileProperty[c][ANIMATION] > 1 ) { // we just drew an animated tile which we will now register for(i=1;i>4][y>>4] = i; goto stop; // and drop out of the loop } } stop: ; } } } // returns the map tile at map position (x,y) unsigned int getmaptileat(unsigned int x, unsigned int y) { int xa = x>>4; int ya = y>>4; if (xa<=255 && ya<=255) { return map.mapdata[xa][ya]; } else { if(xa > 255) { xa = 255; //player[cp].xa = 255; } if(ya > 254) { ya = 255; //player[cp].ya = 255; } return map.mapdata[xa][ya]; //crashflag = 1; //crashflag2 = x; //crashflag3 = y; //why_term_ptr = "getmaptileat(): OOB reading from mapdata."; //return 0; } } unsigned int getlevelat(unsigned int x, unsigned int y) { return map.objectlayer[x>>4][y>>4]; } // called at start of level to draw the upper-left corner of the map // onto the scrollbuffer...from then on the map will only be drawn // in stripes as it scrolls around. void drawmap(void) { int y; for(y=0;y=mapx && y>=mapy && xdrawTile(((mapxstripepos+((x-mapx)<<4))&511), ((mapystripepos+((y-mapy)<<4))&511), newtile); } // searches for animated tiles at the map position (X,Y) and // unregisters them from animtiles void map_deanimate(int x, int y) { int px,py; int i; // figure out pixel position of map tile (x,y) px = ((mapxstripepos+((x-mapx)<<4))&511); py = ((mapystripepos+((y-mapy)<<4))&511); //TileProperty[map.mapdata[x][y]][ANIMATION] = 1; // find it! for(i=1;i>4][py>>4] = 0; return; } } } // tells if the object is animating at a given position int map_isanimated(int x, int y) { int px,py; int i; // figure out pixel position of map tile (x,y) px = ((mapxstripepos+((x-mapx)<<4))&511); py = ((mapystripepos+((y-mapy)<<4))&511); // find it! for(i=1;i>4][py>>4]) return; // find an unused slot in animtiles for(i=1;i>4][py>>4] = i; return; } } crashflag = 1; crashflag2 = x; crashflag3 = y; why_term_ptr = "Unable to animate tile at x/y=crashflag1/2"; } // searches the map's object layer for object OBJ. // if it is found returns nonzero and places the // coordinates of the first occurance of the object // in (xout,yout) char map_findobject(unsigned int obj, int *xout, int *yout) { unsigned int x,y; for(y=2;y