void killline(Line * l) { l->on=false; l->dead=false; // FIX: Make bang noise here? switch (l->dir) { case DOWN: // falls through. case UP: markgrid(l->geom.x,l->geom.y,l->geom.w,l->geom.h,' '); //SDL_FillRect(screen,&l->geom,SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF)); SDL_BlitSurface(screensave,&l->geom, screen, &l->geom); soil(l->geom); break; case RIGHT: // falls through case LEFT: markgrid(l->geom.x,l->geom.y,l->geom.w,l->geom.h,' '); //SDL_FillRect(screen,&l->geom,SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF)); SDL_BlitSurface(screensave,&l->geom, screen, &l->geom); soil(l->geom); break; } }
void checkempty(int x, int y) { //int i,j; // for debugging... SDL_Rect tmprect; // if square isn't empty, just return.... if (grid[x][y]!=' ') { return; } // it'd be nice to find a way to keep this longer... memcpy(maskgrid,grid,WIDTH*HEIGHT); // penguinsearch at that spot... rcount=0; if (!penguinsearch(x,y)) // area is clear! { //printwholemaskgrid(); //floodfill(x,y); // this makes sure x and y are the top left corners of blocks. // since the area is empty of penguins, it should be completely // safe to use this isntead of floodfill here. really. :) squarefill( (((x-BORDERLEFT)/BLOCKWIDTH ) * BLOCKWIDTH ) +BORDERLEFT, (((y-BORDERTOP)/BLOCKHEIGHT) * BLOCKHEIGHT) +BORDERTOP); tmprect.w=BLOCKWIDTH; tmprect.h=BLOCKHEIGHT; for (tmprect.x=BORDERLEFT;tmprect.x<BORDERRIGHT;tmprect.x+=BLOCKWIDTH) for (tmprect.y=BORDERTOP;tmprect.y<BORDERBOTTOM;tmprect.y+=BLOCKHEIGHT) if (grid[tmprect.x][tmprect.y]=='.') // clear it!) { SDL_FillRect(screen,&tmprect,color.background); soil(tmprect); } //printwholegrid(); } /* printf("Search took %ld recursions.\n",rcount); */ /* for (j=0;j<HEIGHT;j+=BLOCKHEIGHT) { for (i=0;i<WIDTH;i+=BLOCKWIDTH) { printf("%c ",maskgrid[i][j]); } printf("\n"); } printf("\n"); */ }
int moveline(Line * l) { int finish=false; char check1; char check2; markgrid(l->mark.x,l->mark.y,l->mark.w,l->mark.h,l->id); SDL_FillRect(screen,&(l->mark),l->color); soil(l->mark); switch (l->dir) { case UP: check1=grid[l->geom.x][l->geom.y-1]; check2=grid[l->geom.x+BLOCKWIDTH-1][l->geom.y-1]; break; case DOWN: check1=grid[l->geom.x][l->geom.y+l->geom.h]; check2=grid[l->geom.x+BLOCKWIDTH-1][l->geom.y+l->geom.h]; break; case LEFT: check1=grid[l->geom.x-1][l->geom.y]; check2=grid[l->geom.x-1][l->geom.y+BLOCKHEIGHT-1]; break; case RIGHT: check1=grid[l->geom.x+l->geom.w][l->geom.y]; check2=grid[l->geom.x+l->geom.w][l->geom.y+BLOCKHEIGHT-1]; break; default: // this will never happen. really. fprintf(stderr,"Line has no direction. That shouldn't have happened.\n"); check1='!'; check2='!'; break; } if (check1 == ' ' && check2 == ' ') { // next space is empty switch (l->dir) { case UP: l->geom.y--; l->geom.h++; l->mark.y--; l->mark.h=1; break; case DOWN: l->geom.h++; // increase length of line -- top stays same l->mark.y+=l->mark.h; l->mark.h=1; break; case LEFT: l->geom.x--; l->geom.w++; l->mark.x--; l->mark.w=1; break; case RIGHT: l->geom.w++; // increase width of line -- left side stays same l->mark.x+=l->mark.w; l->mark.w=1; break; } } else if (check1 == '*' || check2 == '*') { // hit a penguin. kills line. l->dead=true; } else if (check1 == '1' || check2 == '1' || check1 == '2' || check2 == '2') { if (l->stuckcount>LINEMAXSTUCK) { finish=true; } else { l->stuckcount++; // FIX: kludge-o-rama!! // this could work around the irratating thing where // a line gets started 'on top' of another line. but it // is totally repairing the symptom, not the bug. *sigh* //if (l->geom.w==1 || l->geom.h==1) finish=true; } } else { // hit something else finish=true; } if (finish) { markgrid(l->mark.x,l->mark.y,l->mark.w,l->mark.h,l->id); SDL_FillRect(screen,&(l->mark),l->color); soil(l->mark); finishline(l); return(1); } return(0); }
void finishline(Line * l) { int i; int quick1=false; int quick2=false; l->on=false; //printwholegrid(); switch (l->dir) { case DOWN: // falls through. case UP: markgrid(l->geom.x,l->geom.y,l->geom.w,l->geom.h,'|'); SDL_FillRect(screen,&l->geom,SDL_MapRGB(screen->format, 0x00, 0x40, 0x80)); soil(l->geom); // scan along edges to quickly determine if this // is going to be complicated. quick1=true; quick2=true; for (i=l->geom.y+BLOCKHEIGHT/2;i<l->geom.y+l->geom.h;i++) { if (grid[l->geom.x-1][i] != ' ' && grid[l->geom.x-1][i] != '*') quick1=false; if (grid[l->geom.x+BLOCKWIDTH][i] != ' ' && grid[l->geom.x+BLOCKWIDTH][i] != '*') quick2=false; } checkempty(l->geom.x-BLOCKWIDTH/2,l->geom.y+BLOCKHEIGHT/2); checkempty(l->geom.x+BLOCKWIDTH+BLOCKWIDTH/2/2,l->geom.y+BLOCKHEIGHT/2); if (!quick1) for (i=l->geom.y+BLOCKHEIGHT/2+BLOCKHEIGHT;i<l->geom.y+l->geom.h;i+=BLOCKHEIGHT) checkempty(l->geom.x-BLOCKWIDTH/2,i); if (!quick2) for (i=l->geom.y+BLOCKHEIGHT/2+BLOCKHEIGHT;i<l->geom.y+l->geom.h;i+=BLOCKHEIGHT) checkempty(l->geom.x+BLOCKWIDTH+BLOCKWIDTH/2,i); break; case RIGHT: // falls through case LEFT: markgrid(l->geom.x,l->geom.y,l->geom.w,l->geom.h,'-'); SDL_FillRect(screen,&l->geom,SDL_MapRGB(screen->format, 0x00, 0x40, 0x80)); soil(l->geom); // scan along edges to quickly determine if this // is going to be complicated. quick1=true; quick2=true; for (i=l->geom.x+BLOCKWIDTH/2;i<l->geom.x+l->geom.w;i++) { if (grid[i][l->geom.y-1] != ' ' && grid[i][l->geom.y-1] != '*') quick1=false; if (grid[i][l->geom.y+BLOCKHEIGHT] != ' ' && grid[i][l->geom.y+BLOCKHEIGHT] != '*') quick2=false; } checkempty(l->geom.x+BLOCKWIDTH/2,l->geom.y-BLOCKHEIGHT/2); checkempty(l->geom.x+BLOCKWIDTH/2,l->geom.y+BLOCKHEIGHT+BLOCKHEIGHT/2); if (!quick1) for (i=l->geom.x+BLOCKWIDTH/2+BLOCKWIDTH;i<l->geom.x+l->geom.w;i+=BLOCKWIDTH) checkempty(i,l->geom.y-BLOCKHEIGHT/2); if (!quick2) for (i=l->geom.x+BLOCKWIDTH/2+BLOCKWIDTH;i<l->geom.x+l->geom.w;i+=BLOCKWIDTH) checkempty(i,l->geom.y+BLOCKHEIGHT+BLOCKHEIGHT/2); break; } }
int benchmark(void) { int penguincount=MAXPENGUINS; int i; SDL_Event event; SDL_Rect fpsrect; char fpstext[20]; int done = false; Penguin flock[MAXPENGUINS]; Uint32 starttime, endtime, tmptime, framecount, tmpframecount; setupbenchmark(); fpsrect.x=BORDERLEFT; fpsrect.y=BOTTOMSTATUSY; fpsrect.h=CHARHEIGHT*3;; fpsrect.w=CHARWIDTH*2*20; for (i=0;i<penguincount;i++) { flock[i] = createpenguin(); } framecount=0; tmpframecount=0; starttime=SDL_GetTicks(); tmptime=starttime; do { while (pollevent(&event)) { if (event.type == SDL_QUIT) { done=true; } else if (event.type == SDL_MOUSEBUTTONUP) { done=true; } else if (event.type == SDL_KEYUP) { switch(translatekeyevent(&event)) { case KEYCANCEL: done=true; break; default: break; } } } // move (and get old background) for (i=0;i<penguincount;i+=2) { soil(flock[i].geom); // mark the penguin's old position as dirty movepenguin(&flock[i]); soil(flock[i].geom); // mark the penguin's new position as dirty too (it will be soon...) savebehindpenguin(&flock[i]); } // actually draw for (i=0;i<penguincount;i+=2) { drawpenguin(&flock[i]); } // update screen clean(); for (i=0;i<penguincount;i+=2) { erasepenguin(&flock[i]); } if (SDL_GetTicks() >= tmptime+1000) { snprintf(fpstext,20,"FPS: %.2f",((framecount-tmpframecount)*1000.0)/(SDL_GetTicks()-tmptime)); tmptime=SDL_GetTicks(); tmpframecount=framecount; SDL_FillRect(screen,&fpsrect,color.background); puttext(fpsrect.x,fpsrect.y+3,2,color.normaltext,fpstext); soil(fpsrect); } framecount++; } while (!done); endtime=SDL_GetTicks(); if (endtime>starttime) printf("Overall: %.2f frames per second.\n", (framecount*1000.0)/(endtime-starttime) ); clean(); while (penguincount) { penguincount--; deletepenguin(&flock[penguincount]); } return(false); }