// This include is meant to be the body of the function CreateTilemapXX, // which is implemented exactly the same for different resolutions. For // compatibility reasons this is controlled by Defines instead of templates. // Therefor the following type definitions are set to the required values, // while compiling that function: // // #define DATA_TYPE unsigned char #define IMAX 1000 XImage *ximage; Vec2 wcenter; Vec2 dirx,diry,edge; if (page) { if (pm->IsTwinPixmap()) wcenter=Vec2( center.X(), pm->XHeight()+center.Y() ); else wcenter=Vec2( center.X(), center.Y() ); } else wcenter=center; extern int scanline_pad; ximage = img_buf->Init(width,height,scanline_pad/8); if (!itm) { if (page) { dirx=Vec2(-1,0).TurnAngleDeg(windir); diry=Vec2(1,0).TurnLeft().TurnAngleDeg(windir); } else { dirx=Vec2(1,0).TurnAngleDeg(-windir); diry=Vec2(1,0).TurnLeft().TurnAngleDeg(-windir); } edge=wcenter-offx*dirx-offy*diry; } else { dirx=(*itm)*Vec2(1,0); diry=(*itm)*Vec2(0,1); edge=wcenter+(*itm)*Vec2(-offx,-offy); } extern int pixmap_depth; switch(pixmap_depth) { case 24: // // the traditional routine to copy each pixel from one image to the other // with the generic routines. range checking is done in pm's GetPixel() and // there's nothing to worry about (except the time...) // pm->GetImage(); // to make sure the pixmap is valid for (int y=0;yGetPixel( XPix(pt.X()), YPix(pt.Y()) )); pt+=dirx; } } #if 0 for (int y=0;ydata + y * ximage->bytes_per_line); for (int x=0;xGetPixel( XPix(pt.X()), YPix(pt.Y()) ); pt+=dirx; } } #endif break; case 8: case 16: case 32: // // optimized mapping // in a loop in brezenham fashion, each pixel is copied from one buffer to the // other with direct access to the data structure. Since it would be inefficient // to an access outside of the source image on every pixel, only the 4 edges are // check, if the boundary is crossed, a traditional copy with range checking is // done. This happens very seldom, since the buffer for the picture is // large than it has to be, so that only a few flip's will really fall // outside ... XImage *src_image=pm->GetImage(); #ifndef RANGE_CHECK { char *src; char *pic_addr=src_image->data; // image start char *min_addr=pic_addr-pm->offset_bytes; // memory start (including offset) char *max_addr=pic_addr+src_image->bytes_per_line*src_image->height +pm->offset_bytes; // memory end (behind offset) int count=0; Vec2 t=edge; src = (char*)((DATA_TYPE*)(pic_addr+YPix(t.Y())*src_image->bytes_per_line)+XPix(t.X())); if (src=max_addr) count++; t=edge+height*diry; src = (char*)((DATA_TYPE*)(pic_addr+YPix(t.Y())*src_image->bytes_per_line)+XPix(t.X())); if (src=max_addr) count++; t=edge+width*dirx; src = (char*)((DATA_TYPE*)(pic_addr+YPix(t.Y())*src_image->bytes_per_line)+XPix(t.X())); if (src=max_addr) count++; t=edge+height*diry+width*dirx; src = (char*)((DATA_TYPE*)(pic_addr+YPix(t.Y())*src_image->bytes_per_line)+XPix(t.X())); if (src=max_addr) count++; if (count) { DBG0( "*** range overflow -> trying slow mapping\n" ); for (int y=0;ydata + y * ximage->bytes_per_line); for (int x=0;xGetPixel( XPix(pt.X()), YPix(pt.Y()) ); pt+=dirx; } } img_buf->PutImage(dpy,tilemap,DefaultGC(dpy,scr),0,0,0,0,width,height); return; } } #endif int pixels_per_line=src_image->bytes_per_line/sizeof(DATA_TYPE); register int dx=(int)(dirx.X()*IMAX); register int dy=(int)(dirx.Y()*IMAX); for (int y=0;y0)?dx:-dx)/2; register int dy_c = ((dy>0)?dy:-dy)/2; #ifdef RANGE_CHECK register int src_x = XPix(pt.X()); register int src_y = YPix(pt.Y()); # define INC_X src_x++ # define DEC_X src_x-- # define INC_Y src_y++ # define DEC_Y src_y-- #else # define INC_X # define DEC_X # define INC_Y # define DEC_Y #endif register DATA_TYPE *src = (DATA_TYPE*)(src_image->data + YPix(pt.Y()) * src_image->bytes_per_line)+XPix(pt.X()); register DATA_TYPE *dest= (DATA_TYPE*)(ximage->data + y * ximage->bytes_per_line); if (dx>=0) { if (dy>=0) { for (int x=0;x=src_image->width||src_y<0||src_y>=src_image->height) { *dest++ = 0; } else #endif *dest++ = *src; dx_c-=dx; while (dx_c<0) { dx_c+=IMAX; INC_X; src++; } dy_c-=dy; while (dy_c<0) { dy_c+=IMAX; INC_Y; src+=pixels_per_line; } } } else { for (int x=0;x=src_image->width||src_y<0||src_y>=src_image->height) { *dest++ = 0; } else #endif *dest++ = *src; dx_c-=dx; while (dx_c<0) { dx_c+=IMAX; INC_X; src++; } dy_c+=dy; while (dy_c<0) { dy_c+=IMAX; DEC_Y; src-=pixels_per_line; } } } } else { if (dy>=0) { for (int x=0;x=src_image->width||src_y<0||src_y>=src_image->height) { *dest++ = 0; } else #endif *dest++ = *src; dx_c+=dx; while (dx_c<0) { dx_c+=IMAX; DEC_X; src--; } dy_c-=dy; while (dy_c<0) { dy_c+=IMAX; INC_Y; src+=pixels_per_line; } } } else { for (int x=0;x=src_image->width||src_y<0||src_y>=src_image->height) { *dest++ = 0; } else #endif *dest++ = *src; dx_c+=dx; while (dx_c<0) { dx_c+=IMAX; DEC_X; src--; } dy_c+=dy; while (dy_c<0) { dy_c+=IMAX; DEC_Y; src-=pixels_per_line; } } } } } } img_buf->PutImage(dpy,tilemap,DefaultGC(dpy,scr),0,0,0,0,width,height); #undef IMAX