Atrinik Client 2.5
client/sprite.c
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00030 #include <global.h>
00031 
00033 struct _anim *start_anim;
00034 
00036 SDL_Surface *FormatHolder;
00037 
00039 static int dark_alpha[DARK_LEVELS] =
00040 {
00041     0, 44, 80, 117, 153, 190, 226
00042 };
00043 
00045 static SDL_Surface *darkness_filter[DARK_LEVELS] =
00046 {
00047     NULL, NULL, NULL, NULL, NULL, NULL, NULL
00048 };
00049 
00050 static void red_scale(_Sprite *sprite);
00051 static void grey_scale(_Sprite *sprite);
00052 static void fow_scale(_Sprite *sprite);
00053 static int GetBitmapBorders(SDL_Surface *Surface, int *up, int *down, int *left, int *right, uint32 ckey);
00054 
00057 void sprite_init_system()
00058 {
00059     FormatHolder = SDL_CreateRGBSurface(SDL_SRCALPHA, 1, 1, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
00060     SDL_SetAlpha(FormatHolder, SDL_SRCALPHA, 255);
00061 }
00062 
00068 _Sprite *sprite_load_file(char *fname, uint32 flags)
00069 {
00070     _Sprite *sprite = sprite_tryload_file(fname, flags, NULL);
00071 
00072     if (sprite == NULL)
00073     {
00074         LOG(llevBug, "sprite_load_file(): Can't load sprite %s\n", fname);
00075         return NULL;
00076     }
00077 
00078     return sprite;
00079 }
00080 
00087 _Sprite *sprite_tryload_file(char *fname, uint32 flag, SDL_RWops *rwop)
00088 {
00089     _Sprite *sprite;
00090     SDL_Surface *bitmap;
00091     uint32 ckflags, tmp = 0;
00092 
00093     if (fname)
00094     {
00095         if (!(bitmap = IMG_Load_wrapper(fname)))
00096         {
00097             return NULL;
00098         }
00099     }
00100     else
00101     {
00102         bitmap = IMG_LoadPNG_RW(rwop);
00103     }
00104 
00105     if (!(sprite = malloc(sizeof(_Sprite))))
00106     {
00107         return NULL;
00108     }
00109 
00110     memset(sprite, 0, sizeof(_Sprite));
00111 
00112     ckflags = SDL_SRCCOLORKEY | SDL_ANYFORMAT | SDL_RLEACCEL;
00113 
00114     if (bitmap->format->palette)
00115     {
00116         SDL_SetColorKey(bitmap, ckflags, (tmp = bitmap->format->colorkey));
00117     }
00118     /* We force a true color png to colorkey. Default colkey is black (0). */
00119     else if (flag & SURFACE_FLAG_COLKEY_16M)
00120     {
00121         SDL_SetColorKey(bitmap, ckflags, 0);
00122     }
00123 
00124     GetBitmapBorders(bitmap, &sprite->border_up, &sprite->border_down, &sprite->border_left, &sprite->border_right, tmp);
00125 
00126     /* We store our original bitmap */
00127     sprite->bitmap = bitmap;
00128 
00129     if (flag & SURFACE_FLAG_DISPLAYFORMATALPHA)
00130     {
00131         sprite->bitmap = SDL_DisplayFormatAlpha(bitmap);
00132         SDL_FreeSurface(bitmap);
00133     }
00134     else if (flag & SURFACE_FLAG_DISPLAYFORMAT)
00135     {
00136         sprite->bitmap = SDL_DisplayFormat(bitmap);
00137         SDL_FreeSurface(bitmap);
00138     }
00139 
00140     return sprite;
00141 }
00142 
00146 void sprite_free_sprite(_Sprite *sprite)
00147 {
00148     int i;
00149 
00150     if (!sprite)
00151     {
00152         return;
00153     }
00154 
00155     if (sprite->bitmap)
00156     {
00157         SDL_FreeSurface(sprite->bitmap);
00158     }
00159 
00160     if (sprite->grey)
00161     {
00162         SDL_FreeSurface(sprite->grey);
00163     }
00164 
00165     if (sprite->red)
00166     {
00167         SDL_FreeSurface(sprite->red);
00168     }
00169 
00170     if (sprite->fog_of_war)
00171     {
00172         SDL_FreeSurface(sprite->fog_of_war);
00173     }
00174 
00175     if (sprite->effect)
00176     {
00177         SDL_FreeSurface(sprite->effect);
00178     }
00179 
00180     if (sprite->dark_level)
00181     {
00182         for (i = 0; i < DARK_LEVELS; i++)
00183         {
00184             if (sprite->dark_level[i])
00185             {
00186                 SDL_FreeSurface(sprite->dark_level[i]);
00187             }
00188         }
00189     }
00190 
00191     free(sprite);
00192 }
00193 
00201 void sprite_blt(_Sprite *sprite, int x, int y, SDL_Rect *box, _BLTFX *bltfx)
00202 {
00203     SDL_Rect dst;
00204     SDL_Surface *surface, *blt_sprite;
00205 
00206     if (!sprite)
00207     {
00208         return;
00209     }
00210 
00211     blt_sprite = sprite->bitmap;
00212 
00213     if (bltfx && bltfx->surface)
00214     {
00215         surface = bltfx->surface;
00216     }
00217     else
00218     {
00219         surface = ScreenSurface;
00220     }
00221 
00222     dst.x = x;
00223     dst.y = y;
00224 
00225     if (bltfx)
00226     {
00227         if (bltfx->flags & BLTFX_FLAG_SRCALPHA && !(ScreenSurface->flags & SDL_HWSURFACE))
00228         {
00229             SDL_SetAlpha(blt_sprite, SDL_SRCALPHA, bltfx->alpha);
00230         }
00231     }
00232 
00233     if (!blt_sprite)
00234     {
00235         return;
00236     }
00237 
00238     if (box)
00239     {
00240         SDL_BlitSurface(blt_sprite, box, surface, &dst);
00241     }
00242     else
00243     {
00244         SDL_BlitSurface(blt_sprite, NULL, surface, &dst);
00245     }
00246 
00247     if (bltfx && bltfx->flags & BLTFX_FLAG_SRCALPHA && !(ScreenSurface->flags & SDL_HWSURFACE))
00248     {
00249         SDL_SetAlpha(blt_sprite, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
00250     }
00251 }
00252 
00261 void sprite_blt_map(_Sprite *sprite, int x, int y, SDL_Rect *box, _BLTFX *bltfx, uint32 stretch, sint16 zoom, sint16 rotate)
00262 {
00263     SDL_Rect dst;
00264     SDL_Surface *surface, *blt_sprite, *tmp;
00265 
00266     if (!sprite)
00267     {
00268         return;
00269     }
00270 
00271     blt_sprite = sprite->bitmap;
00272     surface = cur_widget[MAP_ID]->widgetSF;
00273     dst.x = x;
00274     dst.y = y;
00275 
00276     if (bltfx)
00277     {
00278         /* Is there an effect overlay active? */
00279         if (effect_has_overlay())
00280         {
00281             /* There is one, so add an overlay to the image if there isn't
00282              * one yet. */
00283             if (!sprite->effect)
00284             {
00285                 effect_scale(sprite);
00286             }
00287 
00288             blt_sprite = sprite->effect;
00289         }
00290         /* No overlay, but the image was previously overlayed; need to
00291          * free the dark surfaces so they can be re-rendered, without the
00292          * overlay. */
00293         else if (sprite->effect)
00294         {
00295             size_t i;
00296 
00297             SDL_FreeSurface(sprite->effect);
00298             sprite->effect = NULL;
00299 
00300             for (i = 0; i < DARK_LEVELS; i++)
00301             {
00302                 if (sprite->dark_level[i])
00303                 {
00304                     SDL_FreeSurface(sprite->dark_level[i]);
00305                     sprite->dark_level[i] = NULL;
00306                 }
00307             }
00308         }
00309 
00310         if (bltfx->flags & BLTFX_FLAG_DARK)
00311         {
00312             /* Last dark level is "no color" */
00313             if (bltfx->dark_level == DARK_LEVELS)
00314             {
00315                 return;
00316             }
00317 
00318             /* We create the filter surfaces only when needed, and then store them */
00319             if (!darkness_filter[bltfx->dark_level])
00320             {
00321                 SDL_SetAlpha(Bitmaps[BITMAP_TEXTWIN_MASK]->bitmap, SDL_SRCALPHA, dark_alpha[bltfx->dark_level]);
00322                 darkness_filter[bltfx->dark_level] = SDL_DisplayFormatAlpha(Bitmaps[BITMAP_TEXTWIN_MASK]->bitmap);
00323                 SDL_SetAlpha(Bitmaps[BITMAP_TEXTWIN_MASK]->bitmap, SDL_SRCALPHA | SDL_RLEACCEL, 255);
00324             }
00325 
00326             if (sprite->dark_level[bltfx->dark_level])
00327             {
00328                 blt_sprite = sprite->dark_level[bltfx->dark_level];
00329             }
00330             else
00331             {
00332                 blt_sprite = SDL_DisplayFormatAlpha(blt_sprite);
00333                 SDL_BlitSurface(darkness_filter[bltfx->dark_level], NULL, blt_sprite, NULL);
00334                 sprite->dark_level[bltfx->dark_level] = blt_sprite;
00335             }
00336         }
00337         else if (bltfx->flags & BLTFX_FLAG_FOW)
00338         {
00339             if (!sprite->fog_of_war)
00340             {
00341                 fow_scale(sprite);
00342             }
00343 
00344             blt_sprite = sprite->fog_of_war;
00345         }
00346         else if (bltfx->flags & BLTFX_FLAG_RED)
00347         {
00348             if (!sprite->red)
00349             {
00350                 red_scale(sprite);
00351             }
00352 
00353             blt_sprite = sprite->red;
00354         }
00355         else if (bltfx->flags & BLTFX_FLAG_GREY)
00356         {
00357             if (!sprite->grey)
00358             {
00359                 grey_scale(sprite);
00360             }
00361 
00362             blt_sprite = sprite->grey;
00363         }
00364 
00365         if (!blt_sprite)
00366         {
00367             return;
00368         }
00369 
00370         if (bltfx->flags & BLTFX_FLAG_STRETCH)
00371         {
00372             Uint8 n = (stretch >> 24) & 0xFF;
00373             Uint8 e = (stretch >> 16) & 0xFF;
00374             Uint8 w = (stretch >> 8) & 0xFF;
00375             Uint8 s = stretch & 0xFF;
00376             int ht_diff;
00377 
00378             tmp = tile_stretch(blt_sprite, n, e, s, w);
00379 
00380             if (!tmp)
00381             {
00382                 return;
00383             }
00384 
00385             ht_diff = tmp->h - blt_sprite->h;
00386 
00387             blt_sprite = tmp;
00388             dst.y = dst.y - ht_diff;
00389         }
00390     }
00391 
00392     if (!blt_sprite)
00393     {
00394         return;
00395     }
00396 
00397     if (rotate)
00398     {
00399         blt_sprite = rotozoomSurface(blt_sprite, rotate, zoom ? zoom / 100.0 : 1.0, setting_get_int(OPT_CAT_MAP, OPT_ZOOM_SMOOTH));
00400 
00401         if (!blt_sprite)
00402         {
00403             return;
00404         }
00405     }
00406     else if (zoom && zoom != 100)
00407     {
00408         blt_sprite = zoomSurface(blt_sprite, zoom / 100.0, zoom / 100.0, setting_get_int(OPT_CAT_MAP, OPT_ZOOM_SMOOTH));
00409 
00410         if (!blt_sprite)
00411         {
00412             return;
00413         }
00414     }
00415 
00416     if (bltfx && bltfx->flags & BLTFX_FLAG_SRCALPHA && !(ScreenSurface->flags & SDL_HWSURFACE))
00417     {
00418         SDL_SetAlpha(blt_sprite, SDL_SRCALPHA, bltfx->alpha);
00419     }
00420 
00421     SDL_BlitSurface(blt_sprite, box, surface, &dst);
00422 
00423     if (bltfx && bltfx->flags & BLTFX_FLAG_SRCALPHA && !(ScreenSurface->flags & SDL_HWSURFACE))
00424     {
00425         SDL_SetAlpha(blt_sprite, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
00426     }
00427 
00428     if (stretch || (zoom && zoom != 100) || rotate)
00429     {
00430         SDL_FreeSurface(blt_sprite);
00431     }
00432 }
00433 
00440 Uint32 getpixel(SDL_Surface *surface, int x, int y)
00441 {
00442     int bpp = surface->format->BytesPerPixel;
00443     /* The address to the pixel we want to retrieve */
00444     Uint8 *p = (Uint8 *) surface->pixels + y * surface->pitch + x * bpp;
00445 
00446     switch (bpp)
00447     {
00448         case 1:
00449             return *p;
00450 
00451         case 2:
00452             return *(Uint16 *) p;
00453 
00454         case 3:
00455             if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
00456             {
00457                 return p[0] << 16 | p[1] << 8 | p[2];
00458             }
00459             else
00460             {
00461                 return p[0] | p[1] << 8 | p[2] << 16;
00462             }
00463 
00464         case 4:
00465             return *(Uint32 *) p;
00466     }
00467 
00468     return 0;
00469 }
00470 
00477 void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
00478 {
00479     int bpp = surface->format->BytesPerPixel;
00480     /* The address to the pixel we want to set */
00481     Uint8 *p = (Uint8 *) surface->pixels + y * surface->pitch + x * bpp;
00482 
00483     switch (bpp)
00484     {
00485         case 1:
00486             *p = pixel;
00487             break;
00488 
00489         case 2:
00490             *(Uint16 *) p = pixel;
00491             break;
00492 
00493         case 3:
00494             if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
00495             {
00496                 p[0] = (pixel >> 16) & 0xff;
00497                 p[1] = (pixel >> 8) & 0xff;
00498                 p[2] = pixel & 0xff;
00499             }
00500             else
00501             {
00502                 p[0] = pixel & 0xff;
00503                 p[1] = (pixel >> 8) & 0xff;
00504                 p[2] = (pixel >> 16) & 0xff;
00505             }
00506 
00507             break;
00508 
00509         case 4:
00510             *(Uint32 *) p = pixel;
00511             break;
00512     }
00513 }
00514 
00518 static void red_scale(_Sprite *sprite)
00519 {
00520     int j, k;
00521     Uint8 r, g, b, a;
00522     SDL_Surface *temp = SDL_ConvertSurface(sprite->bitmap, FormatHolder->format, FormatHolder->flags);
00523 
00524     for (k = 0; k < temp->h; k++)
00525     {
00526         for (j = 0; j < temp->w; j++)
00527         {
00528             SDL_GetRGBA(getpixel(temp, j, k), temp->format, &r, &g, &b, &a);
00529             r = (int) (0.212671 * r + 0.715160 * g + 0.072169 * b);
00530             g = b = 0;
00531             putpixel(temp, j, k, SDL_MapRGBA(temp->format, r, g, b, a));
00532         }
00533     }
00534 
00535     sprite->red = SDL_DisplayFormatAlpha(temp);
00536     SDL_FreeSurface(temp);
00537 }
00538 
00542 static void grey_scale(_Sprite *sprite)
00543 {
00544     int j, k;
00545     Uint8 r, g, b, a;
00546     SDL_Surface *temp = SDL_ConvertSurface(sprite->bitmap, FormatHolder->format, FormatHolder->flags);
00547 
00548     for (k = 0; k < temp->h; k++)
00549     {
00550         for (j = 0; j < temp->w; j++)
00551         {
00552             SDL_GetRGBA(getpixel(temp, j, k), temp->format, &r, &g, &b, &a);
00553             r = g = b = (int) (0.212671 * r + 0.715160 * g + 0.072169 * b);
00554             putpixel(temp, j, k, SDL_MapRGBA(temp->format, r, g, b, a));
00555         }
00556     }
00557 
00558     sprite->grey = SDL_DisplayFormatAlpha(temp);
00559     SDL_FreeSurface(temp);
00560 }
00561 
00565 static void fow_scale(_Sprite *sprite)
00566 {
00567     int j, k;
00568     Uint8 r, g, b, a;
00569     SDL_Surface *temp = SDL_ConvertSurface(sprite->bitmap, FormatHolder->format, FormatHolder->flags);
00570 
00571     for (k = 0; k < temp->h; k++)
00572     {
00573         for (j = 0; j < temp->w; j++)
00574         {
00575             SDL_GetRGBA(getpixel(temp, j, k), temp->format, &r, &g, &b, &a);
00576             r = g = b = (int) ((0.212671 * r + 0.715160 * g + 0.072169 * b) * 0.34);
00577             b += 16;
00578             putpixel(temp, j, k, SDL_MapRGBA(temp->format, r, g, b, a));
00579         }
00580     }
00581 
00582     sprite->fog_of_war = SDL_DisplayFormatAlpha(temp);
00583     SDL_FreeSurface(temp);
00584 }
00585 
00595 static int GetBitmapBorders(SDL_Surface *Surface, int *up, int *down, int *left, int *right, uint32 ckey)
00596 {
00597     int x, y;
00598 
00599     *up = 0;
00600     *down = 0;
00601     *left = 0;
00602     *right = 0;
00603 
00604     /* Left side border */
00605     for (x = 0; x < Surface->w; x++)
00606     {
00607         for (y = 0; y < Surface->h; y++)
00608         {
00609             if (getpixel(Surface, x, y) != ckey)
00610             {
00611                 *left = x;
00612                 goto right_border;
00613             }
00614         }
00615     }
00616 
00617     /* We only need check this one time here - if we are here, the sprite is blank */
00618     return 0;
00619 
00620 right_border:
00621     /* Right side border */
00622     for (x = Surface->w - 1; x >= 0; x--)
00623     {
00624         for (y = 0; y < Surface->h; y++)
00625         {
00626             if (getpixel(Surface, x, y) != ckey)
00627             {
00628                 *right = (Surface->w - 1) - x;
00629                 goto up_border;
00630             }
00631         }
00632     }
00633 
00634 up_border:
00635     /* Up side border */
00636     for (y = 0; y < Surface->h; y++)
00637     {
00638         for (x = 0; x < Surface->w; x++)
00639         {
00640             if (getpixel(Surface, x, y) != ckey)
00641             {
00642                 *up = y;
00643                 goto down_border;
00644             }
00645         }
00646     }
00647 
00648 down_border:
00649     /* Down side border */
00650     for (y = Surface->h - 1; y >= 0; y--)
00651     {
00652         for (x = 0; x < Surface->w; x++)
00653         {
00654             if (getpixel(Surface, x, y) != ckey)
00655             {
00656                 *down = (Surface->h - 1) - y;
00657                 return 1;
00658             }
00659         }
00660     }
00661 
00662     return 1;
00663 }
00664 
00672 struct _anim *add_anim(int type, int mapx, int mapy, int value)
00673 {
00674     struct _anim *tmp, *anim;
00675     int num_ticks;
00676 
00677     for (tmp = start_anim; tmp; tmp = tmp->next)
00678     {
00679         if (!tmp->next)
00680         {
00681             break;
00682         }
00683     }
00684 
00685     /* tmp == null - no anim in que, else tmp = last anim */
00686     anim = (struct _anim *) malloc(sizeof(struct _anim));
00687 
00688     if (!tmp)
00689     {
00690         start_anim = anim;
00691     }
00692     else
00693     {
00694         tmp->next = anim;
00695     }
00696 
00697     anim->before = tmp;
00698     anim->next = NULL;
00699 
00700     anim->type = type;
00701 
00702     /* Starting X position */
00703     anim->x = 0;
00704 
00705     /* Starting Y position */
00706     anim->y = -5;
00707     anim->xoff = 0;
00708 
00709     /* This looks like it makes it move up the screen -- was 0 */
00710     anim->yoff = 1;
00711 
00712     /* Map coordinates */
00713     anim->mapx = mapx;
00714     anim->mapy = mapy;
00715 
00716     /* Amount of damage */
00717     anim->value = value;
00718 
00719     /* Current time in MilliSeconds */
00720     anim->start_tick = LastTick;
00721 
00722     switch (type)
00723     {
00724         case ANIM_DAMAGE:
00725             /* How many ticks to display */
00726             num_ticks = 850;
00727             anim->last_tick = anim->start_tick + num_ticks;
00728             /* 850 ticks 25 pixel move up */
00729             anim->yoff = (25.0f / 850.0f);
00730             break;
00731 
00732         case ANIM_KILL:
00733             /* How many ticks to display */
00734             num_ticks = 850;
00735             anim->last_tick = anim->start_tick + num_ticks;
00736             /* 850 ticks 25 pixel move up */
00737             anim->yoff = (25.0f / 850.0f);
00738             break;
00739     }
00740 
00741     return anim;
00742 }
00743 
00747 void remove_anim(struct _anim *anim)
00748 {
00749     struct _anim *tmp, *tmp_next;
00750 
00751     if (!anim)
00752     {
00753         return;
00754     }
00755 
00756     tmp = anim->before;
00757     tmp_next = anim->next;
00758     free(anim);
00759 
00760     if (tmp)
00761     {
00762         tmp->next = tmp_next;
00763     }
00764     else
00765     {
00766         start_anim = tmp_next;
00767     }
00768 
00769     if (tmp_next)
00770     {
00771         tmp_next->before = tmp;
00772     }
00773 }
00774 
00777 void play_anims()
00778 {
00779     struct _anim *anim, *tmp;
00780     int xpos, ypos, tmp_off;
00781     int num_ticks;
00782     char buf[32];
00783     int tmp_y;
00784 
00785     for (anim = start_anim; anim; anim = tmp)
00786     {
00787         tmp = anim->next;
00788 
00789         /* Have we passed the last tick */
00790         if (LastTick > anim->last_tick)
00791             remove_anim(anim);
00792         else
00793         {
00794             num_ticks = LastTick - anim->start_tick;
00795 
00796             switch (anim->type)
00797             {
00798                 case ANIM_DAMAGE:
00799                     tmp_y = anim->y - (int) ((float) num_ticks * anim->yoff);
00800 
00801                     if (anim->mapx >= MapData.posx && anim->mapx < MapData.posx + setting_get_int(OPT_CAT_MAP, OPT_MAP_WIDTH) && anim->mapy >= MapData.posy && anim->mapy < MapData.posy + setting_get_int(OPT_CAT_MAP, OPT_MAP_HEIGHT))
00802                     {
00803                         xpos = cur_widget[MAP_ID]->x1 + (int) ((MAP_START_XOFF + (anim->mapx - MapData.posx) * MAP_TILE_YOFF - (anim->mapy - MapData.posy - 1) * MAP_TILE_YOFF - 4) * (setting_get_int(OPT_CAT_MAP, OPT_MAP_ZOOM) / 100.0));
00804                         ypos = cur_widget[MAP_ID]->y1 + (int) ((MAP_START_YOFF + (anim->mapx - MapData.posx) * MAP_TILE_XOFF + (anim->mapy - MapData.posy - 1) * MAP_TILE_XOFF - 34) * (setting_get_int(OPT_CAT_MAP, OPT_MAP_ZOOM) / 100.0));
00805 
00806                         if (anim->value < 0)
00807                         {
00808                             snprintf(buf, sizeof(buf), "%d", abs(anim->value));
00809                             string_blt(ScreenSurface, FONT_MONO10, buf, xpos + anim->x + 4 - (int) strlen(buf) * 4 + 1, ypos + tmp_y + 1, COLOR_GREEN, TEXT_OUTLINE, NULL);
00810                         }
00811                         else
00812                         {
00813                             snprintf(buf, sizeof(buf), "%d", anim->value);
00814                             string_blt(ScreenSurface, FONT_MONO10, buf, xpos + anim->x + 4 - (int) strlen(buf) * 4 + 1, ypos + tmp_y + 1, COLOR_ORANGE, TEXT_OUTLINE, NULL);
00815                         }
00816                     }
00817 
00818                     break;
00819 
00820                 case ANIM_KILL:
00821                     tmp_y = anim->y - (int) ((float) num_ticks * anim->yoff);
00822 
00823                     if (anim->mapx >= MapData.posx && anim->mapx < MapData.posx + setting_get_int(OPT_CAT_MAP, OPT_MAP_WIDTH) && anim->mapy >= MapData.posy && anim->mapy < MapData.posy + setting_get_int(OPT_CAT_MAP, OPT_MAP_HEIGHT))
00824                     {
00825                         xpos = cur_widget[MAP_ID]->x1 + (int) ((MAP_START_XOFF + (anim->mapx - MapData.posx) * MAP_TILE_YOFF - (anim->mapy - MapData.posy - 1) * MAP_TILE_YOFF - 4) * (setting_get_int(OPT_CAT_MAP, OPT_MAP_ZOOM) / 100.0));
00826                         ypos = cur_widget[MAP_ID]->y1 + (int) ((MAP_START_YOFF + (anim->mapx - MapData.posx) * MAP_TILE_XOFF + (anim->mapy - MapData.posy - 1) * MAP_TILE_XOFF - 34) * (setting_get_int(OPT_CAT_MAP, OPT_MAP_ZOOM) / 100.0));
00827 
00828                         sprite_blt(Bitmaps[BITMAP_DEATH], xpos + anim->x - 5, ypos + tmp_y - 4, NULL, NULL);
00829                         snprintf(buf, sizeof(buf), "%d", anim->value);
00830 
00831                         tmp_off = 0;
00832 
00833                         /* Let's check the size of the value */
00834                         if (anim->value < 10)
00835                             tmp_off = 6;
00836                         else if (anim->value < 100)
00837                             tmp_off = 0;
00838                         else if (anim->value < 1000)
00839                             tmp_off = -6;
00840                         else if (anim->value < 10000)
00841                             tmp_off = -12;
00842 
00843                         string_blt(ScreenSurface, FONT_MONO10, buf, xpos + anim->x + tmp_off, ypos + tmp_y, COLOR_ORANGE, TEXT_OUTLINE, NULL);
00844                     }
00845 
00846                     break;
00847 
00848                 default:
00849                     LOG(llevBug, "Unknown animation type\n");
00850                     break;
00851             }
00852         }
00853     }
00854 }
00855 
00867 int sprite_collision(int x, int y, int x2, int y2, _Sprite *sprite1, _Sprite *sprite2)
00868 {
00869     int left1, left2;
00870     int right1, right2;
00871     int top1, top2;
00872     int bottom1, bottom2;
00873 
00874     left1 = x + sprite1->border_left;
00875     left2 = x2 + sprite2->border_left;
00876 
00877     right1 = x + sprite1->bitmap->w - sprite1->border_right;
00878     right2 = x2 + sprite2->bitmap->w - sprite2->border_right;
00879 
00880     top1 = y + sprite1->border_up;
00881     top2 = y2 + sprite2->border_down;
00882 
00883     bottom1 = y + sprite1->bitmap->h - sprite1->border_down;
00884     bottom2 = y2 + sprite2->bitmap->h - sprite2->border_down;
00885 
00886     if (bottom1 < top2)
00887     {
00888         return 0;
00889     }
00890 
00891     if (top1 > bottom2)
00892     {
00893         return 0;
00894     }
00895 
00896     if (right1 < left2)
00897     {
00898         return 0;
00899     }
00900 
00901     if (left1 > right2)
00902     {
00903         return 0;
00904     }
00905 
00906     return 1;
00907 }
00908 
00913 void surface_pan(SDL_Surface *surface, SDL_Rect *box)
00914 {
00915     if (box->x >= surface->w - box->w)
00916     {
00917         box->x = (Sint16) (surface->w - box->w);
00918     }
00919 
00920     if (box->x < 0)
00921     {
00922         box->x = 0;
00923     }
00924 
00925     if (box->y >= surface->h - box->h)
00926     {
00927         box->y = (Sint16) (surface->h - box->h);
00928     }
00929 
00930     if (box->y < 0)
00931     {
00932         box->y = 0;
00933     }
00934 }
00935 
00943 void draw_frame(SDL_Surface *surface, int x, int y, int w, int h)
00944 {
00945     SDL_Rect box;
00946 
00947     box.x = x;
00948     box.y = y;
00949     box.h = h;
00950     box.w = 1;
00951     SDL_FillRect(surface, &box, SDL_MapRGB(surface->format, 0x60, 0x60, 0x60));
00952     box.x = x + w;
00953     box.h++;
00954     SDL_FillRect(surface, &box, SDL_MapRGB(surface->format, 0x55, 0x55, 0x55));
00955     box.x = x;
00956     box.y+= h;
00957     box.w = w;
00958     box.h = 1;
00959     SDL_FillRect(surface, &box, SDL_MapRGB(surface->format, 0x60, 0x60, 0x60));
00960     box.x++;
00961     box.y = y;
00962     SDL_FillRect(surface, &box, SDL_MapRGB(surface->format, 0x55, 0x55, 0x55));
00963 }
00964 
00974 void border_create(SDL_Surface *surface, int x, int y, int w, int h, int color, int size)
00975 {
00976     SDL_Rect box;
00977 
00978     /* Left border. */
00979     box.x = x;
00980     box.y = y;
00981     box.h = h;
00982     box.w = size;
00983     SDL_FillRect(surface, &box, color);
00984 
00985     /* Right border. */
00986     box.x = x + w - size;
00987     SDL_FillRect(surface, &box, color);
00988 
00989     /* Top border. */
00990     box.x = x + size;
00991     box.y = y;
00992     box.w = w - size * 2;
00993     box.h = size;
00994     SDL_FillRect(surface, &box, color);
00995 
00996     /* Bottom border. */
00997     box.y = y + h - size;
00998     SDL_FillRect(surface, &box, color);
00999 }
01000 
01001 void border_create_color(SDL_Surface *surface, SDL_Rect *coords, const char *color_notation)
01002 {
01003     SDL_Color color;
01004     SDL_Rect dst;
01005     Uint32 color_mapped;
01006 
01007     if (!text_color_parse(color_notation, &color))
01008     {
01009         LOG(llevBug, "border_create_color(): Invalid color: %s\n", color_notation);
01010         return;
01011     }
01012 
01013     color_mapped = SDL_MapRGB(surface->format, color.r, color.g, color.b);
01014 
01015     dst.x = coords->x;
01016     dst.y = coords->y;
01017     dst.h = coords->h;
01018     dst.w = 1;
01019     SDL_FillRect(surface, &dst, color_mapped);
01020     dst.x = coords->x + coords->w;
01021     dst.h++;
01022     SDL_FillRect(surface, &dst, color_mapped);
01023     dst.x = coords->x;
01024     dst.y += coords->h;
01025     dst.w = coords->w;
01026     dst.h = 1;
01027     SDL_FillRect(surface, &dst, color_mapped);
01028     dst.x++;
01029     dst.y = coords->y;
01030     SDL_FillRect(surface, &dst, color_mapped);
01031 }