00001
00017
00018
00019 #include "draw_map.h"
00020
00021 #include <math.h>
00022 #include "globals.h"
00023 #include "memfile.h"
00024 #include "obj_cube.h"
00025 #include "obj_slabs.h"
00026 #include "lev_data.h"
00027 #include "lev_files.h"
00028 #include "lev_column.h"
00029 #include "obj_column.h"
00030 #include "obj_things.h"
00031 #include "xcubtxtr.h"
00032 #include "xtabdat8.h"
00033 #include "xtabjty.h"
00034
00040 struct PALETTE_ENTRY owned_area_palette_intns[] =
00041 { {63,24,11,0}, {47,31,63,0}, {54,63,26,0}, {63,59,0,0}, {52,47,42,0}, {0,0,0,0}, };
00047 struct PALETTE_ENTRY owned_area_palette_std[] =
00048
00049 { {186,72,30,0}, {120,78,162,0}, {138,162,66,0}, {186,154,0,0}, {132,114,102,0}, {0,0,0,0}, };
00055 struct PALETTE_ENTRY owned_area_palette_weak[] =
00056
00057 { {62,24,10,0}, {40,26,54,0}, {46,54,22,0}, {62,55,0,0}, {44,38,34,0}, {0,0,0,0}, };
00058
00064 struct PALETTE_ENTRY intense_slab_palette_intns[] =
00065
00066 { {248,80,136,0}, {224,224,16,0}, };
00072 struct PALETTE_ENTRY intense_slab_palette_std[] =
00073
00074 { {124,40,68,0}, {112,112,8,0}, };
00075
00076 #define THINGCIRCLE_PALETTE_SIZE 14
00077
00081 struct PALETTE_ENTRY minimap_owned_ground[] =
00082 { {208,84,16,0}, {216,180,232,0}, {96,152,28,0}, {208,208,16,0}, {208,216,160,0}, {216,216,216,0}, };
00083
00087 struct PALETTE_ENTRY minimap_owned_room[] =
00088 { {244,88,16,0}, {248,216,252,0}, {100,180,36,0}, {252,252,16,0}, {252,248,196,0}, {255,255,255,0}, };
00089
00093 struct PALETTE_ENTRY minimap_walldoor[] =
00094
00095 { {112,88,60,0}, {224,236,136,0}, {252,208,152,0}, };
00096
00100 struct PALETTE_ENTRY minimap_pathliquid[] =
00101
00102 { {96,72,28,0}, {140,112,104,0}, {100,60,16,0}, };
00103
00107 struct PALETTE_ENTRY minimap_gold[] =
00108 { {140,136,36,0}, {140,136,36,0}, {160,132,36,0}, {160,136,40,0}, {140,128,28,0}, };
00109
00113 struct PALETTE_ENTRY minimap_rock[] =
00114 { {16,16,16,0}, {20,12,16,0}, {12,20,16,0}, {16,12,20,0}, {18,14,18,0}, };
00115
00119 struct PALETTE_ENTRY minimap_earth[] =
00120 { {56,48,16,0}, {48,44,16,0}, {60,48,16,0}, {72,50,16,0}, {72,56,16,0}, };
00121
00122 struct PALETTE_ENTRY thingcircle_palette_std[] =
00123 { {176,176,176,0},
00124 {224,224, 0,0},
00125 {255,255,255,0},
00126 { 0, 96,255,0},
00127 { 16,255, 16,0},
00128 { 16,255, 16,0},
00129 {176,176,176,0},
00130 { 48, 96,255,0},
00131 {255, 32, 32,0},
00132 {255, 0,255,0},
00133 {176,176,176,0},
00134 {176,176,176,0},
00135 { 0, 96,255,0},
00136 { 0, 96,255,0},
00137 };
00138
00139 struct PALETTE_ENTRY thingcircle_palette_weak[] =
00140 { { 88, 88, 88,0},
00141 { 48, 48, 8,0},
00142 {128,128,128,0},
00143 { 0, 48,128,0},
00144 { 8,128, 8,0},
00145 { 8,128, 8,0},
00146 { 88, 88, 88,0},
00147 { 8, 8,128,0},
00148 {128, 16, 16,0},
00149 {128, 0,128,0},
00150 { 88, 88, 88,0},
00151 { 88, 88, 88,0},
00152 { 0, 48,128,0},
00153 { 0, 48,128,0},
00154 };
00155
00161 struct PALETTE_ENTRY intense_slab_palette_weak[] =
00162
00163 { {62,20,34,0}, {56,56,4,0}, };
00164
00165 const char *palette_fname="palette.dat";
00166 const char *cube_fname="cube.dat";
00167 const char *tmapanim_fname="tmapanim.dat";
00168
00169 struct MAPDRAW_DATA *glb_draw_data;
00170
00171 inline void mdrand_setpos(struct MAPDRAW_DATA *draw_data,int sx,int sy)
00172 {
00173 draw_data->rand_subtl.x=sx;
00174 draw_data->rand_subtl.y=sy;
00175 draw_data->rand_count=0;
00176 glb_draw_data=draw_data;
00177 }
00178
00179 inline unsigned int mdrand_t8(struct MAPDRAW_DATA *draw_data,int tx,int ty,const unsigned int range)
00180 {
00181 if ((draw_data->rand_subtl.x!=tx*MAP_SUBNUM_X) || (draw_data->rand_subtl.y!=ty*MAP_SUBNUM_Y))
00182 {
00183 draw_data->rand_subtl.x=tx*MAP_SUBNUM_X;
00184 draw_data->rand_subtl.y=ty*MAP_SUBNUM_Y;
00185 draw_data->rand_count=0;
00186 glb_draw_data=draw_data;
00187 }
00188 int idx=((ty*MAP_SUBNUM_Y)*draw_data->subsize.x + tx*MAP_SUBNUM_X)*sizeof(int)+draw_data->rand_count;
00189 draw_data->rand_count++;
00190 return (draw_data->rand_pool[idx%draw_data->rand_size]%range);
00191 }
00192
00193 inline unsigned int mdrand_s8(struct MAPDRAW_DATA *draw_data,int sx,int sy,const unsigned int range)
00194 {
00195 if ((draw_data->rand_subtl.x!=sx) || (draw_data->rand_subtl.y!=sy))
00196 {
00197 draw_data->rand_subtl.x=sx;
00198 draw_data->rand_subtl.y=sy;
00199 draw_data->rand_count=0;
00200 glb_draw_data=draw_data;
00201 }
00202 int idx=((sy)*draw_data->subsize.x + sx)*sizeof(int)+draw_data->rand_count;
00203 draw_data->rand_count++;
00204 return (draw_data->rand_pool[idx%draw_data->rand_size]%range);
00205 }
00206
00207 inline unsigned int mdrand_nx8(struct MAPDRAW_DATA *draw_data,const unsigned int range)
00208 {
00209 int idx=((draw_data->rand_subtl.y)*draw_data->subsize.x + draw_data->rand_subtl.x)*sizeof(int)+draw_data->rand_count;
00210 draw_data->rand_count++;
00211 return (draw_data->rand_pool[idx%draw_data->rand_size]%range);
00212 }
00213
00214 inline unsigned int mdrand_g8(const unsigned int range)
00215 {
00216 int idx=((glb_draw_data->rand_subtl.y)*glb_draw_data->subsize.x + glb_draw_data->rand_subtl.x)*sizeof(int)+glb_draw_data->rand_count;
00217 glb_draw_data->rand_count++;
00218 return (glb_draw_data->rand_pool[idx%glb_draw_data->rand_size]%range);
00219 }
00220
00221 inline void mdrand_g8_waste(const unsigned int num)
00222 {
00223 glb_draw_data->rand_count+=num;
00224 }
00225
00226
00234 short load_palette(struct PALETTE_ENTRY *pal,char *fname)
00235 {
00236 message_log(" load_palette: Starting");
00237
00238 struct MEMORY_FILE *mem;
00239 short result;
00240 result = memfile_readnew(&mem,fname,MAX_FILE_SIZE);
00241 if (result != MFILE_OK)
00242 return result;
00243
00244 if ((mem->len!=256*3))
00245 {
00246 memfile_free(&mem);
00247 return ERR_FILE_BADDATA;
00248 }
00249
00250 int i;
00251 for (i=0; i<256; i++)
00252 {
00253 unsigned int item_pos=i*3;
00254 pal[i].b=mem->content[item_pos+2];
00255 pal[i].g=mem->content[item_pos+1];
00256 pal[i].r=mem->content[item_pos+0];
00257 pal[i].o=0;
00258 }
00259 memfile_free(&mem);
00260 message_log(" load_palette: Finished");
00261 return ERR_NONE;
00262 }
00263
00271 inline void draw_pixel_exact_offs(unsigned char *dest,
00272 const unsigned long offset,const struct PALETTE_ENTRY *color)
00273 {
00274 dest[offset+0]=color->b;
00275 dest[offset+1]=color->g;
00276 dest[offset+2]=color->r;
00277 }
00278
00286 inline void draw_pixel_mul_offs(unsigned char *dest,
00287 const unsigned long offset,const struct PALETTE_ENTRY *color)
00288 {
00289 unsigned short nvalr,nvalg,nvalb;
00290 nvalb=(dest[offset+0]);
00291 nvalg=(dest[offset+1]);
00292 nvalr=(dest[offset+2]);
00293 unsigned short sum=nvalr+nvalg+nvalb;
00294 dest[offset+0]=min(nvalb+((sum*color->b)>>10),255);
00295 dest[offset+1]=min(nvalg+((sum*color->g)>>10),255);
00296 dest[offset+2]=min(nvalr+((sum*color->r)>>10),255);
00297 }
00298
00307 inline void draw_pixel_x4walpha_offs(unsigned char *dest,
00308 const unsigned long offset,const unsigned short alpha,
00309 const struct PALETTE_ENTRY *color)
00310 {
00311 unsigned short nvalr,nvalg,nvalb;
00312 nvalb=(dest[offset+0]);
00313 nvalg=(dest[offset+1]);
00314 nvalr=(dest[offset+2]);
00315 dest[offset+0]=(alpha*nvalb+(255-alpha)*(color->b<<2))>>8;
00316 dest[offset+1]=(alpha*nvalg+(255-alpha)*(color->g<<2))>>8;
00317 dest[offset+2]=(alpha*nvalr+(255-alpha)*(color->r<<2))>>8;
00318 }
00319
00330 inline void draw_circle_fill(unsigned char *dest,const struct IPOINT_2D dest_pos,
00331 const struct IPOINT_2D dest_size,const unsigned int dest_scanln,
00332 const struct PALETTE_ENTRY *bcolor,const struct PALETTE_ENTRY *fcolor,
00333 int radius)
00334 {
00335 unsigned long n=0;
00336 long invradius=(1/(float)radius)*0x10000L;
00337 int dx=0,dy=radius;
00338 if ((dy>15)||(dy==1)) dy--;
00339 int i;
00340 int dxoffset,dyoffset;
00341 unsigned int offset = dest_pos.y*dest_scanln;
00342
00343 while (dx<=dy)
00344 {
00345 dxoffset = dest_scanln*dx;
00346 dyoffset = dest_scanln*dy;
00347
00348 i=dy;
00349 {
00350 int pos;
00351 if ((dest_pos.y-dx>=0)&&(dest_pos.y-dx<dest_size.y))
00352 {
00353 pos=dest_pos.x+i ;
00354 if ((pos>=0)&&(pos<dest_size.x))
00355 draw_pixel_exact_offs(dest,offset+3*pos-dxoffset,bcolor);
00356 pos=dest_pos.x-i ;
00357 if ((pos>=0)&&(pos<dest_size.x))
00358 draw_pixel_exact_offs(dest,offset+3*pos-dxoffset,bcolor);
00359 }
00360 if ((dest_pos.y-i>=0)&&(dest_pos.y-i<dest_size.y))
00361 {
00362 pos=dest_pos.x+dx;
00363 if ((pos>=0)&&(pos<dest_size.x))
00364 draw_pixel_exact_offs(dest,offset+3*pos-dyoffset,bcolor);
00365 pos=dest_pos.x-dx;
00366 if ((pos>=0)&&(pos<dest_size.x))
00367 draw_pixel_exact_offs(dest,offset+3*pos-dyoffset,bcolor);
00368 }
00369 if ((dest_pos.y+dx>=0)&&(dest_pos.y+dx<dest_size.y))
00370 {
00371 pos=dest_pos.x-i ;
00372 if ((pos>=0)&&(pos<dest_size.x))
00373 draw_pixel_exact_offs(dest,offset+3*pos+dxoffset,bcolor);
00374 pos=dest_pos.x+i ;
00375 if ((pos>=0)&&(pos<dest_size.x))
00376 draw_pixel_exact_offs(dest,offset+3*pos+dxoffset,bcolor);
00377 }
00378 if ((dest_pos.y+i>=0)&&(dest_pos.y+i<dest_size.y))
00379 {
00380 pos=dest_pos.x-dx;
00381 if ((pos>=0)&&(pos<dest_size.x))
00382 draw_pixel_exact_offs(dest,offset+3*pos+dyoffset,bcolor);
00383 pos=dest_pos.x+dx;
00384 if ((pos>=0)&&(pos<dest_size.x))
00385 draw_pixel_exact_offs(dest,offset+3*pos+dyoffset,bcolor);
00386 }
00387 }
00388 i--;dyoffset-=dest_scanln;
00389
00390 for(;i>=dx;i--,dyoffset-=dest_scanln)
00391 {
00392 int pos;
00393 if ((dest_pos.y-dx>=0)&&(dest_pos.y-dx<dest_size.y))
00394 {
00395 pos=dest_pos.x+i ;
00396 if ((pos>=0)&&(pos<dest_size.x))
00397 draw_pixel_exact_offs(dest,offset+3*pos-dxoffset,fcolor);
00398 pos=dest_pos.x-i ;
00399 if ((pos>=0)&&(pos<dest_size.x))
00400 draw_pixel_exact_offs(dest,offset+3*pos-dxoffset,fcolor);
00401 }
00402 if ((dest_pos.y-i>=0)&&(dest_pos.y-i<dest_size.y))
00403 {
00404 pos=dest_pos.x+dx;
00405 if ((pos>=0)&&(pos<dest_size.x))
00406 draw_pixel_exact_offs(dest,offset+3*pos-dyoffset,fcolor);
00407 pos=dest_pos.x-dx;
00408 if ((pos>=0)&&(pos<dest_size.x))
00409 draw_pixel_exact_offs(dest,offset+3*pos-dyoffset,fcolor);
00410 }
00411 if ((dest_pos.y+dx>=0)&&(dest_pos.y+dx<dest_size.y))
00412 {
00413 pos=dest_pos.x-i ;
00414 if ((pos>=0)&&(pos<dest_size.x))
00415 draw_pixel_exact_offs(dest,offset+3*pos+dxoffset,fcolor);
00416 pos=dest_pos.x+i ;
00417 if ((pos>=0)&&(pos<dest_size.x))
00418 draw_pixel_exact_offs(dest,offset+3*pos+dxoffset,fcolor);
00419 }
00420 if ((dest_pos.y+i>=0)&&(dest_pos.y+i<dest_size.y))
00421 {
00422 pos=dest_pos.x-dx;
00423 if ((pos>=0)&&(pos<dest_size.x))
00424 draw_pixel_exact_offs(dest,offset+3*pos+dyoffset,fcolor);
00425 pos=dest_pos.x+dx;
00426 if ((pos>=0)&&(pos<dest_size.x))
00427 draw_pixel_exact_offs(dest,offset+3*pos+dyoffset,fcolor);
00428 }
00429 }
00430 {
00431 dx++;
00432 n+=invradius;
00433 if ((n>>6)>=SIN_ACOS_SIZE) break;
00434 dy = (int)((radius * (glb_draw_data->sin_acos[(int)(n>>6)])) >> 16);
00435 }
00436 }
00437 }
00438
00449 inline void draw_circle_mul(unsigned char *dest,const struct IPOINT_2D dest_pos,
00450 const struct IPOINT_2D dest_size,const unsigned int dest_scanln,
00451 const struct PALETTE_ENTRY *bcolor,const struct PALETTE_ENTRY *fcolor,
00452 int radius)
00453 {
00454 unsigned long n=0;
00455 long invradius=(1/(float)radius)*0x10000L;
00456 int dx=0,dy=radius;
00457 if ((dy>15)||(dy==1)) dy--;
00458 int i;
00459 int dxoffset,dyoffset;
00460 unsigned int offset = dest_pos.y*dest_scanln;
00461
00462 while (dx<=dy)
00463 {
00464 dxoffset = dest_scanln*dx;
00465 dyoffset = dest_scanln*dy;
00466
00467 i=dy;
00468 {
00469 int pos;
00470 if ((dest_pos.y-dx>=0)&&(dest_pos.y-dx<dest_size.y))
00471 {
00472 pos=dest_pos.x+i ;
00473 if ((pos>=0)&&(pos<dest_size.x))
00474 draw_pixel_mul_offs(dest,offset+3*pos-dxoffset,bcolor);
00475 pos=dest_pos.x-i ;
00476 if ((pos>=0)&&(pos<dest_size.x))
00477 draw_pixel_mul_offs(dest,offset+3*pos-dxoffset,bcolor);
00478 }
00479 if ((dest_pos.y-i>=0)&&(dest_pos.y-i<dest_size.y))
00480 {
00481 pos=dest_pos.x+dx;
00482 if ((pos>=0)&&(pos<dest_size.x))
00483 draw_pixel_mul_offs(dest,offset+3*pos-dyoffset,bcolor);
00484 pos=dest_pos.x-dx;
00485 if ((pos>=0)&&(pos<dest_size.x))
00486 draw_pixel_mul_offs(dest,offset+3*pos-dyoffset,bcolor);
00487 }
00488 if ((dest_pos.y+dx>=0)&&(dest_pos.y+dx<dest_size.y))
00489 {
00490 pos=dest_pos.x-i ;
00491 if ((pos>=0)&&(pos<dest_size.x))
00492 draw_pixel_mul_offs(dest,offset+3*pos+dxoffset,bcolor);
00493 pos=dest_pos.x+i ;
00494 if ((pos>=0)&&(pos<dest_size.x))
00495 draw_pixel_mul_offs(dest,offset+3*pos+dxoffset,bcolor);
00496 }
00497 if ((dest_pos.y+i>=0)&&(dest_pos.y+i<dest_size.y))
00498 {
00499 pos=dest_pos.x-dx;
00500 if ((pos>=0)&&(pos<dest_size.x))
00501 draw_pixel_mul_offs(dest,offset+3*pos+dyoffset,bcolor);
00502 pos=dest_pos.x+dx;
00503 if ((pos>=0)&&(pos<dest_size.x))
00504 draw_pixel_mul_offs(dest,offset+3*pos+dyoffset,bcolor);
00505 }
00506 }
00507 i--;dyoffset-=dest_scanln;
00508
00509 for(;i>=dx;i--,dyoffset-=dest_scanln)
00510 {
00511 int pos;
00512 if ((dest_pos.y-dx>=0)&&(dest_pos.y-dx<dest_size.y))
00513 {
00514 pos=dest_pos.x+i ;
00515 if ((pos>=0)&&(pos<dest_size.x))
00516 draw_pixel_mul_offs(dest,offset+3*pos-dxoffset,fcolor);
00517 pos=dest_pos.x-i ;
00518 if ((pos>=0)&&(pos<dest_size.x))
00519 draw_pixel_mul_offs(dest,offset+3*pos-dxoffset,fcolor);
00520 }
00521 if ((dest_pos.y-i>=0)&&(dest_pos.y-i<dest_size.y))
00522 {
00523 pos=dest_pos.x+dx;
00524 if ((pos>=0)&&(pos<dest_size.x))
00525 draw_pixel_mul_offs(dest,offset+3*pos-dyoffset,fcolor);
00526 pos=dest_pos.x-dx;
00527 if ((pos>=0)&&(pos<dest_size.x))
00528 draw_pixel_mul_offs(dest,offset+3*pos-dyoffset,fcolor);
00529 }
00530 if ((dest_pos.y+dx>=0)&&(dest_pos.y+dx<dest_size.y))
00531 {
00532 pos=dest_pos.x-i ;
00533 if ((pos>=0)&&(pos<dest_size.x))
00534 draw_pixel_mul_offs(dest,offset+3*pos+dxoffset,fcolor);
00535 pos=dest_pos.x+i ;
00536 if ((pos>=0)&&(pos<dest_size.x))
00537 draw_pixel_mul_offs(dest,offset+3*pos+dxoffset,fcolor);
00538 }
00539 if ((dest_pos.y+i>=0)&&(dest_pos.y+i<dest_size.y))
00540 {
00541 pos=dest_pos.x-dx;
00542 if ((pos>=0)&&(pos<dest_size.x))
00543 draw_pixel_mul_offs(dest,offset+3*pos+dyoffset,fcolor);
00544 pos=dest_pos.x+dx;
00545 if ((pos>=0)&&(pos<dest_size.x))
00546 draw_pixel_mul_offs(dest,offset+3*pos+dyoffset,fcolor);
00547 }
00548 }
00549 {
00550 dx++;
00551 n+=invradius;
00552 if ((n>>6)>=SIN_ACOS_SIZE) break;
00553 dy = (int)((radius * (glb_draw_data->sin_acos[(int)(n>>6)])) >> 16);
00554 }
00555 }
00556 }
00557
00568 short place_sprite_cntr_on_buf_rgb(unsigned char *dest,const struct IPOINT_2D dest_pos,
00569 const struct IPOINT_2D dest_size,const unsigned int dest_scanln,
00570 const struct PALETTE_ENTRY *pal,const struct IMAGEITEM *spr)
00571 {
00572 long dest_idx=((dest_pos.y-(spr->height>>1))*dest_scanln);
00573 unsigned long src_idx=0;
00574 unsigned long dest_fullsize=dest_scanln*dest_size.y;
00575 unsigned long dest_startx=3*(dest_pos.x-(spr->width>>1));
00576 unsigned long dest_maxidx=(dest_size.x-1)*3;
00577 if (dest_maxidx>=dest_scanln) dest_maxidx=dest_scanln-1;
00578 int w,h;
00579 for (h=0;h<spr->height;h++)
00580 {
00581 if (dest_idx>=0) break;
00582 dest_idx+=dest_scanln;
00583 src_idx+=spr->width;
00584 }
00585 for (;h<spr->height;h++)
00586 {
00587 if (dest_idx>=dest_fullsize) break;
00588 long dest_sidx=dest_startx;
00589 for (w=0;w<spr->width;w++)
00590 {
00591 if (dest_sidx>=0) break;
00592 dest_sidx+=3;
00593 }
00594 for (;w<spr->width;w++)
00595 {
00596 if (dest_sidx>dest_maxidx) continue;
00597
00598 draw_pixel_x4walpha_offs(dest,dest_idx+dest_sidx,
00599 spr->alpha[src_idx+w],&pal[spr->data[src_idx+w]]);
00600 dest_sidx+=3;
00601 }
00602 dest_idx+=dest_scanln;
00603 src_idx+=spr->width;
00604 }
00605 return ERR_NONE;
00606 }
00607
00620 short draw_rect_mul_on_buffer(unsigned char *dest,const struct IPOINT_2D dest_pos,
00621 const struct IPOINT_2D dest_size,const unsigned int dest_scanln,
00622 const struct IPOINT_2D rect_size,const struct PALETTE_ENTRY *pxdata,
00623 const struct IPOINT_2D scale)
00624 {
00625 unsigned long dest_idx=(dest_pos.y*dest_scanln);
00626 unsigned long dest_fullsize=dest_scanln*dest_size.y;
00627 unsigned long dest_startx=3*dest_pos.x;
00628 unsigned long dest_maxidx=(dest_size.x-1)*3;
00629 if (dest_maxidx>=dest_scanln) dest_maxidx=dest_scanln-1;
00630 struct IPOINT_2D dest_rect_size={rect_size.x/scale.x,rect_size.y/scale.y};
00631
00632
00633
00634 int i,j;
00635 for (j=0;j<dest_rect_size.y;j++)
00636 {
00637 if (dest_idx>=dest_fullsize) break;
00638 unsigned long dest_sidx=dest_startx;
00639 for (i=0;i<dest_rect_size.x;i++)
00640 {
00641 if (dest_sidx>dest_maxidx) continue;
00642
00643 draw_pixel_mul_offs(dest,dest_idx+dest_sidx,pxdata);
00644 dest_sidx+=3;
00645 }
00646 dest_idx+=dest_scanln;
00647 }
00648 return ERR_NONE;
00649 }
00650
00662 short draw_rect_sum_on_buffer(unsigned char *dest,const struct IPOINT_2D dest_pos,
00663 const struct IPOINT_2D dest_size,const unsigned int dest_scanln,
00664 const struct IPOINT_2D rect_size,const struct PALETTE_ENTRY *pxdata,
00665 const struct IPOINT_2D scale)
00666 {
00667 unsigned long dest_idx=(dest_pos.y*dest_scanln);
00668 unsigned long dest_fullsize=dest_scanln*dest_size.y;
00669 int i,j;
00670 for (j=0;j<rect_size.y;j++)
00671 {
00672 if (dest_idx>=dest_fullsize) break;
00673 if ((j%scale.y)>0)
00674 continue;
00675 for (i=0;i<rect_size.x;i++)
00676 {
00677 if ((i%scale.x)!=0) continue;
00678 unsigned long dest_sidx=dest_pos.x+(i/scale.x);
00679 if (dest_sidx>=dest_size.x) continue;
00680
00681 unsigned char nval;
00682 dest_sidx*=3;
00683 nval=(dest[dest_idx+dest_sidx+0]);
00684 dest[dest_idx+dest_sidx+0]=min(nval+pxdata->b,255);
00685 nval=(dest[dest_idx+dest_sidx+1]);
00686 dest[dest_idx+dest_sidx+1]=min(nval+pxdata->g,255);
00687 nval=(dest[dest_idx+dest_sidx+2]);
00688 dest[dest_idx+dest_sidx+2]=min(nval+pxdata->r,255);
00689 }
00690 dest_idx+=dest_scanln;
00691 }
00692 return ERR_NONE;
00693 }
00694
00710 short draw_texture_on_buffer_avg4(unsigned char *dest,const struct IPOINT_2D dest_pos,
00711 const struct IPOINT_2D dest_size, const unsigned int dest_scanln,
00712 const unsigned char *src,const struct IPOINT_2D src_pos,const struct IPOINT_2D src_size,
00713 const struct IPOINT_2D rect_size,struct PALETTE_ENTRY *pal,const struct IPOINT_2D scale)
00714 {
00715 long dest_idx=(dest_pos.y*dest_scanln);
00716 long src_idx=(src_pos.y*src_size.x);
00717 unsigned long src_fullsize=src_size.x*src_size.y;
00718 unsigned long dest_fullsize=dest_scanln*dest_size.y;
00719 unsigned long dest_startx=3*dest_pos.x;
00720 unsigned long dest_maxidx=(dest_size.x-1)*3;
00721 if (dest_maxidx>=dest_scanln) dest_maxidx=dest_scanln-1;
00722 int i,j;
00723 for (j=0;j<rect_size.y;j++)
00724 {
00725 if ((src_idx>=0)&&(dest_idx>=0))
00726 break;
00727 if ((j%scale.y)>0)
00728 {
00729 src_idx+=src_size.x;
00730 continue;
00731 }
00732 unsigned short ridy=mdrand_g8(scale.x);
00733 for (i=0;i<rect_size.x;i++)
00734 if ((i%scale.x)==(ridy))
00735 {
00736 i+=scale.x-ridy-1;
00737 ridy=mdrand_g8(scale.x);
00738 mdrand_g8_waste(2);
00739 }
00740 dest_idx+=dest_scanln;
00741 src_idx+=src_size.x;
00742 }
00743 for (;j<rect_size.y;j++)
00744 {
00745 if ((j%scale.y)>0)
00746 {
00747 src_idx+=src_size.x;
00748 continue;
00749 }
00750 if (dest_idx>=dest_fullsize) break;
00751 if (src_idx>=src_fullsize) break;
00752 unsigned short ridy=mdrand_g8(scale.x);
00753
00754 if (src_idx+(scale.y-1)*src_size.x>=src_fullsize) break;
00755 unsigned long dest_sidx=dest_startx;
00756 for (i=0;i<rect_size.x;i++)
00757 {
00758 if ((i%scale.x)!=(ridy)) continue;
00759 int src_xfinal=src_pos.x+i;
00760 i+=scale.x-ridy-1;
00761 ridy=mdrand_g8(scale.x);
00762
00763 int scaley_half=scale.y>>1;
00764 int src_add1=(mdrand_g8(scaley_half))*src_size.x;
00765 int src_add2=(mdrand_g8(scaley_half)+scaley_half)*src_size.x;
00766 if (dest_sidx>dest_maxidx) continue;
00767 if (src_xfinal>=src_size.x) continue;
00768
00769 struct PALETTE_ENTRY *pxdata1;
00770 struct PALETTE_ENTRY *pxdata2;
00771 struct PALETTE_ENTRY *pxdata3;
00772 struct PALETTE_ENTRY *pxdata4;
00773 if ((src_xfinal+6)>=src_size.x)
00774 {
00775 pxdata1=&pal[src[src_idx+src_add1+src_xfinal]];
00776 pxdata2=pxdata1;
00777 pxdata3=pxdata1;
00778 pxdata4=pxdata1;
00779 } else
00780 {
00781 pxdata1=&pal[src[src_idx+src_add1+src_xfinal]];
00782 pxdata2=&pal[src[src_idx+src_add1+src_xfinal+2]];
00783 pxdata3=&pal[src[src_idx+src_add2+src_xfinal+4]];
00784 pxdata4=&pal[src[src_idx+src_add2+src_xfinal+6]];
00785 }
00786 dest[dest_idx+dest_sidx+0]=(pxdata1->b)+(pxdata2->b)+(pxdata3->b)+(pxdata4->b);
00787 dest[dest_idx+dest_sidx+1]=(pxdata1->g)+(pxdata2->g)+(pxdata3->g)+(pxdata4->g);
00788 dest[dest_idx+dest_sidx+2]=(pxdata1->r)+(pxdata2->r)+(pxdata3->r)+(pxdata4->r);
00789 dest_sidx+=3;
00790 }
00791 dest_idx+=dest_scanln;
00792 src_idx+=src_size.x;
00793 }
00794 return ERR_NONE;
00795 }
00796
00814 short draw_texture_on_buffer_avg4_unsafe(unsigned char *dest,const struct IPOINT_2D dest_pos,
00815 const struct IPOINT_2D dest_size, const unsigned int dest_scanln,
00816 const unsigned char *src,const struct IPOINT_2D src_pos,const struct IPOINT_2D src_size,
00817 const struct IPOINT_2D rect_size,struct PALETTE_ENTRY *pal,const struct IPOINT_2D scale)
00818 {
00819 long dest_idx=(dest_pos.y*dest_scanln);
00820 long src_idx=(src_pos.y*src_size.x);
00821 int i,j;
00822 for (j=0;j<rect_size.y;j++)
00823 {
00824 if ((j%scale.y)>0)
00825 {
00826 src_idx+=src_size.x;
00827 continue;
00828 }
00829 unsigned short ridy=mdrand_g8(scale.x);
00830
00831 for (i=0;i<rect_size.x;i++)
00832 {
00833 if ((i%scale.x)!=(ridy)) continue;
00834 int src_xfinal=src_pos.x+i;
00835 i+=scale.x-ridy-1;
00836 unsigned long dest_sidx=dest_pos.x+(i/scale.x);
00837 ridy=mdrand_g8(scale.x);
00838
00839 int scaley_half=scale.y>>1;
00840 int src_add1=(mdrand_g8(scaley_half))*src_size.x;
00841 int src_add2=(mdrand_g8(scaley_half)+scaley_half)*src_size.x;
00842 src_add1+=src_idx+src_xfinal;
00843 src_add2+=src_idx+src_xfinal;
00844
00845 struct PALETTE_ENTRY *pxdata1;
00846 struct PALETTE_ENTRY *pxdata2;
00847 struct PALETTE_ENTRY *pxdata3;
00848 struct PALETTE_ENTRY *pxdata4;
00849 pxdata1=&pal[src[src_add1]];
00850 pxdata2=&pal[src[src_add1+2]];
00851 pxdata3=&pal[src[src_add2+4]];
00852 pxdata4=&pal[src[src_add2+6]];
00853 dest_sidx*=3;
00854 dest_sidx+=dest_idx;
00855 dest[dest_sidx+0]=(pxdata1->b)+(pxdata2->b)+(pxdata3->b)+(pxdata4->b);
00856 dest[dest_sidx+1]=(pxdata1->g)+(pxdata2->g)+(pxdata3->g)+(pxdata4->g);
00857 dest[dest_sidx+2]=(pxdata1->r)+(pxdata2->r)+(pxdata3->r)+(pxdata4->r);
00858 }
00859 dest_idx+=dest_scanln;
00860 src_idx+=src_size.x;
00861 }
00862 return ERR_NONE;
00863 }
00864
00880 short draw_texture_on_buffer_avg2(unsigned char *dest,const struct IPOINT_2D dest_pos,
00881 const struct IPOINT_2D dest_size, const unsigned int dest_scanln,
00882 const unsigned char *src,const struct IPOINT_2D src_pos,const struct IPOINT_2D src_size,
00883 const struct IPOINT_2D rect_size,struct PALETTE_ENTRY *pal,const struct IPOINT_2D scale)
00884 {
00885 long dest_idx=(dest_pos.y*dest_scanln);
00886 long src_idx=(src_pos.y*src_size.x);
00887 unsigned long src_fullsize=src_size.x*src_size.y;
00888 unsigned long dest_fullsize=dest_scanln*dest_size.y;
00889 int i,j;
00890 for (j=0;j<rect_size.y;j++)
00891 {
00892 if ((src_idx>=0)&&(dest_idx>=0))
00893 break;
00894 if ((j%scale.y)>0)
00895 {
00896 src_idx+=src_size.x;
00897 continue;
00898 }
00899 unsigned short ridy=mdrand_g8(scale.x);
00900 for (i=0;i<rect_size.x;i++)
00901 if ((i%scale.x)==(ridy))
00902 {
00903 i+=scale.x-ridy-1;
00904 ridy=mdrand_g8(scale.x);
00905 mdrand_g8_waste(1);
00906 }
00907 dest_idx+=dest_scanln;
00908 src_idx+=src_size.x;
00909 }
00910 for (;j<rect_size.y;j++)
00911 {
00912 if ((j%scale.y)>0)
00913 {
00914 src_idx+=src_size.x;
00915 continue;
00916 }
00917 if (dest_idx>=dest_fullsize) break;
00918 if (src_idx>=src_fullsize) break;
00919 unsigned short ridy=mdrand_g8(scale.x);
00920
00921 if (src_idx+(scale.y-1)*src_size.x>=src_fullsize) break;
00922 for (i=0;i<rect_size.x;i++)
00923 {
00924 if ((i%scale.x)!=(ridy)) continue;
00925 int src_xfinal=src_pos.x+i;
00926 i+=scale.x-ridy-1;
00927 unsigned long dest_sidx=dest_pos.x+(i/scale.x);
00928 ridy=mdrand_g8(scale.x);
00929 int src_add=mdrand_g8(scale.y)*src_size.x;
00930 if (dest_sidx>=dest_size.x) continue;
00931 if ((src_pos.x+i)>=src_size.x) continue;
00932 struct PALETTE_ENTRY *pxdata1;
00933 struct PALETTE_ENTRY *pxdata2;
00934 if ((src_xfinal+2)>=src_size.x)
00935 {
00936 pxdata1=&pal[src[src_idx+src_add+src_xfinal]];
00937 pxdata2=pxdata1;
00938 } else
00939 {
00940 pxdata1=&pal[src[src_idx+src_add+src_xfinal]];
00941 pxdata2=&pal[src[src_idx+src_add+src_xfinal+2]];
00942 }
00943 dest_sidx*=3;
00944 dest_sidx+=dest_idx;
00945 dest[dest_sidx+0]=(pxdata1->b+pxdata2->b)<<1;
00946 dest[dest_sidx+1]=(pxdata1->g+pxdata2->g)<<1;
00947 dest[dest_sidx+2]=(pxdata1->r+pxdata2->r)<<1;
00948 }
00949 dest_idx+=dest_scanln;
00950 src_idx+=src_size.x;
00951 }
00952 return ERR_NONE;
00953 }
00954
00970 inline __fastcall short draw_texture_on_buffer_avg2_fast(unsigned char *dest,const struct IPOINT_2D dest_pos,
00971 const struct IPOINT_2D dest_size, const unsigned int dest_scanln,
00972 const unsigned char *src,const struct IPOINT_2D src_pos,const struct IPOINT_2D src_size,
00973 const struct IPOINT_2D rect_size,struct PALETTE_ENTRY *pal,const struct IPOINT_2D scale)
00974 {
00975 long dest_idx=(dest_pos.y*dest_scanln);
00976 long src_idx=(src_pos.y*src_size.x);
00977 unsigned long dest_fullsize=dest_scanln*dest_size.y;
00978 int i,j;
00979 for (j=0;j<rect_size.y;j++)
00980 {
00981 if ((src_idx>=0)&&(dest_idx>=0))
00982 break;
00983 if ((j%scale.y)>0)
00984 {
00985 src_idx+=src_size.x;
00986 continue;
00987 }
00988 unsigned short ridy=mdrand_g8(scale.x);
00989 for (i=0;i<rect_size.x;i++)
00990 if ((i%scale.x)==(ridy)) mdrand_g8_waste(1);
00991 dest_idx+=dest_scanln;
00992 src_idx+=src_size.x;
00993 }
00994 for (;j<rect_size.y;j++)
00995 {
00996 if ((j%scale.y)>0)
00997 {
00998 src_idx+=src_size.x;
00999 continue;
01000 }
01001 if (dest_idx>=dest_fullsize) break;
01002 unsigned short ridy=mdrand_g8(scale.x);
01003 long dest_sidx=3*dest_pos.x;
01004 for (i=0;i<rect_size.x;i++)
01005 {
01006 if (dest_sidx>=0) break;
01007 if ((i%scale.x)!=(ridy)) continue;
01008 mdrand_g8_waste(1);
01009 dest_sidx+=3;
01010 }
01011 for (;i<rect_size.x;i++)
01012 {
01013 if ((i%scale.x)!=(ridy)) continue;
01014 int src_add=mdrand_g8(scale.y)*src_size.x;
01015 if (dest_sidx+2>=dest_scanln) continue;
01016 src_add+=src_idx+src_pos.x+i;
01017 struct PALETTE_ENTRY *pxdata1;
01018 struct PALETTE_ENTRY *pxdata2;
01019 pxdata1=&pal[src[src_add]];
01020 pxdata2=&pal[src[src_add+2]];
01021 dest[dest_idx+dest_sidx+0]=(pxdata1->b+pxdata2->b)<<1;
01022 dest[dest_idx+dest_sidx+1]=(pxdata1->g+pxdata2->g)<<1;
01023 dest[dest_idx+dest_sidx+2]=(pxdata1->r+pxdata2->r)<<1;
01024 dest_sidx+=3;
01025 }
01026 dest_idx+=dest_scanln;
01027 src_idx+=src_size.x;
01028 }
01029 return ERR_NONE;
01030 }
01031
01049 inline __fastcall short draw_texture_on_buffer_avg2_fast_unsafe(unsigned char *dest,const struct IPOINT_2D dest_pos,
01050 const struct IPOINT_2D dest_size, const unsigned int dest_scanln,
01051 const unsigned char *src,const struct IPOINT_2D src_pos,const struct IPOINT_2D src_size,
01052 const struct IPOINT_2D rect_size,struct PALETTE_ENTRY *pal,const struct IPOINT_2D scale)
01053 {
01054 long dest_idx=(dest_pos.y*dest_scanln);
01055 long src_idx=(src_pos.y*src_size.x);
01056 int i,j;
01057 for (j=0;j<rect_size.y;j++)
01058 {
01059 if ((j%scale.y)>0)
01060 {
01061 src_idx+=src_size.x;
01062 continue;
01063 }
01064 unsigned short ridy=mdrand_g8(scale.x);
01065 long dest_sidx=3*dest_pos.x;
01066 for (i=0;i<rect_size.x;i++)
01067 {
01068 if ((i%scale.x)!=(ridy)) continue;
01069 int src_add=mdrand_g8(scale.y)*src_size.x;
01070 src_add+=src_idx+src_pos.x+i;
01071 struct PALETTE_ENTRY *pxdata1;
01072 struct PALETTE_ENTRY *pxdata2;
01073 pxdata1=&pal[src[src_add]];
01074 pxdata2=&pal[src[src_add+2]];
01075 dest[dest_idx+dest_sidx+0]=(pxdata1->b+pxdata2->b)<<1;
01076 dest[dest_idx+dest_sidx+1]=(pxdata1->g+pxdata2->g)<<1;
01077 dest[dest_idx+dest_sidx+2]=(pxdata1->r+pxdata2->r)<<1;
01078 dest_sidx+=3;
01079 }
01080 dest_idx+=dest_scanln;
01081 src_idx+=src_size.x;
01082 }
01083 return ERR_NONE;
01084 }
01085
01100 short draw_texture_on_buffer_noavg(unsigned char *dest,const struct IPOINT_2D dest_pos,
01101 const struct IPOINT_2D dest_size, const unsigned int dest_scanln,
01102 const unsigned char *src,const struct IPOINT_2D src_pos,const struct IPOINT_2D src_size,
01103 const struct IPOINT_2D rect_size,struct PALETTE_ENTRY *pal,const struct IPOINT_2D scale)
01104 {
01105 long dest_idx=(dest_pos.y*dest_scanln);
01106 long src_idx=(src_pos.y*src_size.x);
01107 unsigned long src_fullsize=src_size.x*src_size.y;
01108 unsigned long dest_fullsize=dest_scanln*dest_size.y;
01109 unsigned long dest_maxidx=(dest_size.x-1)*3;
01110 if (dest_maxidx>=dest_scanln) dest_maxidx=dest_scanln-1;
01111 int i,j;
01112 for (j=0;j<rect_size.y;j++)
01113 {
01114 if ((src_idx>=0)&&(dest_idx>=0))
01115 break;
01116 if ((j%scale.y)>0)
01117 {
01118 src_idx+=src_size.x;
01119 continue;
01120 }
01121 unsigned short ridy=mdrand_g8(scale.x);
01122 for (i=0;i<rect_size.x;i++)
01123 {
01124 if ((i%scale.x)==(ridy))
01125 {
01126 i+=scale.x-ridy-1;
01127 ridy=mdrand_g8(scale.x);
01128 mdrand_g8_waste(1);
01129 }
01130 }
01131 dest_idx+=dest_scanln;
01132 src_idx+=src_size.x;
01133 }
01134 for (;j<rect_size.y;j++)
01135 {
01136 if ((j%scale.y)>0)
01137 {
01138 src_idx+=src_size.x;
01139 continue;
01140 }
01141 unsigned short ridy=mdrand_g8(scale.x);
01142
01143 if (dest_idx >= dest_fullsize) break;
01144 if (src_idx+(scale.y-1)*src_size.x >= src_fullsize) break;
01145 long dest_sidx=3*dest_pos.x;
01146 for (i=0;i<rect_size.x;i++)
01147 {
01148 if (dest_sidx>=0) break;
01149 if ((i%scale.x)==(ridy))
01150 {
01151 i+=scale.x-ridy-1;
01152 ridy=mdrand_g8(scale.x);
01153 mdrand_g8_waste(1);
01154 dest_sidx+=3;
01155 }
01156 }
01157 for (;i<rect_size.x;i++)
01158 {
01159 if ((i%scale.x)!=(ridy)) continue;
01160 int src_xfinal=src_pos.x+i;
01161 i+=scale.x-ridy-1;
01162 ridy=mdrand_g8(scale.x);
01163 int src_add=src_idx+mdrand_g8(scale.y)*src_size.x;
01164 if (dest_sidx>dest_maxidx) continue;
01165 if (src_xfinal>=src_size.x) continue;
01166 struct PALETTE_ENTRY *pxdata=&pal[src[src_add+src_xfinal]];
01167 dest[dest_idx+dest_sidx+0]=(pxdata->b<<2);
01168 dest[dest_idx+dest_sidx+1]=(pxdata->g<<2);
01169 dest[dest_idx+dest_sidx+2]=(pxdata->r<<2);
01170 dest_sidx+=3;
01171 }
01172 dest_idx+=dest_scanln;
01173 src_idx+=src_size.x;
01174 }
01175 return ERR_NONE;
01176 }
01177
01194 short draw_texture_on_buffer_noavg_unsafe(unsigned char *dest,const struct IPOINT_2D dest_pos,
01195 const struct IPOINT_2D dest_size, const unsigned int dest_scanln,
01196 const unsigned char *src,const struct IPOINT_2D src_pos,const struct IPOINT_2D src_size,
01197 const struct IPOINT_2D rect_size,struct PALETTE_ENTRY *pal,const struct IPOINT_2D scale)
01198 {
01199 long dest_idx=(dest_pos.y*dest_scanln);
01200 long src_idx=(src_pos.y*src_size.x);
01201 int i,j;
01202
01203 for (j=0;j<rect_size.y;j++)
01204 {
01205 if ((j%scale.y)>0)
01206 {
01207 src_idx+=src_size.x;
01208 continue;
01209 }
01210 unsigned short ridy=mdrand_g8(scale.x);
01211 long dest_sidx=3*dest_pos.x;
01212
01213 for (i=0;i<rect_size.x;i++)
01214 {
01215 if ((i%scale.x)!=(ridy)) continue;
01216 int src_add=src_pos.x+i;
01217 i+=scale.x-ridy-1;
01218 ridy=mdrand_g8(scale.x);
01219 src_add+=src_idx+mdrand_g8(scale.y)*src_size.x;
01220
01221
01222 struct PALETTE_ENTRY *pxdata=&pal[src[src_add]];
01223 dest[dest_idx+dest_sidx+0]=(pxdata->b<<2);
01224 dest[dest_idx+dest_sidx+1]=(pxdata->g<<2);
01225 dest[dest_idx+dest_sidx+2]=(pxdata->r<<2);
01226 dest_sidx+=3;
01227 }
01228 dest_idx+=dest_scanln;
01229 src_idx+=src_size.x;
01230 }
01231 return ERR_NONE;
01232 }
01233
01247 short draw_texture_on_buffer_noscale(unsigned char *dest,const struct IPOINT_2D dest_pos,
01248 const struct IPOINT_2D dest_size, const unsigned int dest_scanln,
01249 const unsigned char *src,const struct IPOINT_2D src_pos,const struct IPOINT_2D src_size,
01250 const struct IPOINT_2D rect_size,struct PALETTE_ENTRY *pal)
01251 {
01252 long dest_idx=(dest_pos.y*dest_scanln);
01253 long src_idx=(src_pos.y*src_size.x);
01254 unsigned long src_fullsize=src_size.x*src_size.y;
01255 unsigned long dest_fullsize=dest_scanln*dest_size.y;
01256 int i,j;
01257 for (j=0;j<rect_size.y;j++)
01258 {
01259 if ((src_idx>=0)&&(dest_idx>=0))
01260 break;
01261 dest_idx+=dest_scanln;
01262 src_idx+=src_size.x;
01263 }
01264 for (;j<rect_size.y;j++)
01265 {
01266 if (dest_idx>=dest_fullsize) break;
01267 if (src_idx>=src_fullsize) break;
01268 for (i=0;i<rect_size.x;i++)
01269 {
01270 unsigned long dest_sidx=dest_pos.x+i;
01271 if (dest_sidx>=dest_size.x) continue;
01272 if ((src_pos.x+i)>=src_size.x) continue;
01273 struct PALETTE_ENTRY *pxdata=&pal[src[src_idx+src_pos.x+i]];
01274 dest_sidx*=3;
01275 dest_sidx+=dest_idx;
01276 dest[dest_sidx+0]=(pxdata->b<<2);
01277 dest[dest_sidx+1]=(pxdata->g<<2);
01278 dest[dest_sidx+2]=(pxdata->r<<2);
01279 }
01280 dest_idx+=dest_scanln;
01281 src_idx+=src_size.x;
01282 }
01283 return ERR_NONE;
01284 }
01285
01301 inline short draw_texture_on_buffer(unsigned char *dest,const struct IPOINT_2D dest_pos,
01302 const struct IPOINT_2D dest_size, const unsigned int dest_scanln,
01303 const unsigned char *src,const struct IPOINT_2D src_pos,const struct IPOINT_2D src_size,
01304 const struct IPOINT_2D rect_size,struct PALETTE_ENTRY *pal,const struct IPOINT_2D scale)
01305 {
01306 if (scale.x>7)
01307 return draw_texture_on_buffer_avg4(dest,dest_pos,dest_size,
01308 dest_scanln,src,src_pos,src_size,rect_size,pal,scale);
01309 else
01310 if (scale.x>3)
01311 return draw_texture_on_buffer_avg2(dest,dest_pos,dest_size,
01312 dest_scanln,src,src_pos,src_size,rect_size,pal,scale);
01313 else
01314 if ((scale.x==1)&&(scale.y==1))
01315 return draw_texture_on_buffer_noscale(dest,dest_pos,dest_size,
01316 dest_scanln,src,src_pos,src_size,rect_size,pal);
01317 else
01318 return draw_texture_on_buffer_noavg(dest,dest_pos,dest_size,
01319 dest_scanln,src,src_pos,src_size,rect_size,pal,scale);
01320 }
01321
01339 inline short draw_texture_on_buffer_unsafe(unsigned char *dest,const struct IPOINT_2D dest_pos,
01340 const struct IPOINT_2D dest_size, const unsigned int dest_scanln,
01341 const unsigned char *src,const struct IPOINT_2D src_pos,const struct IPOINT_2D src_size,
01342 const struct IPOINT_2D rect_size,struct PALETTE_ENTRY *pal,const struct IPOINT_2D scale)
01343 {
01344 if (scale.x>7)
01345 return draw_texture_on_buffer_avg4_unsafe(dest,dest_pos,dest_size,
01346 dest_scanln,src,src_pos,src_size,rect_size,pal,scale);
01347 else
01348 if (scale.x>3)
01349 return draw_texture_on_buffer_avg2(dest,dest_pos,dest_size,
01350 dest_scanln,src,src_pos,src_size,rect_size,pal,scale);
01351 else
01352 if ((scale.x==1)&&(scale.y==1))
01353 return draw_texture_on_buffer_noscale(dest,dest_pos,dest_size,
01354 dest_scanln,src,src_pos,src_size,rect_size,pal);
01355 else
01356 return draw_texture_on_buffer_noavg_unsafe(dest,dest_pos,dest_size,
01357 dest_scanln,src,src_pos,src_size,rect_size,pal,scale);
01358 }
01359
01375 inline short draw_texture_on_buffer_fast(unsigned char *dest,const struct IPOINT_2D dest_pos,
01376 const struct IPOINT_2D dest_size, const unsigned int dest_scanln,
01377 const unsigned char *src,const struct IPOINT_2D src_pos,const struct IPOINT_2D src_size,
01378 const struct IPOINT_2D rect_size,struct PALETTE_ENTRY *pal,const struct IPOINT_2D scale)
01379 {
01380 if (scale.x>7)
01381 return draw_texture_on_buffer_avg2_fast(dest,dest_pos,dest_size,
01382 dest_scanln,src,src_pos,src_size,rect_size,pal,scale);
01383 else
01384 if ((scale.x==1)&&(scale.y==1))
01385 return draw_texture_on_buffer_noscale(dest,dest_pos,dest_size,
01386 dest_scanln,src,src_pos,src_size,rect_size,pal);
01387 else
01388 return draw_texture_on_buffer_noavg(dest,dest_pos,dest_size,
01389 dest_scanln,src,src_pos,src_size,rect_size,pal,scale);
01390 }
01391
01409 inline short draw_texture_on_buffer_fast_unsafe(unsigned char *dest,const struct IPOINT_2D dest_pos,
01410 const struct IPOINT_2D dest_size, const unsigned int dest_scanln,
01411 const unsigned char *src,const struct IPOINT_2D src_pos,const struct IPOINT_2D src_size,
01412 const struct IPOINT_2D rect_size,struct PALETTE_ENTRY *pal,const struct IPOINT_2D scale)
01413 {
01414 if (scale.x>7)
01415 return draw_texture_on_buffer_avg2_fast_unsafe(dest,dest_pos,dest_size,
01416 dest_scanln,src,src_pos,src_size,rect_size,pal,scale);
01417 else
01418 if ((scale.x==1)&&(scale.y==1))
01419 return draw_texture_on_buffer_noscale(dest,dest_pos,dest_size,
01420 dest_scanln,src,src_pos,src_size,rect_size,pal);
01421 else
01422 return draw_texture_on_buffer_noavg_unsafe(dest,dest_pos,dest_size,
01423 dest_scanln,src,src_pos,src_size,rect_size,pal,scale);
01424 }
01425
01434 inline short texture_index_to_texture_pos(struct IPOINT_2D *texture_pos,
01435 const struct CUBES_DATA *cubes,unsigned short textr_idx,unsigned int anim_frame)
01436 {
01437 short result=ERR_NONE;
01438
01439 if (textr_idx>=TEXTURE_COUNT_X*TEXTURE_COUNT_Y)
01440 {
01441 textr_idx-=TEXTURE_COUNT_X*TEXTURE_COUNT_Y;
01442 if (textr_idx<cubes->anitxcount)
01443 {
01444 int frame;
01445 if ((textr_idx<12)||(textr_idx>37))
01446 {
01447 frame=anim_frame+mdrand_g8(8);
01448 } else
01449 {
01450 frame=anim_frame;
01451 mdrand_g8_waste(1);
01452 }
01453 textr_idx=cubes->anitx[textr_idx].data[frame%8];
01454 } else
01455 {
01456 textr_idx=1;
01457 mdrand_g8_waste(1);
01458 result=ERR_DRAW_BADTXTR;
01459 }
01460 } else
01461 {
01462 mdrand_g8_waste(1);
01463 }
01464 texture_pos->x=(textr_idx&7)*TEXTURE_SIZE_X;
01465 texture_pos->y=((textr_idx>>3)&127)*TEXTURE_SIZE_Y;
01466 return result;
01467 }
01468
01478 short get_top_texture_pos(struct IPOINT_2D *texture_pos,
01479 const struct CUBES_DATA *cubes,unsigned short cube_idx,unsigned int anim)
01480 {
01481
01482 unsigned int textr_top;
01483 short result=ERR_NONE;
01484 if (cube_idx<cubes->count)
01485 {
01486 textr_top=cubes->data[cube_idx].t;
01487 } else
01488 {
01489 textr_top=1;
01490 }
01491 result=texture_index_to_texture_pos(texture_pos,cubes,textr_top,anim);
01492 if (textr_top==1)
01493 return ERR_DRAW_BADCUBE;
01494 return result;
01495 }
01496
01505 short draw_map_on_buffer(char *dest,const struct LEVEL *lvl,
01506 struct MAPDRAW_DATA *draw_data,unsigned int anim)
01507 {
01508
01509 struct IPOINT_2D texture_size={TEXTURE_SIZE_X*TEXTURE_COUNT_X,TEXTURE_SIZE_Y*TEXTURE_COUNT_Y};
01510 struct IPOINT_2D single_txtr_size={TEXTURE_SIZE_X,TEXTURE_SIZE_Y};
01511 struct IPOINT_2D dest_size={draw_data->end.x-draw_data->start.x+1,draw_data->end.y-draw_data->start.y+1};
01512 struct IPOINT_2D texture_pos;
01513 struct IPOINT_2D dest_pos;
01514 struct IPOINT_2D scale={1<<(draw_data->rescale),1<<(draw_data->rescale)};
01515 struct IPOINT_2D scaled_txtr_size={TEXTURE_SIZE_X>>(draw_data->rescale),TEXTURE_SIZE_Y>>(draw_data->rescale)};
01516
01517 struct IPOINT_2D start;
01518 start.x = draw_data->start.x/scaled_txtr_size.x;
01519 start.y = draw_data->start.y/scaled_txtr_size.y;
01520 struct IPOINT_2D end;
01521 end.x = draw_data->end.x/scaled_txtr_size.x + ((draw_data->end.x%scaled_txtr_size.x)>0);
01522 end.y = draw_data->end.y/scaled_txtr_size.y + ((draw_data->end.y%scaled_txtr_size.y)>0);
01523 struct IPOINT_2D stile_count={end.x-start.x-1,end.y-start.y-1};
01524
01525 int i,j;
01526 j=0;
01527 {
01528 dest_pos.y=-(draw_data->start.y%scaled_txtr_size.y);
01529 for (i=0; i<=stile_count.x; i++)
01530 {
01531 unsigned short cube_idx;
01532 unsigned char *clmentry;
01533 mdrand_setpos(draw_data,start.x+i,start.y);
01534 clmentry=get_subtile_column(lvl,start.x+i,start.y);
01535 cube_idx=get_clm_entry_topcube(clmentry);
01536 if (cube_idx>0)
01537 get_top_texture_pos(&texture_pos,draw_data->cubes,cube_idx,anim);
01538 else
01539 texture_index_to_texture_pos(&texture_pos,draw_data->cubes,
01540 get_clm_entry_base(clmentry),anim);
01541 dest_pos.x=i*(scaled_txtr_size.x)-(draw_data->start.x%scaled_txtr_size.x);
01542 draw_texture_on_buffer(dest,dest_pos,dest_size,draw_data->dest_scanln,draw_data->texture,
01543 texture_pos,texture_size,single_txtr_size,draw_data->palette,scale);
01544 }
01545 }
01546 for (j=1; j<stile_count.y; j++)
01547 {
01548 unsigned short cube_idx;
01549 unsigned char *clmentry;
01550 dest_pos.y=j*(scaled_txtr_size.y)-(draw_data->start.y%scaled_txtr_size.y);
01551 i=0;
01552 {
01553 mdrand_setpos(draw_data,start.x,start.y+j);
01554 clmentry=get_subtile_column(lvl,start.x,start.y+j);
01555 cube_idx=get_clm_entry_topcube(clmentry);
01556 if (cube_idx>0)
01557 get_top_texture_pos(&texture_pos,draw_data->cubes,cube_idx,anim);
01558 else
01559 texture_index_to_texture_pos(&texture_pos,draw_data->cubes,
01560 get_clm_entry_base(clmentry),anim);
01561 dest_pos.x=-(draw_data->start.x%scaled_txtr_size.x);
01562 draw_texture_on_buffer(dest,dest_pos,dest_size,draw_data->dest_scanln,draw_data->texture,
01563 texture_pos,texture_size,single_txtr_size,draw_data->palette,scale);
01564 }
01565 for (i=1; i<stile_count.x; i++)
01566 {
01567 mdrand_setpos(draw_data,start.x+i,start.y+j);
01568 clmentry=get_subtile_column(lvl,start.x+i,start.y+j);
01569 cube_idx=get_clm_entry_topcube(clmentry);
01570 if (cube_idx>0)
01571 get_top_texture_pos(&texture_pos,draw_data->cubes,cube_idx,anim);
01572 else
01573 texture_index_to_texture_pos(&texture_pos,draw_data->cubes,
01574 get_clm_entry_base(clmentry),anim);
01575 dest_pos.x=i*(scaled_txtr_size.x)-(draw_data->start.x%scaled_txtr_size.x);
01576 draw_texture_on_buffer_unsafe(dest,dest_pos,dest_size,draw_data->dest_scanln,draw_data->texture,
01577 texture_pos,texture_size,single_txtr_size,draw_data->palette,scale);
01578 }
01579 {
01580 mdrand_setpos(draw_data,start.x+i,start.y+j);
01581 clmentry=get_subtile_column(lvl,start.x+i,start.y+j);
01582 cube_idx=get_clm_entry_topcube(clmentry);
01583 if (cube_idx>0)
01584 get_top_texture_pos(&texture_pos,draw_data->cubes,cube_idx,anim);
01585 else
01586 texture_index_to_texture_pos(&texture_pos,draw_data->cubes,
01587 get_clm_entry_base(clmentry),anim);
01588 dest_pos.x=i*(scaled_txtr_size.x)-(draw_data->start.x%scaled_txtr_size.x);
01589 draw_texture_on_buffer(dest,dest_pos,dest_size,draw_data->dest_scanln,draw_data->texture,
01590 texture_pos,texture_size,single_txtr_size,draw_data->palette,scale);
01591 }
01592 }
01593 {
01594 dest_pos.y=j*(scaled_txtr_size.y)-(draw_data->start.y%scaled_txtr_size.y);
01595 for (i=0; i<=stile_count.x; i++)
01596 {
01597 unsigned short cube_idx;
01598 unsigned char *clmentry;
01599 mdrand_setpos(draw_data,start.x+i,start.y+j);
01600 clmentry=get_subtile_column(lvl,start.x+i,start.y+j);
01601 cube_idx=get_clm_entry_topcube(clmentry);
01602 if (cube_idx>0)
01603 get_top_texture_pos(&texture_pos,draw_data->cubes,cube_idx,anim);
01604 else
01605 texture_index_to_texture_pos(&texture_pos,draw_data->cubes,
01606 get_clm_entry_base(clmentry),anim);
01607 dest_pos.x=i*(scaled_txtr_size.x)-(draw_data->start.x%scaled_txtr_size.x);
01608 draw_texture_on_buffer(dest,dest_pos,dest_size,draw_data->dest_scanln,draw_data->texture,
01609 texture_pos,texture_size,single_txtr_size,draw_data->palette,scale);
01610 }
01611 }
01612
01613 if (draw_data->ownerpal!=NULL)
01614 for (j=0; j<end.y-start.y; j++)
01615 {
01616 dest_pos.y=j*(scaled_txtr_size.y)-(draw_data->start.y%scaled_txtr_size.y);
01617 for (i=0; i<end.x-start.x; i++)
01618 {
01619 mdrand_setpos(draw_data,start.x+i,start.y+j);
01620 dest_pos.x=i*(scaled_txtr_size.x)-(draw_data->start.x%scaled_txtr_size.x);
01621 unsigned short slab=get_tile_slab(lvl,(start.x+i)/MAP_SUBNUM_X,(start.y+j)/MAP_SUBNUM_Y);
01622 unsigned char owner=get_subtl_owner(lvl,start.x+i,start.y+j);
01623 if (slab==SLAB_TYPE_GOLD)
01624 {
01625 if (draw_data->intnspal!=NULL)
01626 draw_rect_mul_on_buffer(dest,dest_pos,dest_size,draw_data->dest_scanln,
01627 single_txtr_size,&(draw_data->intnspal[1]),scale);
01628 } else
01629 if (slab==SLAB_TYPE_GEMS)
01630 {
01631 if (draw_data->intnspal!=NULL)
01632 draw_rect_mul_on_buffer(dest,dest_pos,dest_size,draw_data->dest_scanln,
01633 single_txtr_size,&(draw_data->intnspal[0]),scale);
01634 } else
01635 {
01636 draw_rect_mul_on_buffer(dest,dest_pos,dest_size,draw_data->dest_scanln,
01637 single_txtr_size,&(draw_data->ownerpal[owner%6]),scale);
01638 }
01639 }
01640 }
01641
01642 return ERR_NONE;
01643 }
01644
01654 short draw_map_on_buffer_fast(char *dest,const struct LEVEL *lvl,
01655 struct MAPDRAW_DATA *draw_data,unsigned int anim)
01656 {
01657
01658 struct IPOINT_2D texture_size={TEXTURE_SIZE_X*TEXTURE_COUNT_X,TEXTURE_SIZE_Y*TEXTURE_COUNT_Y};
01659 struct IPOINT_2D single_txtr_size={TEXTURE_SIZE_X,TEXTURE_SIZE_Y};
01660 struct IPOINT_2D dest_size={draw_data->end.x-draw_data->start.x+1,draw_data->end.y-draw_data->start.y+1};
01661 struct IPOINT_2D texture_pos;
01662 struct IPOINT_2D dest_pos;
01663 struct IPOINT_2D scale={1<<(draw_data->rescale),1<<(draw_data->rescale)};
01664 struct IPOINT_2D scaled_txtr_size={TEXTURE_SIZE_X>>(draw_data->rescale),TEXTURE_SIZE_Y>>(draw_data->rescale)};
01665
01666 struct IPOINT_2D start;
01667 start.x = draw_data->start.x/scaled_txtr_size.x;
01668 start.y = draw_data->start.y/scaled_txtr_size.y;
01669 struct IPOINT_2D end;
01670 end.x = draw_data->end.x/scaled_txtr_size.x + ((draw_data->end.x%scaled_txtr_size.x)>0);
01671 end.y = draw_data->end.y/scaled_txtr_size.y + ((draw_data->end.y%scaled_txtr_size.y)>0);
01672 int i,j;
01673 struct IPOINT_2D tile_count={end.x-start.x-1,end.y-start.y-1};
01674 dest_pos.y=-(draw_data->start.y%scaled_txtr_size.y);
01675
01676 j=0;
01677 {
01678 dest_pos.x=-(draw_data->start.x%scaled_txtr_size.x);
01679 for (i=0; i<=tile_count.x; i++)
01680 {
01681 unsigned short cube_idx;
01682 unsigned char *clmentry;
01683 mdrand_setpos(draw_data,start.x+i,start.y+j);
01684 clmentry=get_subtile_column(lvl,start.x+i,start.y+j);
01685 cube_idx=get_clm_entry_topcube(clmentry);
01686 if (cube_idx>0)
01687 get_top_texture_pos(&texture_pos,draw_data->cubes,cube_idx,anim);
01688 else
01689 texture_index_to_texture_pos(&texture_pos,draw_data->cubes,
01690 get_clm_entry_base(clmentry),anim);
01691 draw_texture_on_buffer_fast(dest,dest_pos,dest_size,draw_data->dest_scanln,draw_data->texture,
01692 texture_pos,texture_size,single_txtr_size,draw_data->palette,scale);
01693 dest_pos.x+=scaled_txtr_size.x;
01694 }
01695 dest_pos.y+=scaled_txtr_size.y;
01696 }
01697
01698 for (j=1; j<tile_count.y; j++)
01699 {
01700 dest_pos.x=-(draw_data->start.x%scaled_txtr_size.x);
01701 i=0;
01702 {
01703 unsigned short cube_idx;
01704 unsigned char *clmentry;
01705 mdrand_setpos(draw_data,start.x+i,start.y+j);
01706 clmentry=get_subtile_column(lvl,start.x+i,start.y+j);
01707 cube_idx=get_clm_entry_topcube(clmentry);
01708 if (cube_idx>0)
01709 get_top_texture_pos(&texture_pos,draw_data->cubes,cube_idx,anim);
01710 else
01711 texture_index_to_texture_pos(&texture_pos,draw_data->cubes,
01712 get_clm_entry_base(clmentry),anim);
01713 draw_texture_on_buffer_fast(dest,dest_pos,dest_size,draw_data->dest_scanln,draw_data->texture,
01714 texture_pos,texture_size,single_txtr_size,draw_data->palette,scale);
01715 dest_pos.x+=scaled_txtr_size.x;
01716 }
01717 for (i=1; i<tile_count.x; i++)
01718 {
01719 unsigned short cube_idx;
01720 unsigned char *clmentry;
01721 mdrand_setpos(draw_data,start.x+i,start.y+j);
01722 clmentry=get_subtile_column(lvl,start.x+i,start.y+j);
01723 cube_idx=get_clm_entry_topcube(clmentry);
01724 if (cube_idx>0)
01725 get_top_texture_pos(&texture_pos,draw_data->cubes,cube_idx,anim);
01726 else
01727 texture_index_to_texture_pos(&texture_pos,draw_data->cubes,
01728 get_clm_entry_base(clmentry),anim);
01729 draw_texture_on_buffer_fast_unsafe(dest,dest_pos,dest_size,draw_data->dest_scanln,draw_data->texture,
01730 texture_pos,texture_size,single_txtr_size,draw_data->palette,scale);
01731 dest_pos.x+=scaled_txtr_size.x;
01732 }
01733 {
01734 unsigned short cube_idx;
01735 unsigned char *clmentry;
01736 mdrand_setpos(draw_data,start.x+i,start.y+j);
01737 clmentry=get_subtile_column(lvl,start.x+i,start.y+j);
01738 cube_idx=get_clm_entry_topcube(clmentry);
01739 if (cube_idx>0)
01740 get_top_texture_pos(&texture_pos,draw_data->cubes,cube_idx,anim);
01741 else
01742 texture_index_to_texture_pos(&texture_pos,draw_data->cubes,
01743 get_clm_entry_base(clmentry),anim);
01744 draw_texture_on_buffer_fast(dest,dest_pos,dest_size,draw_data->dest_scanln,draw_data->texture,
01745 texture_pos,texture_size,single_txtr_size,draw_data->palette,scale);
01746 dest_pos.x+=scaled_txtr_size.x;
01747 }
01748 dest_pos.y+=scaled_txtr_size.y;
01749 }
01750 {
01751 dest_pos.x=-(draw_data->start.x%scaled_txtr_size.x);
01752 for (i=0; i<=tile_count.x; i++)
01753 {
01754 unsigned short cube_idx;
01755 unsigned char *clmentry;
01756 mdrand_setpos(draw_data,start.x+i,start.y+j);
01757 clmentry=get_subtile_column(lvl,start.x+i,start.y+j);
01758 cube_idx=get_clm_entry_topcube(clmentry);
01759 if (cube_idx>0)
01760 get_top_texture_pos(&texture_pos,draw_data->cubes,cube_idx,anim);
01761 else
01762 texture_index_to_texture_pos(&texture_pos,draw_data->cubes,
01763 get_clm_entry_base(clmentry),anim);
01764 draw_texture_on_buffer_fast(dest,dest_pos,dest_size,draw_data->dest_scanln,draw_data->texture,
01765 texture_pos,texture_size,single_txtr_size,draw_data->palette,scale);
01766 dest_pos.x+=scaled_txtr_size.x;
01767 }
01768 dest_pos.y+=scaled_txtr_size.y;
01769 }
01770
01771 return ERR_NONE;
01772 }
01773
01779 inline unsigned int get_objcircle_std_radius(const struct IPOINT_2D scaled_txtr_size)
01780 {
01781 unsigned int radius;
01782 radius=min(scaled_txtr_size.x,scaled_txtr_size.y);
01783 if (radius>31)
01784 radius=(radius>>3);
01785 else
01786 if (radius>15)
01787 radius=(radius>>3)+(radius>>4);
01788 else
01789 if (radius>3)
01790 radius=2;
01791 else
01792 radius=1;
01793 return radius;
01794 }
01795
01803 inline unsigned int get_objcircle_ranged_radius(const struct IPOINT_2D scaled_txtr_size,
01804 const unsigned int obj_range,const int secscale)
01805 {
01806 unsigned int radius;
01807 radius=min(scaled_txtr_size.x,scaled_txtr_size.y);
01808 radius=(obj_range*radius)>>(8+secscale);
01809 return radius;
01810 }
01811
01812
01820 short draw_things_on_buffer(char *dest,const struct LEVEL *lvl,struct MAPDRAW_DATA *draw_data)
01821 {
01822
01823 struct IPOINT_2D scaled_txtr_size={TEXTURE_SIZE_X>>(draw_data->rescale),TEXTURE_SIZE_Y>>(draw_data->rescale)};
01824
01825 struct IPOINT_2D start;
01826 start.x = draw_data->start.x/scaled_txtr_size.x;
01827 start.y = draw_data->start.y/scaled_txtr_size.y;
01828 struct IPOINT_2D end;
01829 end.x = draw_data->end.x/scaled_txtr_size.x + ((draw_data->end.x%scaled_txtr_size.x)>0);
01830 end.y = draw_data->end.y/scaled_txtr_size.y + ((draw_data->end.y%scaled_txtr_size.y)>0);
01831
01832
01833 struct IPOINT_2D dest_scaled_size={(draw_data->end.x-draw_data->start.x+1),(draw_data->end.y-draw_data->start.y+1)};
01834 struct IPOINT_2D dest_pos;
01835
01836 int i,j,k;
01837 for (j=0; j<end.y-start.y; j++)
01838 {
01839 for (i=0; i<end.x-start.x; i++)
01840 {
01841 mdrand_setpos(draw_data,start.x+i,start.y+j);
01842 int last_obj=get_thing_subnums(lvl,start.x+i,start.y+j)-1;
01843 for (k=last_obj; k>=0; k--)
01844 {
01845 unsigned char *thing=get_thing(lvl,start.x+i,start.y+j,k);
01846 int spr_idx=-1;
01847 if (is_gold(thing))
01848 {
01849
01850 if ((draw_data->rescale<4)||(mdrand_g8(7)==0))
01851 spr_idx=510;
01852 } else
01853 if (is_food(thing))
01854 {
01855 spr_idx=313;
01856 } else
01857 if (is_spellbook(thing))
01858 {
01859 spr_idx=60;
01860 } else
01861 if (is_trainpost(thing))
01862 {
01863 spr_idx=66;
01864 }
01865 dest_pos.x=i*(scaled_txtr_size.x)-(draw_data->start.x%scaled_txtr_size.x);
01866 dest_pos.x+=((unsigned int)get_thing_subtpos_x(thing)*scaled_txtr_size.x)>>8;
01867 dest_pos.y=j*(scaled_txtr_size.y)-(draw_data->start.y%scaled_txtr_size.y);
01868 dest_pos.y+=((unsigned int)get_thing_subtpos_y(thing)*scaled_txtr_size.y)>>8;
01869 if ((spr_idx>=0)&&(spr_idx<(draw_data->images->count)))
01870 {
01871 struct IMAGEITEM *item=&(draw_data->images->items[spr_idx]);
01872 place_sprite_cntr_on_buf_rgb(dest,dest_pos,dest_scaled_size,
01873 draw_data->dest_scanln,draw_data->palette,item);
01874 }
01875 }
01876 }
01877 }
01878
01879 for (j=0; j<end.y-start.y; j++)
01880 {
01881 for (i=0; i<end.x-start.x; i++)
01882 {
01883 mdrand_setpos(draw_data,start.x+i,start.y+j);
01884 int last_obj=get_thing_subnums(lvl,start.x+i,start.y+j)-1;
01885 for (k=last_obj; k>=0; k--)
01886 {
01887 unsigned char *thing=get_thing(lvl,start.x+i,start.y+j,k);
01888 int spr_idx=-1;
01889 if (is_creature(thing))
01890 {
01891 unsigned short subtp=get_thing_subtype(thing);
01892 if (subtp<=CREATR_SUBTP_TENTCL)
01893 spr_idx=175+(2*subtp);
01894 else
01895 if (subtp==CREATR_SUBTP_ORC)
01896 spr_idx=495;
01897 else
01898 spr_idx=497;
01899 } else
01900 if (is_dngspecbox(thing))
01901 {
01902 spr_idx=163;
01903 }
01904 dest_pos.x=i*(scaled_txtr_size.x)-(draw_data->start.x%scaled_txtr_size.x);
01905 dest_pos.x+=((unsigned int)get_thing_subtpos_x(thing)*scaled_txtr_size.x)>>8;
01906 dest_pos.y=j*(scaled_txtr_size.y)-(draw_data->start.y%scaled_txtr_size.y);
01907 dest_pos.y+=((unsigned int)get_thing_subtpos_y(thing)*scaled_txtr_size.y)>>8;
01908 if ((spr_idx>=0)&&(spr_idx<(draw_data->images->count)))
01909 {
01910 struct IMAGEITEM *item=&(draw_data->images->items[spr_idx]);
01911 place_sprite_cntr_on_buf_rgb(dest,dest_pos,dest_scaled_size,
01912 draw_data->dest_scanln,draw_data->palette,item);
01913 }
01914 }
01915 }
01916 }
01917
01918
01919 if (draw_data->tngflags&TNGFLG_SHOW_CIRCLES)
01920 {
01921 mdrand_setpos(draw_data,0,0);
01922 struct PALETTE_ENTRY *bcolor;
01923 struct PALETTE_ENTRY *fcolor;
01924 struct PALETTE_ENTRY ecolor={0,0,0,0};
01925 int tngradius=get_objcircle_std_radius(scaled_txtr_size);
01926 for (j=0; j<end.y-start.y; j++)
01927 {
01928 for (i=0; i<end.x-start.x; i++)
01929 {
01930 unsigned char *obj;
01931 int radius;
01932 int last_obj;
01933 last_obj=get_thing_subnums(lvl,start.x+i,start.y+j)-1;
01934 for (k=last_obj; k>=0; k--)
01935 {
01936 obj=get_thing(lvl,start.x+i,start.y+j,k);
01937 unsigned char type_idx=get_thing_type(obj);
01938 bcolor=&thingcircle_palette_std[type_idx%THINGCIRCLE_PALETTE_SIZE];
01939 dest_pos.x=i*(scaled_txtr_size.x)-(draw_data->start.x%scaled_txtr_size.x);
01940 dest_pos.x+=((unsigned int)get_thing_subtpos_x(obj)*scaled_txtr_size.x)>>8;
01941 dest_pos.y=j*(scaled_txtr_size.y)-(draw_data->start.y%scaled_txtr_size.y);
01942 dest_pos.y+=((unsigned int)get_thing_subtpos_y(obj)*scaled_txtr_size.y)>>8;
01943 if (type_idx==THING_TYPE_EFFECTGEN)
01944 {
01945 fcolor=&thingcircle_palette_weak[type_idx%THINGCIRCLE_PALETTE_SIZE];
01946 radius=get_objcircle_ranged_radius(scaled_txtr_size,
01947 get_thing_range_adv(obj),0);
01948 draw_circle_mul(dest,dest_pos,dest_scaled_size,
01949 draw_data->dest_scanln,bcolor,fcolor,radius);
01950 } else
01951 {
01952 draw_circle_fill(dest,dest_pos,dest_scaled_size,
01953 draw_data->dest_scanln,bcolor,&ecolor,tngradius);
01954 }
01955 }
01956 last_obj=get_stlight_subnums(lvl,start.x+i,start.y+j)-1;
01957 for (k=last_obj; k>=0; k--)
01958 {
01959 obj=get_stlight(lvl,start.x+i,start.y+j,k);
01960 bcolor=&thingcircle_palette_std[THING_TYPE_ITEM];
01961 fcolor=&thingcircle_palette_weak[THING_TYPE_ITEM];
01962 dest_pos.x=i*(scaled_txtr_size.x)-(draw_data->start.x%scaled_txtr_size.x);
01963 dest_pos.x+=((unsigned int)get_stlight_subtpos_x(obj)*scaled_txtr_size.x)>>8;
01964 dest_pos.y=j*(scaled_txtr_size.y)-(draw_data->start.y%scaled_txtr_size.y);
01965 dest_pos.y+=((unsigned int)get_stlight_subtpos_y(obj)*scaled_txtr_size.y)>>8;
01966 radius=get_objcircle_ranged_radius(scaled_txtr_size,
01967 get_stlight_range_adv(obj),1);
01968 draw_circle_mul(dest,dest_pos,dest_scaled_size,
01969 draw_data->dest_scanln,bcolor,fcolor,radius);
01970 }
01971 last_obj=get_actnpt_subnums(lvl,start.x+i,start.y+j)-1;
01972 for (k=last_obj; k>=0; k--)
01973 {
01974 obj=get_actnpt(lvl,start.x+i,start.y+j,k);
01975 bcolor=&thingcircle_palette_std[THING_TYPE_DOOR];
01976 fcolor=&thingcircle_palette_weak[THING_TYPE_DOOR];
01977 dest_pos.x=i*(scaled_txtr_size.x)-(draw_data->start.x%scaled_txtr_size.x);
01978 dest_pos.x+=((unsigned int)get_actnpt_subtpos_x(obj)*scaled_txtr_size.x)>>8;
01979 dest_pos.y=j*(scaled_txtr_size.y)-(draw_data->start.y%scaled_txtr_size.y);
01980 dest_pos.y+=((unsigned int)get_actnpt_subtpos_y(obj)*scaled_txtr_size.y)>>8;
01981 radius=get_objcircle_ranged_radius(scaled_txtr_size,
01982 get_actnpt_range_adv(obj),0);
01983 draw_circle_mul(dest,dest_pos,dest_scaled_size,
01984 draw_data->dest_scanln,bcolor,fcolor,radius);
01985 }
01986 }
01987 }
01988 }
01989
01990 return ERR_NONE;
01991 }
01992
02002 short draw_text_on_buffer(char *dest,const int px,const int py,
02003 const char *text,struct MAPDRAW_DATA *draw_data,short font)
02004 {
02005 struct IPOINT_2D dest_scaled_size={(draw_data->end.x-draw_data->start.x+1),(draw_data->end.y-draw_data->start.y+1)};
02006 struct IPOINT_2D dest_pos={px,py};
02007 int i;
02008 struct IMAGELIST *fontimgs;
02009 if (font==0)
02010 fontimgs=draw_data->font0;
02011 else
02012 fontimgs=draw_data->font1;
02013 if ((text==NULL)||(fontimgs==NULL))
02014 return ERR_INTERNAL;
02015 for (i=0;text[i]!='\0';i++)
02016 {
02017 short spr_idx=(short)((unsigned char)text[i]) - 32;
02018 if ((spr_idx>=0)&&(spr_idx<(fontimgs->count)))
02019 {
02020 struct IMAGEITEM *item=&(fontimgs->items[spr_idx]);
02021 place_sprite_cntr_on_buf_rgb(dest,dest_pos,dest_scaled_size,
02022 draw_data->dest_scanln,draw_data->palette,item);
02023 dest_pos.x+=item->width;
02024 }
02025 }
02026
02027 return ERR_NONE;
02028 }
02029
02037 short write_bitmap_rgb(const char *fname,const unsigned char *data,const struct IPOINT_2D size)
02038 {
02039 message_log(" write_bitmap_rgb: Starting");
02040 if ((fname==NULL)||(data==NULL))
02041 {
02042 message_error("Internal error - null poiner detected in write_bitmap_rgb");
02043 return 2;
02044 }
02045
02046 FILE *out;
02047 out = fopen (fname, "wb");
02048 if (out==NULL)
02049 {
02050 message_error("Can't open \"%s\" for writing", fname);
02051 return 1;
02052 }
02053
02054 short result;
02055 result=write_bmp_fp_24b(out,size.x,size.y,data);
02056 fclose(out);
02057 message_log(" write_bitmap_rgb: Finished");
02058 return result;
02059 }
02060
02073 short set_draw_data_rect(struct MAPDRAW_DATA *draw_data,
02074 const int startx,const int starty,const int endx,const int endy,
02075 const unsigned int scanline,const short rescale)
02076 {
02077 draw_data->start.x=startx;
02078 draw_data->start.y=starty;
02079 draw_data->end.x=endx;
02080 draw_data->end.y=endy;
02081 if (rescale > 3)
02082 {
02083 draw_data->ownerpal=owned_area_palette_std;
02084 draw_data->intnspal=intense_slab_palette_std;
02085 } else
02086 if (rescale > 2)
02087 {
02088 draw_data->ownerpal=owned_area_palette_weak;
02089 draw_data->intnspal=intense_slab_palette_weak;
02090 } else
02091 {
02092 draw_data->ownerpal=NULL;
02093 draw_data->intnspal=NULL;
02094 }
02095 draw_data->rescale=rescale;
02096 draw_data->dest_scanln=scanline;
02097 return ERR_NONE;
02098 }
02099
02111 short set_draw_data_rect_ip(struct MAPDRAW_DATA *draw_data,
02112 const struct IPOINT_2D start,const struct IPOINT_2D end,
02113 const unsigned int scanline,const short rescale)
02114 {
02115 return set_draw_data_rect(draw_data,start.x,start.y,end.x,end.y,scanline,rescale);
02116 }
02117
02131 short set_draw_data_rect_sl4(struct MAPDRAW_DATA *draw_data,
02132 const int startx,const int starty,const int endx,const int endy,
02133 const short dest_sizex,const short rescale)
02134 {
02135 unsigned int scanln=(3*dest_sizex);
02136 if ((scanln%4)!=0) scanln+=4-(scanln%4);
02137 return set_draw_data_rect(draw_data,startx,starty,endx,endy,scanln,rescale);
02138 }
02139
02151 short load_draw_data(struct MAPDRAW_DATA **draw_data,const struct MAPDRAW_OPTIONS *opts,
02152 const struct UPOINT_2D *subtl,const struct IPOINT_2D bmp_size,int textr_idx)
02153 {
02154 short result;
02155 (*draw_data) = malloc(sizeof(struct MAPDRAW_DATA));
02156 if ((*draw_data) == NULL)
02157 {
02158 message_error("load_draw_data: Cannot allocate draw_data memory.");
02159 return 2;
02160 }
02161 (*draw_data)->subsize.x=subtl->x;
02162 (*draw_data)->subsize.y=subtl->y;
02163 (*draw_data)->tngflags=opts->tngflags;
02164 unsigned int total_subtiles=(*draw_data)->subsize.x*(*draw_data)->subsize.y;
02165
02166 (*draw_data)->cubes=malloc(sizeof(struct CUBES_DATA));
02167 (*draw_data)->palette=malloc(256*sizeof(struct PALETTE_ENTRY));
02168 (*draw_data)->images=malloc(sizeof(struct IMAGELIST));
02169 (*draw_data)->rand_size=total_subtiles*sizeof(int);
02170 (*draw_data)->rand_pool=malloc((*draw_data)->rand_size);
02171 if ((*draw_data)->cubes != NULL)
02172 {
02173 (*draw_data)->cubes->count=0;
02174 (*draw_data)->cubes->data=NULL;
02175 }
02176 if (opts->bmfonts&BMFONT_LOAD_SMALL)
02177 (*draw_data)->font0=malloc(sizeof(struct IMAGELIST));
02178 else
02179 (*draw_data)->font0=NULL;
02180 if (opts->bmfonts&BMFONT_LOAD_LARGE)
02181 (*draw_data)->font1=malloc(sizeof(struct IMAGELIST));
02182 else
02183 (*draw_data)->font1=NULL;
02184 (*draw_data)->texture=NULL;
02185 (*draw_data)->ownerpal=NULL;
02186 (*draw_data)->intnspal=NULL;
02187 if (((*draw_data)->cubes==NULL) || ((*draw_data)->palette==NULL) ||
02188 (((*draw_data)->font0==NULL)&&(opts->bmfonts&BMFONT_LOAD_SMALL)) ||
02189 (((*draw_data)->font1==NULL)&&(opts->bmfonts&BMFONT_LOAD_LARGE)) ||
02190 ((*draw_data)->images==NULL) || ((*draw_data)->rand_pool==NULL) )
02191 {
02192 message_error("load_draw_data: Out of memory.");
02193 free_draw_data(*draw_data);
02194 (*draw_data)=NULL;
02195 return 3;
02196 }
02197
02198 int i;
02199 for (i=0;i<total_subtiles;i++)
02200 {
02201 int *rnd_ints=(int *)(*draw_data)->rand_pool;
02202 rnd_ints[i]=rand();
02203 }
02204 (*draw_data)->rand_count=0;
02205
02206 set_draw_data_rect(*draw_data,0,0,bmp_size.x-1,bmp_size.y-1,bmp_size.x*3,(opts->rescale));
02207
02208 char *fnames;
02209 result=true;
02210 if (result)
02211 {
02212 message_log(" load_draw_data: Loading \"%s\"",palette_fname);
02213 fnames=NULL;
02214 result = format_data_fname(&fnames,opts->data_path,palette_fname);
02215 if (result)
02216 result = (load_palette((*draw_data)->palette,fnames)==ERR_NONE);
02217 if (!result)
02218 message_error("Error when loading file \"%s\"",fnames);
02219 free(fnames);
02220 }
02221 if (result)
02222 {
02223 message_log(" load_draw_data: Loading \"%s\"",cube_fname);
02224 fnames=NULL;
02225 format_data_fname(&fnames,opts->data_path,cube_fname);
02226 result = (load_cubedata((*draw_data)->cubes,fnames)==ERR_NONE);
02227 if (!result)
02228 message_error("Error when loading file \"%s\"",fnames);
02229 free(fnames);
02230 }
02231 if (result)
02232 {
02233 message_log(" load_draw_data: Loading \"%s\"",tmapanim_fname);
02234 fnames=NULL;
02235 format_data_fname(&fnames,opts->data_path,tmapanim_fname);
02236 result = (load_textureanim((*draw_data)->cubes,fnames)==ERR_NONE);
02237 if (!result)
02238 message_error("Error when loading file \"%s\"",fnames);
02239 free(fnames);
02240 }
02241 if (result)
02242 {
02243 message_log(" load_draw_data: Loading texture");
02244 result = (change_draw_data_texture(*draw_data,opts,textr_idx)==ERR_NONE);
02245 }
02246
02247 if (result)
02248 {
02249 message_log(" load_draw_data: Loading gui2-0 icons");
02250 char *tabfname;
02251 fnames=NULL;
02252 tabfname=NULL;
02253 int large_tngicons=((opts->rescale)<3);
02254 format_data_fname(&fnames,opts->data_path,"gui%d-%d-%d.dat",2,0,large_tngicons);
02255 format_data_fname(&tabfname,opts->data_path,"gui%d-%d-%d.tab",2,0,large_tngicons);
02256 result = (create_images_dattab_idx((*draw_data)->images,fnames,tabfname,0)==ERR_NONE);
02257 if (!result)
02258 message_error("Error when loading dat/tab pair \"%s\"",fnames);
02259 free(fnames);
02260 free(tabfname);
02261 }
02262
02263 if ((result)&&(opts->bmfonts&BMFONT_LOAD_SMALL))
02264 {
02265 message_log(" load_draw_data: Loading small font");
02266 char *tabfname;
02267 fnames=NULL;
02268 tabfname=NULL;
02269 int large_tngicons=((opts->rescale)<3);
02270 format_data_fname(&fnames,opts->data_path,"font%d-%d.dat",2,0);
02271 format_data_fname(&tabfname,opts->data_path,"font%d-%d.tab",2,0);
02272 result = (create_images_dattab_idx((*draw_data)->font0,fnames,tabfname,0)==ERR_NONE);
02273 if (!result)
02274 message_error("Error when loading dat/tab pair \"%s\"",fnames);
02275 free(fnames);
02276 free(tabfname);
02277 }
02278
02279 if ((result)&&(opts->bmfonts&BMFONT_LOAD_LARGE))
02280 {
02281 message_log(" load_draw_data: Loading large font");
02282 char *tabfname;
02283 fnames=NULL;
02284 tabfname=NULL;
02285 int large_tngicons=((opts->rescale)<3);
02286 format_data_fname(&fnames,opts->data_path,"font%d-%d.dat",2,1);
02287 format_data_fname(&tabfname,opts->data_path,"font%d-%d.tab",2,1);
02288 result = (create_images_dattab_idx((*draw_data)->font1,fnames,tabfname,0)==ERR_NONE);
02289 if (!result)
02290 message_error("Error when loading dat/tab pair \"%s\"",fnames);
02291 free(fnames);
02292 free(tabfname);
02293 }
02294
02295 if (result)
02296 {
02297 message_log(" load_draw_data: Preparing constant arrays");
02298 for(i=0;i<SIN_ACOS_SIZE;i++)
02299 {
02300 (*draw_data)->sin_acos[i]=sin(acos(((float)i)/SIN_ACOS_SIZE))*0x10000L;
02301 }
02302 }
02303 if (!result)
02304 {
02305 free_draw_data(*draw_data);
02306 (*draw_data)=NULL;
02307 return 1;
02308 }
02309 return ERR_NONE;
02310 }
02311
02320 short change_draw_data_texture(struct MAPDRAW_DATA *draw_data,
02321 const struct MAPDRAW_OPTIONS *opts,const int textr_idx)
02322 {
02323 char *fname;
02324 short result;
02325 format_data_fname(&fname,opts->data_path,"tmapa%03d.dat",textr_idx);
02326 free(draw_data->texture);
02327 draw_data->texture=NULL;
02328 result = load_texture(&(draw_data->texture),fname);
02329 if (result!=ERR_NONE)
02330 message_error("Error when loading file \"%s\"",fname);
02331 free(fname);
02332 return ERR_NONE;
02333 }
02334
02340 short free_draw_data(struct MAPDRAW_DATA *draw_data)
02341 {
02342 if (draw_data==NULL)
02343 return ERR_NONE;
02344 free_dattab_images(draw_data->images);
02345 free(draw_data->images);
02346 if (draw_data->cubes != NULL)
02347 free(draw_data->cubes->data);
02348 free(draw_data->texture);
02349 free(draw_data->palette);
02350 free(draw_data->cubes);
02351 free(draw_data->rand_pool);
02352 free(draw_data);
02353 return ERR_NONE;
02354 }
02355
02366 short get_draw_tile_rect(struct IPOINT_2D *tstart,
02367 struct IPOINT_2D *tdim, const struct MAPDRAW_DATA *draw_data,
02368 unsigned int tx,unsigned int ty)
02369 {
02370 if (draw_data==NULL)
02371 return ERR_INTERNAL;
02372 tdim->x = (TEXTURE_SIZE_X>>(draw_data->rescale))*MAP_SUBNUM_X;
02373 tdim->y = (TEXTURE_SIZE_Y>>(draw_data->rescale))*MAP_SUBNUM_Y;
02374
02375 tstart->x = (tdim->x*tx)-draw_data->start.x;
02376 tstart->y = (tdim->y*ty)-draw_data->start.y;
02377 return ERR_NONE;
02378 }
02379
02390 short get_draw_subtile_rect(struct IPOINT_2D *sstart,
02391 struct IPOINT_2D *sdim, const struct MAPDRAW_DATA *draw_data,
02392 unsigned int sx,unsigned int sy)
02393 {
02394 if (draw_data==NULL)
02395 return ERR_INTERNAL;
02396 sdim->x = (TEXTURE_SIZE_X>>(draw_data->rescale));
02397 sdim->y = (TEXTURE_SIZE_Y>>(draw_data->rescale));
02398
02399 sstart->x = (sdim->x*sx)-draw_data->start.x;
02400 sstart->y = (sdim->y*sy)-draw_data->start.y;
02401 return ERR_NONE;
02402 }
02403
02413 short get_subtile_from_draw_coords(unsigned int *sx,unsigned int *sy,
02414 const struct MAPDRAW_DATA *draw_data,
02415 unsigned int px,unsigned int py)
02416 {
02417 if (draw_data==NULL)
02418 return ERR_INTERNAL;
02419 struct IPOINT_2D scaled_txtr_size=
02420 {TEXTURE_SIZE_X>>(draw_data->rescale),TEXTURE_SIZE_Y>>(draw_data->rescale)};
02421 (*sx)=(px+draw_data->start.x)/scaled_txtr_size.x;
02422 (*sy)=(py+draw_data->start.y)/scaled_txtr_size.y;
02423 return ERR_NONE;
02424 }
02425
02436 short get_subtile_from_draw_coords_ip(struct IPOINT_2D *subtl,
02437 struct IPOINT_2D *subpos,const struct MAPDRAW_DATA *draw_data,
02438 unsigned int px,unsigned int py)
02439 {
02440 if (draw_data==NULL)
02441 return ERR_INTERNAL;
02442 struct IPOINT_2D scaled_txtr_size=
02443 {TEXTURE_SIZE_X>>(draw_data->rescale),TEXTURE_SIZE_Y>>(draw_data->rescale)};
02444 struct IPOINT_2D absol_coords=
02445 {px+draw_data->start.x,py+draw_data->start.y};
02446 subtl->x = absol_coords.x/scaled_txtr_size.x;
02447 subtl->y = absol_coords.y/scaled_txtr_size.y;
02448 subpos->x = (absol_coords.x%scaled_txtr_size.x)*(256/scaled_txtr_size.x);
02449 subpos->y = (absol_coords.y%scaled_txtr_size.y)*(256/scaled_txtr_size.y);
02450 return ERR_NONE;
02451 }
02452
02462 short get_subtile_from_draw_coords_adv(unsigned int *ssx,unsigned int *ssy,
02463 const struct MAPDRAW_DATA *draw_data,unsigned int px,unsigned int py)
02464 {
02465 if (draw_data==NULL)
02466 return ERR_INTERNAL;
02467 struct IPOINT_2D scaled_txtr_size=
02468 {TEXTURE_SIZE_X>>(draw_data->rescale),TEXTURE_SIZE_Y>>(draw_data->rescale)};
02469 struct IPOINT_2D absol_coords=
02470 {px+draw_data->start.x,py+draw_data->start.y};
02471 *ssx = ((absol_coords.x/scaled_txtr_size.x)<<8) +
02472 (absol_coords.x%scaled_txtr_size.x)*(256/scaled_txtr_size.x);
02473 *ssy = ((absol_coords.y/scaled_txtr_size.y)<<8) +
02474 (absol_coords.y%scaled_txtr_size.y)*(256/scaled_txtr_size.y);
02475 return ERR_NONE;
02476 }
02477
02489 inline short get_subtile_from_draw_coords_adv_fast(unsigned int *ssx,unsigned int *ssy,
02490 const struct IPOINT_2D scaled_txtr_size,const struct IPOINT_2D start,
02491 unsigned int px,unsigned int py)
02492 {
02493 struct IPOINT_2D absol_coords=
02494 {px+start.x,py+start.y};
02495 *ssx = ((absol_coords.x/scaled_txtr_size.x)<<8) +
02496 (absol_coords.x%scaled_txtr_size.x)*(256/scaled_txtr_size.x);
02497 *ssy = ((absol_coords.y/scaled_txtr_size.y)<<8) +
02498 (absol_coords.y%scaled_txtr_size.y)*(256/scaled_txtr_size.y);
02499 return ERR_NONE;
02500 }
02501
02513 short get_thing_with_circle_at(unsigned int *sx,unsigned int *sy,unsigned int *num,
02514 const struct MAPDRAW_DATA *draw_data,const struct LEVEL *lvl,
02515 unsigned int px,unsigned int py)
02516 {
02517
02518 if (draw_data==NULL)
02519 return ERR_INTERNAL;
02520 struct IPOINT_2D scaled_txtr_size=
02521 {TEXTURE_SIZE_X>>(draw_data->rescale),TEXTURE_SIZE_Y>>(draw_data->rescale)};
02522 short result;
02523 unsigned int test_ssx,test_ssy;
02524 result=get_subtile_from_draw_coords_adv_fast(&test_ssx,&test_ssy,
02525 scaled_txtr_size,draw_data->start,px,py);
02526 if (result!=ERR_NONE)
02527 {
02528 message_error("Cannot convert coordinates");
02529 return result;
02530 }
02531
02532
02533 unsigned int obj_sx,obj_sy,obj_num;
02534 long dist;
02535 dist=get_nearest_thing_idx(lvl,test_ssx,test_ssy,&obj_sx,&obj_sy,&obj_num);
02536 if (dist<0)
02537 {
02538 message_info("No thing near subtile (%u,%u)",test_ssx>>8,test_ssy>>8);
02539 return ERR_INTERNAL;
02540 }
02541
02542
02543
02544 long radius;
02545 radius=get_objcircle_std_radius(scaled_txtr_size);
02546 if (radius<3) radius=3;
02547 radius = ((unsigned long)radius<<8)/scaled_txtr_size.x;
02548
02549 if (dist<=radius)
02550 {
02551
02552 *sx=obj_sx;
02553 *sy=obj_sy;
02554 *num=obj_num;
02555 return ERR_NONE;
02556 }
02557
02558 return ERR_INTERNAL;
02559 }
02560
02572 short get_object_with_circle_at(unsigned int *sx,unsigned int *sy,unsigned int *z,
02573 const struct MAPDRAW_DATA *draw_data,const struct LEVEL *lvl,
02574 unsigned int px,unsigned int py)
02575 {
02576
02577 if (draw_data==NULL)
02578 return ERR_INTERNAL;
02579 struct IPOINT_2D scaled_txtr_size=
02580 {TEXTURE_SIZE_X>>(draw_data->rescale),TEXTURE_SIZE_Y>>(draw_data->rescale)};
02581 short result;
02582 unsigned int test_ssx,test_ssy;
02583 result=get_subtile_from_draw_coords_adv_fast(&test_ssx,&test_ssy,
02584 scaled_txtr_size,draw_data->start,px,py);
02585 if (result!=ERR_NONE)
02586 {
02587 message_error("Cannot convert coordinates");
02588 return result;
02589 }
02590
02591
02592 unsigned int obj_sx,obj_sy,obj_num;
02593 long dist;
02594 dist=get_nearest_object_idx(lvl,test_ssx,test_ssy,&obj_sx,&obj_sy,&obj_num);
02595 if (dist<0)
02596 {
02597 message_info("No object near subtile (%u,%u)",test_ssx>>8,test_ssy>>8);
02598 return ERR_INTERNAL;
02599 }
02600
02601
02602
02603 long radius;
02604 radius=get_objcircle_std_radius(scaled_txtr_size);
02605 if (radius<3) radius=3;
02606 radius = ((unsigned long)radius<<8)/scaled_txtr_size.x;
02607
02608 if (dist<=radius)
02609 {
02610
02611 *sx=obj_sx;
02612 *sy=obj_sy;
02613 *z=obj_num;
02614 return ERR_NONE;
02615 }
02616
02617 return ERR_INTERNAL;
02618 }
02619
02628 short get_full_draw_dimensions(struct IPOINT_2D *gdim,
02629 const struct MAPDRAW_DATA *draw_data)
02630 {
02631 if (draw_data==NULL)
02632 return ERR_INTERNAL;
02633 struct IPOINT_2D scaled_txtr_size=
02634 {TEXTURE_SIZE_X>>(draw_data->rescale),TEXTURE_SIZE_Y>>(draw_data->rescale)};
02635 gdim->x = scaled_txtr_size.x*draw_data->subsize.x;
02636 gdim->y = scaled_txtr_size.y*draw_data->subsize.y;
02637 return ERR_NONE;
02638 }
02639
02650 short get_full_draw_dimensions_opt(struct IPOINT_2D *gdim,
02651 const struct UPOINT_2D *subtl,const struct MAPDRAW_OPTIONS *opts)
02652 {
02653 if (opts==NULL)
02654 return ERR_INTERNAL;
02655 struct IPOINT_2D scaled_txtr_size=
02656 {TEXTURE_SIZE_X>>(opts->rescale),TEXTURE_SIZE_Y>>(opts->rescale)};
02657 gdim->x = scaled_txtr_size.x*subtl->x;
02658 gdim->y = scaled_txtr_size.y*subtl->y;
02659 return ERR_NONE;
02660 }
02661
02671 short generate_map_bitmap(const char *bmpfname,const struct LEVEL *lvl,
02672 const struct MAPDRAW_OPTIONS *opts)
02673 {
02674 message_log(" generate_map_bitmap: Starting");
02675 short result;
02676 struct MAPDRAW_DATA *draw_data;
02677
02678 struct IPOINT_2D textr_size={TEXTURE_SIZE_X>>(opts->rescale),TEXTURE_SIZE_Y>>(opts->rescale)};
02679 struct IPOINT_2D bmp_size;
02680
02681 bmp_size.x=textr_size.x*lvl->subsize.x;
02682 bmp_size.y=textr_size.y*lvl->subsize.y;
02683 result=load_draw_data(&draw_data,opts,&(lvl->subsize),bmp_size,(int)(lvl->inf%8));
02684 if (result!=ERR_NONE)
02685 return result;
02686 unsigned char *bitmap=NULL;
02687 if (result==ERR_NONE)
02688 {
02689 bitmap=(unsigned char *)malloc((bmp_size.x*bmp_size.y+1)*3);
02690 if (bitmap==NULL)
02691 {
02692 message_error("generate_map_bitmap: Cannot allocate bitmap memory.");
02693 free_draw_data(draw_data);
02694 return 2;
02695 }
02696 }
02697 if (result==ERR_NONE)
02698 {
02699 result = draw_map_on_buffer(bitmap,lvl,draw_data,rnd(32768));
02700 if (result!=ERR_NONE)
02701 message_error("Error when drawing map on memory buffer");
02702 }
02703 if (result==ERR_NONE)
02704 {
02705 if ((opts->rescale)<5)
02706 result = draw_things_on_buffer(bitmap,lvl,draw_data);
02707 if (result!=ERR_NONE)
02708 message_error("Error when placing thing sprites on memory buffer");
02709 }
02710 if (result==ERR_NONE)
02711 {
02712
02713 result = write_bitmap_rgb(bmpfname,bitmap,bmp_size);
02714 }
02715 free(bitmap);
02716 free_draw_data(draw_data);
02717 message_log(" generate_map_bitmap: Finished");
02718 return result;
02719 }
02720
02726 short generate_map_bitmap_mapfname(struct LEVEL *lvl)
02727 {
02728 short result;
02729 char *bmpfname;
02730 bmpfname = (char *)malloc(strlen(lvl->fname)+5);
02731 if (bmpfname==NULL)
02732 {
02733 message_error("generate_map_bitmap_mapfname: Cannot allocate memory.");
02734 return false;
02735 }
02736 sprintf (bmpfname, "%s.bmp", lvl->fname);
02737 lvl->optns.picture.data_path=lvl->optns.data_path;
02738 result = generate_map_bitmap(bmpfname,lvl,&(lvl->optns.picture));
02739 if (result==ERR_NONE)
02740 message_info("Bitmap \"%s\" created.",bmpfname);
02741 free(bmpfname);
02742 return result;
02743 }
02744