1 2 // This include is meant to be the body of the function CreateTilemapXX, 3 // which is implemented exactly the same for different resolutions. For 4 // compatibility reasons this is controlled by Defines instead of templates. 5 // Therefor the following type definitions are set to the required values, 6 // while compiling that function: 7 // 8 // #define DATA_TYPE unsigned char 9 10 #define IMAX 1000 11 12 XImage *ximage; 13 Vec2 wcenter; 14 Vec2 dirx,diry,edge; 15 16 if (page) { 17 if (pm->IsTwinPixmap()) 18 wcenter=Vec2( center.X(), pm->XHeight()+center.Y() ); 19 else wcenter=Vec2( center.X(), center.Y() ); 20 } 21 else wcenter=center; 22 23 extern int scanline_pad; 24 25 ximage = img_buf->Init(width,height,scanline_pad/8); 26 27 if (!itm) { 28 if (page) { 29 dirx=Vec2(-1,0).TurnAngleDeg(windir); 30 diry=Vec2(1,0).TurnLeft().TurnAngleDeg(windir); 31 } 32 else { 33 dirx=Vec2(1,0).TurnAngleDeg(-windir); 34 diry=Vec2(1,0).TurnLeft().TurnAngleDeg(-windir); 35 } 36 edge=wcenter-offx*dirx-offy*diry; 37 } 38 else { 39 dirx=(*itm)*Vec2(1,0); 40 diry=(*itm)*Vec2(0,1); 41 edge=wcenter+(*itm)*Vec2(-offx,-offy); 42 } 43 44 extern int pixmap_depth; 45 46 switch(pixmap_depth) { 47 case 24: 48 49 // 50 // the traditional routine to copy each pixel from one image to the other 51 // with the generic routines. range checking is done in pm's GetPixel() and 52 // there's nothing to worry about (except the time...) 53 // 54 55 pm->GetImage(); // to make sure the pixmap is valid 56 57 for (int y=0;y<height;y++) { 58 Vec2 pt=edge+y*diry; 59 for (int x=0;x<width;x++) { 60 XPutPixel(ximage,x,y,pm->GetPixel( XPix(pt.X()), YPix(pt.Y()) )); 61 pt+=dirx; 62 } 63 } 64 65 #if 0 66 for (int y=0;y<height;y++) { 67 Vec2 pt=edge+y*diry; 68 /* x,y, dx,dy bestimmen ... */ 69 register DATA_TYPE *dest = (DATA_TYPE*)(ximage->data + y * ximage->bytes_per_line); 70 for (int x=0;x<width;x++) { 71 *dest++ = pm->GetPixel( XPix(pt.X()), YPix(pt.Y()) ); 72 pt+=dirx; 73 } 74 } 75 #endif 76 77 break; 78 case 8: 79 case 16: 80 case 32: 81 82 // 83 // optimized mapping 84 // in a loop in brezenham fashion, each pixel is copied from one buffer to the 85 // other with direct access to the data structure. Since it would be inefficient 86 // to an access outside of the source image on every pixel, only the 4 edges are 87 // check, if the boundary is crossed, a traditional copy with range checking is 88 // done. This happens very seldom, since the buffer for the picture is 89 // large than it has to be, so that only a few flip's will really fall 90 // outside ... 91 92 XImage *src_image=pm->GetImage(); 93 94 #ifndef RANGE_CHECK 95 { 96 char *src; 97 char *pic_addr=src_image->data; // image start 98 char *min_addr=pic_addr-pm->offset_bytes; // memory start (including offset) 99 char *max_addr=pic_addr+src_image->bytes_per_line*src_image->height 100 +pm->offset_bytes; // memory end (behind offset) 101 int count=0; 102 103 Vec2 t=edge; 104 src = (char*)((DATA_TYPE*)(pic_addr+YPix(t.Y())*src_image->bytes_per_line)+XPix(t.X())); 105 if (src<min_addr||src>=max_addr) count++; 106 t=edge+height*diry; 107 src = (char*)((DATA_TYPE*)(pic_addr+YPix(t.Y())*src_image->bytes_per_line)+XPix(t.X())); 108 if (src<min_addr||src>=max_addr) count++; 109 t=edge+width*dirx; 110 src = (char*)((DATA_TYPE*)(pic_addr+YPix(t.Y())*src_image->bytes_per_line)+XPix(t.X())); 111 if (src<min_addr||src>=max_addr) count++; 112 t=edge+height*diry+width*dirx; 113 src = (char*)((DATA_TYPE*)(pic_addr+YPix(t.Y())*src_image->bytes_per_line)+XPix(t.X())); 114 if (src<min_addr||src>=max_addr) count++; 115 116 if (count) { 117 DBG0( "*** range overflow -> trying slow mapping\n" ); 118 119 for (int y=0;y<height;y++) { 120 Vec2 pt=edge+y*diry; 121 /* x,y, dx,dy bestimmen ... */ 122 register DATA_TYPE *dest = (DATA_TYPE*)(ximage->data + y * ximage->bytes_per_line); 123 for (int x=0;x<width;x++) { 124 *dest++ = (DATA_TYPE)pm->GetPixel( XPix(pt.X()), YPix(pt.Y()) ); 125 pt+=dirx; 126 } 127 } 128 img_buf->PutImage(dpy,tilemap,DefaultGC(dpy,scr),0,0,0,0,width,height); 129 return; 130 } 131 } 132 #endif 133 134 int pixels_per_line=src_image->bytes_per_line/sizeof(DATA_TYPE); 135 136 register int dx=(int)(dirx.X()*IMAX); 137 register int dy=(int)(dirx.Y()*IMAX); 138 139 for (int y=0;y<height;y++) { 140 Vec2 pt=edge+y*diry; 141 /* x,y, dx,dy bestimmen ... */ 142 register int dx_c = ((dx>0)?dx:-dx)/2; 143 register int dy_c = ((dy>0)?dy:-dy)/2; 144 #ifdef RANGE_CHECK 145 register int src_x = XPix(pt.X()); 146 register int src_y = YPix(pt.Y()); 147 # define INC_X src_x++ 148 # define DEC_X src_x-- 149 # define INC_Y src_y++ 150 # define DEC_Y src_y-- 151 #else 152 # define INC_X 153 # define DEC_X 154 # define INC_Y 155 # define DEC_Y 156 #endif 157 158 register DATA_TYPE *src = (DATA_TYPE*)(src_image->data + YPix(pt.Y()) * src_image->bytes_per_line)+XPix(pt.X()); 159 register DATA_TYPE *dest= (DATA_TYPE*)(ximage->data + y * ximage->bytes_per_line); 160 if (dx>=0) { 161 if (dy>=0) { 162 for (int x=0;x<width;x++) { 163 #ifdef RANGE_CHECK 164 if (src_x<0||src_x>=src_image->width||src_y<0||src_y>=src_image->height) { 165 *dest++ = 0; 166 } 167 else 168 #endif 169 *dest++ = *src; 170 171 dx_c-=dx; 172 while (dx_c<0) { dx_c+=IMAX; INC_X; src++; } 173 dy_c-=dy; 174 while (dy_c<0) { dy_c+=IMAX; INC_Y; src+=pixels_per_line; } 175 } 176 } 177 else { 178 for (int x=0;x<width;x++) { 179 #ifdef RANGE_CHECK 180 if (src_x<0||src_x>=src_image->width||src_y<0||src_y>=src_image->height) { 181 *dest++ = 0; 182 } 183 else 184 #endif 185 *dest++ = *src; 186 187 dx_c-=dx; 188 while (dx_c<0) { dx_c+=IMAX; INC_X; src++; } 189 dy_c+=dy; 190 while (dy_c<0) { dy_c+=IMAX; DEC_Y; src-=pixels_per_line; } 191 } 192 } 193 } 194 else { 195 if (dy>=0) { 196 for (int x=0;x<width;x++) { 197 #ifdef RANGE_CHECK 198 if (src_x<0||src_x>=src_image->width||src_y<0||src_y>=src_image->height) { 199 *dest++ = 0; 200 } 201 else 202 #endif 203 *dest++ = *src; 204 205 dx_c+=dx; 206 while (dx_c<0) { dx_c+=IMAX; DEC_X; src--; } 207 dy_c-=dy; 208 while (dy_c<0) { dy_c+=IMAX; INC_Y; src+=pixels_per_line; } 209 } 210 } 211 else { 212 for (int x=0;x<width;x++) { 213 #ifdef RANGE_CHECK 214 if (src_x<0||src_x>=src_image->width||src_y<0||src_y>=src_image->height) { 215 *dest++ = 0; 216 } 217 else 218 #endif 219 *dest++ = *src; 220 221 dx_c+=dx; 222 while (dx_c<0) { dx_c+=IMAX; DEC_X; src--; } 223 dy_c+=dy; 224 while (dy_c<0) { dy_c+=IMAX; DEC_Y; src-=pixels_per_line; } 225 } 226 } 227 } 228 } 229 } 230 231 img_buf->PutImage(dpy,tilemap,DefaultGC(dpy,scr),0,0,0,0,width,height); 232 233 #undef IMAX 234