#include #include #include #include #include "bomber.h" #include "gfx.h" #define MAXCOLORS 256 int usedcolors=0; SDL_Surface *thescreen; SDL_Color themap[256]; uchar *videomem; int stride; int mousex,mousey,mouseb; uchar mustlock=0,locked=0; uchar *block64; int buttonstate=0,buttondown=0; int mxpos,mypos; int pressedcodes[KEYMAX],downcodes[KEYMAX],numpressed,numdown; void dumpgfx() { usedcolors = 0; } int bestmatch(int red,int green,int blue) { int i; int bestcolor,bestdelta=0; int rdelta,gdelta,bdelta; int delta; i=0; bestcolor=-1; while(igs_pic; for(i=0;i<256;i++) counts[i]=0; i=gs->gs_xsize*gs->gs_ysize; while(i--) counts[*p++]++; cnt=0; gs->gs_inout[0]=0; for(i=1;i<256;i++) { if(counts[i]) { cnt++; p=gs->gs_colormap+i+i+i; red=*p++; green=*p++; blue=*p++; for(j=0;jgs_inout[i]=j; break; } } if(j==usedcolors) { if(usedcolorsgs_inout[i]=usedcolors; ++usedcolors; } else gs->gs_inout[i]=bestmatch(red,green,blue); } } } updatemap(); } uchar *compressfig(uchar *put,gfxset *gs, int sourcex,int sourcey,int sizex,int sizey) { int j,gswidth; uchar *p, *p2,pixel,*map1; int dx,dy; gswidth=gs->gs_xsize; map1=gs->gs_inout; p=gs->gs_pic+sourcex+gswidth*sourcey; for(dy=0;dygs_inout; gswidth=gs->gs_xsize; p=gs->gs_pic+sourcex+gswidth*sourcey; minx=miny=maxx=maxy=-1; for(dy=0;dymaxy) maxy=ty; tx=sourcex+dx; if(minx==-1 || txmaxx) maxx=tx; } p+=gswidth; } if(minx==-1) { minx=maxx=sourcex; miny=maxy=sourcey; } fig->xdelta=minx-sourcex; fig->ydelta=miny-sourcey; sourcex=minx; sourcey=miny; fig->xsize=sizex=maxx-minx+1; fig->ysize=sizey=maxy-miny+1; p=compressfig(block64,gs,sourcex,sourcey,sizex,sizey); fig->graphics=malloc(p-block64); if(fig->graphics) memcpy(fig->graphics,block64,p-block64); } //(gfxset *gs,figure *fig,int sourcex,int sourcey,int sizex,int sizey) void gfxfetch(gfxset *gs,figure *fig,int num) { int x,y; int xsize,ysize; int fxsize,fysize; unsigned char *p,*p2; xsize=gs->gs_xsize; ysize=gs->gs_ysize; p2=p=gs->gs_pic+xsize+1; fxsize=2; while(*p++==0) ++fxsize; fysize=2; while(*p2==0) ++fysize,p2+=xsize; x=fxsize; y=0; while(num--) { gfxfetchsingle(fig,gs,x,y,fxsize,fysize); x+=fxsize; if(x>xsize-fxsize) { x=0; y+=fysize; if(y>ysize-fysize) y=0; } fig++; } } void solidfetch(gfxset *gs,solid *dest) { int xsize,ysize; int i; unsigned char *p,*map; uchar *gfx; memset(dest,0,sizeof(solid)); xsize=gs->gs_xsize; ysize=gs->gs_ysize; i=xsize*ysize; gfx=dest->graphics=malloc(i); if(!gfx) return; dest->xsize=xsize; dest->ysize=ysize; map=gs->gs_inout; memcpy(gfx,gs->gs_pic,i); p=gfx; while(i--) { if(*p) *p=map[*p]; ++p; } } void solidcopyany(solid *src,solid *dest,int destx,int desty,int sizex,int sizey) { int xmax,ymax; int j; uchar *p1,*p2; int w; xmax=src->xsize; ymax=src->ysize; if(destx>=xmax || desty>=ymax || destx+sizex<=0 || desty+sizey<=0) return; if(destx<0) { sizex+=destx; destx=0; } if(desty<0) { sizey+=desty; desty=0; } if(destx+sizex>xmax) sizex=xmax-destx; if(desty+sizey>ymax) sizey=ymax-desty; if(dest) { w=dest->xsize; p1=dest->graphics+desty*w+destx; } else { gfxlock(); w=stride; p1=videomem+desty*stride+destx; } p2=src->graphics+desty*xmax+destx; for(j=0;jgraphics; if(dest) { w=clipx=dest->xsize; clipy=dest->ysize; pc=dest->graphics; } else { gfxlock(); w=stride; clipx=IXSIZE; clipy=IYSIZE; pc=videomem; } dx=fig->xdelta; dy=fig->ydelta; xsize=fig->xsize; ysize=fig->ysize; x+=dx; y+=dy; if(x>=0 && y>=0 && x<=clipx-xsize && y<=clipy-ysize) { while((run=*take++)) { dx=*((signed char *)take); ++take; dy=*((signed char *)take); ++take; p=pc+w*(y+dy)+x+dx; while(run--) *p++=*take++; } } else { while((run=*take++)) { dx=*((signed char *)take); ++take; dy=*((signed char *)take); ++take; dx+=x; dy+=y; p2=take; take+=run; if(dy<0 || dy>=clipy) continue; if(dx>=clipx) continue; if(dx<0) { p2-=dx; run+=dx; dx=0; } else if(dx+run>clipx) run=clipx-dx; p=pc+w*dy+dx; if(run) memcpy(p,p2,run); } } } void drawfigure(int destx,int desty,figure *fig) { drawfigureany(destx,desty,fig,0); } void copyup() { gfxunlock(); SDL_UpdateRect(thescreen, 0, 0, 0, 0); needwhole=0; } void copyupxy(int x,int y) { gfxunlock(); SDL_UpdateRect(thescreen,x,y,24,24); } void copyupxysize(int x,int y,int xsize,int ysize) { gfxunlock(); SDL_UpdateRect(thescreen,x,y,xsize,ysize); } void set_color(int color, int red, int green, int blue) { themap[color].r=red; themap[color].g=green; themap[color].b=blue; } void opengfx(int argc, char **argv) { unsigned long videoflags; themap[0].r=0; themap[0].g=0; themap[0].b=0; usedcolors=1; block64=malloc(65536); if(!block64) { printf("Couldn't allocate block64\n"); exit(50); } if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO) < 0 ) { fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); exit(1); } videoflags = SDL_SWSURFACE|SDL_HWPALETTE; //|SDL_FULLSCREEN; thescreen = SDL_SetVideoMode(IXSIZE, IYSIZE, 8, videoflags); if ( thescreen == NULL ) { fprintf(stderr, "Couldn't set display mode: %s\n", SDL_GetError()); SDL_Quit(); exit(5); } stride=thescreen->pitch; videomem=thescreen->pixels; mustlock=SDL_MUSTLOCK(thescreen); locked=0; SDL_ShowCursor(0); } void closegfx(void) { SDL_Quit(); } int checkpressed(int code) { int *p,i; i=numpressed; p=pressedcodes; while(i--) if(*p++==code) return 1; return 0; } int checkdown(int code) { int *p,i; i=numdown; p=downcodes; while(i--) if(*p++==code) return 1; return 0; } int checkbutton(int button) { return buttonstate & (1<', SDLK_COMMA,'<', SDLK_BACKQUOTE,'~', SDLK_BACKSPACE,8, SDLK_TAB,9, SDLK_DELETE,MYDELETE, SDLK_RETURN,13, SDLK_F1,MYF1+MYSHIFTED, SDLK_F2,MYF2+MYSHIFTED, SDLK_F3,MYF3+MYSHIFTED, SDLK_F4,MYF4+MYSHIFTED, SDLK_F5,MYF5+MYSHIFTED, SDLK_F6,MYF6+MYSHIFTED, SDLK_F7,MYF7+MYSHIFTED, SDLK_F8,MYF8+MYSHIFTED, SDLK_F9,MYF9+MYSHIFTED, SDLK_F10,MYF10+MYSHIFTED, SDLK_ESCAPE,0x1b, SDLK_LEFT,MYLEFT+MYSHIFTED, SDLK_RIGHT,MYRIGHT+MYSHIFTED, SDLK_UP,MYUP+MYSHIFTED, SDLK_DOWN,MYDOWN+MYSHIFTED, SDLK_PAGEUP,MYPAGEUP, SDLK_PAGEDOWN,MYPAGEDOWN, SDLK_SPACE,' ', SDLK_HOME,MYHOME, SDLK_END,MYEND, SDLK_LALT,MYALTL, SDLK_RALT,MYALTR, ENDMARK }; int looklist(int code,int *list) { while(*list!=ENDMARK) { if(*list==code) return list[1]; list+=2; } return -1; } int mapkey(int code,int qual) { if(qual & KMOD_SHIFT) code=looklist(code,sdlinoutshifted); else code=looklist(code,sdlinoutnormal); if(code<0) return -1; if(qual & KMOD_ALT) code|=MYALTED; return code; } void markkey(int code,int status) { int i; int *ip; if(status) { if(numdown>1; mousey=event.button.y>>1; mouseb=bs; break; case SDL_MOUSEBUTTONDOWN: bs|=1<<(event.button.button-1); mousex=event.button.x>>1; mousey=event.button.y>>1; mouseb=bs; break; case SDL_MOUSEMOTION: mousex=event.motion.x>>1; mousey=event.motion.y>>1; break; case SDL_QUIT: exitflag = 1; break; } } } /* void scaninput() { int i,*ip,code; numdown=0; buttondown=0; while(XCheckMaskEvent(dp,~0,&event)) switch(event.type) { case KeyPress: code=XLookupKeysym(keyevent,0); if(numdownbutton; buttonstate|=i; buttondown|=i; break; case ButtonRelease: buttonstate&=~(1<button); break; case MotionNotify: mxpos=motionevent->x; mypos=motionevent->y; break; case Expose: copyup(); needwhole=0; break; case FocusOut: numpressed=0; break; } } */ void drawrect(int x,int y,int xs,int ys,int c) { uchar *p; gfxlock(); p=videomem+y*stride+x; while(ys--) { memset(p,c,xs); p+=stride; } } void greyrect(int x,int y,int xsize,int ysize) { static int greycolor=-1; if(greycolor==-1) greycolor=bestmatch(0,0,0x70); drawrect(x,y,xsize,ysize,greycolor); } void clear() { int j; uchar *p; gfxlock(); p=videomem; for(j=0;j