|
Atrinik Client 2.5
|
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 static effect_struct *effects = NULL; 00035 static effect_struct *current_effect = NULL; 00037 static const char *overlay_cols[] = {"r", "g", "b", "a"}; 00038 00041 void effects_init() 00042 { 00043 FILE *fp; 00044 char buf[MAX_BUF], *cp; 00045 effect_struct *effect = NULL; 00046 effect_sprite_def *sprite_def = NULL; 00047 effect_overlay *overlay = NULL; 00048 00049 /* Try to deinitialize all effects first. */ 00050 effects_deinit(); 00051 00052 fp = server_file_open(SERVER_FILE_EFFECTS); 00053 00054 if (!fp) 00055 { 00056 return; 00057 } 00058 00059 /* Read the file... */ 00060 while (fgets(buf, sizeof(buf) - 1, fp)) 00061 { 00062 /* Ignore comments and blank lines. */ 00063 if (buf[0] == '#' || buf[0] == '\n') 00064 { 00065 continue; 00066 } 00067 00068 /* End a previous 'effect xxx' or 'sprite xxx' block. */ 00069 if (!strcmp(buf, "end\n")) 00070 { 00071 /* Inside effect block. */ 00072 if (effect) 00073 { 00074 /* Inside sprite block. */ 00075 if (sprite_def) 00076 { 00077 /* Add this sprite to the linked list. */ 00078 sprite_def->next = effect->sprite_defs; 00079 effect->sprite_defs = sprite_def; 00080 /* Update total chance value. */ 00081 effect->chance_total += sprite_def->chance; 00082 sprite_def = NULL; 00083 } 00084 /* Overlay block, just set it as the effect's overlay. */ 00085 else if (overlay) 00086 { 00087 effect->overlay = overlay; 00088 overlay = NULL; 00089 } 00090 /* Inside effect block. */ 00091 else 00092 { 00093 /* Add this effect to the linked list of effects. */ 00094 effect->next = effects; 00095 effects = effect; 00096 effect = NULL; 00097 } 00098 } 00099 00100 continue; 00101 } 00102 00103 cp = strrchr(buf, '\n'); 00104 00105 /* Eliminate newline. */ 00106 if (cp) 00107 { 00108 *cp = '\0'; 00109 } 00110 00111 /* Parse definitions inside sprite block. */ 00112 if (sprite_def) 00113 { 00114 if (!strncmp(buf, "chance ", 7)) 00115 { 00116 sprite_def->chance = atoi(buf + 7); 00117 } 00118 else if (!strncmp(buf, "weight ", 7)) 00119 { 00120 sprite_def->weight = atof(buf + 7); 00121 } 00122 else if (!strncmp(buf, "weight_mod ", 11)) 00123 { 00124 sprite_def->weight_mod = atof(buf + 11); 00125 } 00126 else if (!strncmp(buf, "delay ", 6)) 00127 { 00128 sprite_def->delay = atoi(buf + 6); 00129 } 00130 else if (!strncmp(buf, "wind ", 5)) 00131 { 00132 sprite_def->wind = atoi(buf + 5); 00133 } 00134 else if (!strncmp(buf, "wiggle ", 7)) 00135 { 00136 sprite_def->wiggle = atof(buf + 7); 00137 } 00138 else if (!strncmp(buf, "wind_mod ", 9)) 00139 { 00140 sprite_def->wind_mod = atof(buf + 9); 00141 } 00142 else if (!strncmp(buf, "x ", 2)) 00143 { 00144 sprite_def->x = atoi(buf + 2); 00145 } 00146 else if (!strncmp(buf, "y ", 2)) 00147 { 00148 sprite_def->y = atoi(buf + 2); 00149 } 00150 else if (!strncmp(buf, "xpos ", 5)) 00151 { 00152 sprite_def->xpos = atoi(buf + 5); 00153 } 00154 else if (!strncmp(buf, "ypos ", 5)) 00155 { 00156 sprite_def->ypos = atoi(buf + 5); 00157 } 00158 else if (!strncmp(buf, "reverse ", 8)) 00159 { 00160 sprite_def->reverse = atoi(buf + 8); 00161 sprite_def->y_mod = -sprite_def->y_mod; 00162 } 00163 else if (!strncmp(buf, "y_rndm ", 7)) 00164 { 00165 sprite_def->y_rndm = atof(buf + 7); 00166 } 00167 else if (!strncmp(buf, "x_mod ", 6)) 00168 { 00169 sprite_def->x_mod = atof(buf + 6); 00170 } 00171 else if (!strncmp(buf, "y_mod ", 6)) 00172 { 00173 sprite_def->y_mod = atof(buf + 6); 00174 } 00175 else if (!strncmp(buf, "x_check_mod ", 12)) 00176 { 00177 sprite_def->x_check_mod = atoi(buf + 12); 00178 } 00179 else if (!strncmp(buf, "y_check_mod ", 12)) 00180 { 00181 sprite_def->y_check_mod = atoi(buf + 12); 00182 } 00183 else if (!strncmp(buf, "kill_sides ", 11)) 00184 { 00185 sprite_def->kill_side_left = sprite_def->kill_side_right = atoi(buf + 11); 00186 } 00187 else if (!strncmp(buf, "kill_side_left ", 15)) 00188 { 00189 sprite_def->kill_side_left = atoi(buf + 15); 00190 } 00191 else if (!strncmp(buf, "kill_side_right ", 16)) 00192 { 00193 sprite_def->kill_side_right = atoi(buf + 16); 00194 } 00195 else if (!strncmp(buf, "zoom ", 5)) 00196 { 00197 sprite_def->zoom = atoi(buf + 5); 00198 } 00199 else if (!strncmp(buf, "warp_sides ", 11)) 00200 { 00201 sprite_def->warp_sides = atoi(buf + 11); 00202 } 00203 else if (!strncmp(buf, "ttl ", 4)) 00204 { 00205 sprite_def->ttl = atoi(buf + 4); 00206 } 00207 else if (!strncmp(buf, "sound_file ", 11)) 00208 { 00209 strncpy(sprite_def->sound_file, buf + 11, sizeof(sprite_def->sound_file) - 1); 00210 sprite_def->sound_file[sizeof(sprite_def->sound_file) - 1] = '\0'; 00211 } 00212 else if (!strncmp(buf, "sound_volume ", 13)) 00213 { 00214 sprite_def->sound_volume = atoi(buf + 13); 00215 } 00216 } 00217 else if (!strcmp(buf, "overlay")) 00218 { 00219 size_t col; 00220 00221 overlay = calloc(1, sizeof(effect_overlay)); 00222 00223 for (col = 0; col < arraysize(overlay_cols); col++) 00224 { 00225 overlay->col[col].val = -1; 00226 overlay->col[col].mod[4] = 1.0; 00227 } 00228 } 00229 else if (overlay) 00230 { 00231 size_t col; 00232 00233 for (col = 0; col < arraysize(overlay_cols); col++) 00234 { 00235 if (!strncmp(buf, overlay_cols[col], strlen(overlay_cols[col]))) 00236 { 00237 if (!strncmp(buf + 1, "_rndm_min ", 10)) 00238 { 00239 overlay->col[col].rndm_min = atoi(buf + 11); 00240 } 00241 else if (!strncmp(buf + 1, "_rndm_max ", 10)) 00242 { 00243 overlay->col[col].rndm_max = atoi(buf + 11); 00244 } 00245 else if (!strncmp(buf + 1, "_mod1 ", 6)) 00246 { 00247 overlay->col[col].mod[0] = atof(buf + 7); 00248 } 00249 else if (!strncmp(buf + 1, "_mod2 ", 6)) 00250 { 00251 overlay->col[col].mod[1] = atof(buf + 7); 00252 } 00253 else if (!strncmp(buf + 1, "_mod3 ", 6)) 00254 { 00255 overlay->col[col].mod[2] = atof(buf + 7); 00256 } 00257 else if (!strncmp(buf + 1, "_mod4 ", 6)) 00258 { 00259 overlay->col[col].mod[3] = atof(buf + 7); 00260 } 00261 else if (!strncmp(buf + 1, "_mod5 ", 6)) 00262 { 00263 overlay->col[col].mod[4] = atof(buf + 7); 00264 } 00265 else 00266 { 00267 overlay->col[col].val = atoi(buf + 2); 00268 } 00269 } 00270 } 00271 } 00272 /* Parse definitions inside effect block. */ 00273 else if (effect) 00274 { 00275 if (!strncmp(buf, "wind_chance ", 12)) 00276 { 00277 effect->wind_chance = atof(buf + 12); 00278 } 00279 else if (!strncmp(buf, "sprite_chance ", 14)) 00280 { 00281 effect->sprite_chance = atof(buf + 14); 00282 } 00283 else if (!strncmp(buf, "delay ", 6)) 00284 { 00285 effect->delay = atoi(buf + 6); 00286 } 00287 else if (!strncmp(buf, "wind_blow_dir ", 14)) 00288 { 00289 effect->wind_blow_dir = atoi(buf + 14); 00290 } 00291 else if (!strncmp(buf, "max_sprites ", 12)) 00292 { 00293 effect->max_sprites = atoi(buf + 12); 00294 } 00295 else if (!strncmp(buf, "wind_mod ", 9)) 00296 { 00297 effect->wind_mod = atof(buf + 9); 00298 } 00299 else if (!strncmp(buf, "sprites_per_move ", 17)) 00300 { 00301 effect->sprites_per_move = atoi(buf + 17); 00302 } 00303 /* Start of sprite block. */ 00304 else if (!strncmp(buf, "sprite ", 7)) 00305 { 00306 sprite_def = calloc(1, sizeof(*sprite_def)); 00307 /* Store the sprite ID and name. */ 00308 sprite_def->id = get_bmap_id(buf + 7); 00309 sprite_def->name = strdup(buf + 7); 00310 /* Initialize default values. */ 00311 sprite_def->chance = 1; 00312 sprite_def->weight = 1.0; 00313 sprite_def->weight_mod = 2.0; 00314 sprite_def->wind = 1; 00315 sprite_def->wiggle = 1.0; 00316 sprite_def->wind_mod = 1.0; 00317 sprite_def->x = -1; 00318 sprite_def->y = -1; 00319 sprite_def->reverse = 0; 00320 sprite_def->y_rndm = 60.0; 00321 sprite_def->x_mod = 1.0; 00322 sprite_def->y_mod = 1.0; 00323 sprite_def->x_check_mod = 1; 00324 sprite_def->y_check_mod = 1; 00325 sprite_def->kill_side_left = 1; 00326 sprite_def->kill_side_right = 0; 00327 sprite_def->zoom = 0; 00328 sprite_def->warp_sides = 1; 00329 sprite_def->ttl = 0; 00330 sprite_def->sound_volume = 100; 00331 } 00332 } 00333 /* Start of effect block. */ 00334 else if (!strncmp(buf, "effect ", 7)) 00335 { 00336 effect = calloc(1, sizeof(effect_struct)); 00337 /* Store the effect unique name. */ 00338 strncpy(effect->name, buf + 7, sizeof(effect->name) - 1); 00339 effect->name[sizeof(effect->name) - 1] = '\0'; 00340 /* Initialize default values. */ 00341 effect->wind_chance = 0.98; 00342 effect->sprite_chance = 60.0; 00343 effect->wind_blow_dir = WIND_BLOW_RANDOM; 00344 effect->wind_mod = 1.0; 00345 effect->max_sprites = -1; 00346 effect->sprites_per_move = 1; 00347 } 00348 } 00349 00350 /* Close the file. */ 00351 fclose(fp); 00352 } 00353 00356 void effects_deinit() 00357 { 00358 effect_struct *effect, *effect_next; 00359 effect_sprite_def *sprite_def, *sprite_def_next; 00360 00361 /* Deinitialize all effects. */ 00362 for (effect = effects; effect; effect = effect_next) 00363 { 00364 effect_next = effect->next; 00365 00366 /* Deinitialize the effect's sprite definitions. */ 00367 for (sprite_def = effect->sprite_defs; sprite_def; sprite_def = sprite_def_next) 00368 { 00369 sprite_def_next = sprite_def->next; 00370 effect_sprite_def_free(sprite_def); 00371 } 00372 00373 /* Deinitialize the shown sprites and the actual effect. */ 00374 effect_sprites_free(effect); 00375 effect_free(effect); 00376 } 00377 00378 effects = current_effect = NULL; 00379 } 00380 00384 void effects_reinit() 00385 { 00386 effect_struct *effect; 00387 effect_sprite_def *sprite_def; 00388 00389 for (effect = effects; effect; effect = effect->next) 00390 { 00391 for (sprite_def = effect->sprite_defs; sprite_def; sprite_def = sprite_def->next) 00392 { 00393 sprite_def->id = get_bmap_id(sprite_def->name); 00394 } 00395 } 00396 } 00397 00401 void effect_sprites_free(effect_struct *effect) 00402 { 00403 effect_sprite *tmp, *next; 00404 00405 for (tmp = effect->sprites; tmp; tmp = next) 00406 { 00407 next = tmp->next; 00408 effect_sprite_free(tmp); 00409 } 00410 00411 effect->sprites = effect->sprites_end = NULL; 00412 } 00413 00417 void effect_free(effect_struct *effect) 00418 { 00419 if (effect->overlay) 00420 { 00421 free(effect->overlay); 00422 } 00423 00424 free(effect); 00425 } 00426 00430 void effect_sprite_def_free(effect_sprite_def *sprite_def) 00431 { 00432 free(sprite_def->name); 00433 free(sprite_def); 00434 } 00435 00439 void effect_sprite_free(effect_sprite *sprite) 00440 { 00441 free(sprite); 00442 } 00443 00447 void effect_sprite_remove(effect_sprite *sprite) 00448 { 00449 if (!sprite || !current_effect) 00450 { 00451 return; 00452 } 00453 00454 if (sprite->prev) 00455 { 00456 sprite->prev->next = sprite->next; 00457 } 00458 else 00459 { 00460 current_effect->sprites = sprite->next; 00461 } 00462 00463 if (sprite->next) 00464 { 00465 sprite->next->prev = sprite->prev; 00466 } 00467 else 00468 { 00469 current_effect->sprites_end = sprite->prev; 00470 } 00471 00472 effect_sprite_free(sprite); 00473 } 00474 00481 static effect_sprite *effect_sprite_create(effect_struct *effect) 00482 { 00483 int roll; 00484 effect_sprite_def *tmp; 00485 effect_sprite *sprite; 00486 00487 if (!effect->sprite_defs) 00488 { 00489 return NULL; 00490 } 00491 00492 /* Choose which sprite to use. */ 00493 roll = rndm(1, effect->chance_total) - 1; 00494 00495 for (tmp = effect->sprite_defs; tmp; tmp = tmp->next) 00496 { 00497 roll -= tmp->chance; 00498 00499 if (roll < 0) 00500 { 00501 break; 00502 } 00503 } 00504 00505 if (!tmp) 00506 { 00507 return NULL; 00508 } 00509 00510 /* Allocate a new sprite. */ 00511 sprite = calloc(1, sizeof(*sprite)); 00512 sprite->def = tmp; 00513 00514 /* Add it to the linked list. */ 00515 if (!effect->sprites) 00516 { 00517 effect->sprites = effect->sprites_end = sprite; 00518 } 00519 else 00520 { 00521 effect->sprites_end->next = sprite; 00522 sprite->prev = effect->sprites_end; 00523 effect->sprites_end = sprite; 00524 } 00525 00526 return sprite; 00527 } 00528 00531 void effect_sprites_play() 00532 { 00533 effect_sprite *tmp, *next; 00534 int num_sprites = 0; 00535 int x_check, y_check; 00536 uint32 ticks; 00537 00538 /* No current effect or not playing, quit. */ 00539 if (!current_effect || GameStatus != GAME_STATUS_PLAY) 00540 { 00541 return; 00542 } 00543 00544 ticks = SDL_GetTicks(); 00545 00546 for (tmp = current_effect->sprites; tmp; tmp = next) 00547 { 00548 next = tmp->next; 00549 00550 if (!FaceList[tmp->def->id].sprite) 00551 { 00552 continue; 00553 } 00554 00555 /* Check if the sprite should be removed due to ttl being up. */ 00556 if (tmp->def->ttl && ticks - tmp->created_tick > tmp->def->ttl) 00557 { 00558 effect_sprite_remove(tmp); 00559 continue; 00560 } 00561 00562 x_check = y_check = 0; 00563 00564 if (tmp->def->x_check_mod) 00565 { 00566 x_check = FaceList[tmp->def->id].sprite->bitmap->w; 00567 } 00568 00569 if (tmp->def->y_check_mod) 00570 { 00571 y_check = FaceList[tmp->def->id].sprite->bitmap->h; 00572 } 00573 00574 if (tmp->def->warp_sides) 00575 { 00576 if (tmp->x + x_check < 0) 00577 { 00578 tmp->x = cur_widget[MAP_ID]->wd; 00579 continue; 00580 } 00581 else if (tmp->x - x_check > cur_widget[MAP_ID]->wd) 00582 { 00583 tmp->x = -x_check; 00584 continue; 00585 } 00586 } 00587 00588 /* Off-screen? */ 00589 if ((tmp->def->kill_side_left && tmp->x + x_check < 0) || (tmp->def->kill_side_right && tmp->x - x_check > cur_widget[MAP_ID]->ht) || tmp->y + y_check < 0 || tmp->y - y_check > cur_widget[MAP_ID]->ht) 00590 { 00591 effect_sprite_remove(tmp); 00592 continue; 00593 } 00594 00595 /* Show the sprite. */ 00596 sprite_blt_map(FaceList[tmp->def->id].sprite, tmp->x, tmp->y, NULL, NULL, 0, tmp->def->zoom, 0); 00597 num_sprites++; 00598 00599 /* Move it if there is no delay configured or if enough time has passed. */ 00600 if (!tmp->def->delay || !tmp->delay_ticks || ticks - tmp->delay_ticks > tmp->def->delay) 00601 { 00602 int ypos = tmp->def->weight * tmp->def->weight_mod; 00603 00604 if (tmp->def->reverse) 00605 { 00606 ypos = -ypos; 00607 } 00608 00609 tmp->y += ypos; 00610 tmp->x += (-1.0 + 3.0 * RANDOM() / (RAND_MAX + 1.0)) * tmp->def->wiggle; 00611 00612 /* Apply wind. */ 00613 if (tmp->def->wind && current_effect->wind_blow_dir != WIND_BLOW_NONE) 00614 { 00615 tmp->x += ((double) current_effect->wind / tmp->def->weight + tmp->def->weight * tmp->def->weight_mod * ((-1.0 + 2.0 * RANDOM() / (RAND_MAX + 1.0)) * tmp->def->wind_mod)); 00616 } 00617 00618 tmp->delay_ticks = ticks; 00619 map_redraw_flag = 1; 00620 } 00621 } 00622 00623 /* Change wind direction... */ 00624 if (current_effect->wind_blow_dir == WIND_BLOW_RANDOM && current_effect->wind_chance != 1.0 && (current_effect->wind_chance == 0.0 || RANDOM() / (RAND_MAX + 1.0) >= current_effect->wind_chance)) 00625 { 00626 current_effect->wind += (-2.0 + 4.0 * RANDOM() / (RAND_MAX + 1.0)) * current_effect->wind_mod; 00627 } 00628 00629 if (current_effect->wind_blow_dir == WIND_BLOW_LEFT) 00630 { 00631 current_effect->wind = -1.0 * current_effect->wind_mod; 00632 } 00633 else if (current_effect->wind_blow_dir == WIND_BLOW_RIGHT) 00634 { 00635 current_effect->wind = 1.0 * current_effect->wind_mod; 00636 } 00637 00638 if ((current_effect->max_sprites == -1 || num_sprites < current_effect->max_sprites) && (!current_effect->delay || !current_effect->delay_ticks || ticks - current_effect->delay_ticks > current_effect->delay) && RANDOM() / (RAND_MAX + 1.0) >= (100.0 - current_effect->sprite_chance) / 100.0) 00639 { 00640 int i; 00641 effect_sprite *sprite; 00642 00643 for (i = 0; i < current_effect->sprites_per_move; i++) 00644 { 00645 /* Add the sprite. */ 00646 sprite = effect_sprite_create(current_effect); 00647 00648 if (!sprite) 00649 { 00650 return; 00651 } 00652 00653 /* Invalid sprite. */ 00654 if (sprite->def->id == -1 || !FaceList[sprite->def->id].sprite) 00655 { 00656 LOG(llevInfo, "Invalid sprite ID %d\n", sprite->def->id); 00657 effect_sprite_remove(sprite); 00658 return; 00659 } 00660 00661 if (sprite->def->x != -1) 00662 { 00663 sprite->x = sprite->def->x; 00664 } 00665 else 00666 { 00667 /* Calculate where to put the sprite. */ 00668 sprite->x = (double) cur_widget[MAP_ID]->wd * RANDOM() / (RAND_MAX + 1.0) * sprite->def->x_mod; 00669 } 00670 00671 if (sprite->def->reverse) 00672 { 00673 sprite->y = cur_widget[MAP_ID]->ht - FaceList[sprite->def->id].sprite->bitmap->h; 00674 } 00675 else if (sprite->def->y != -1) 00676 { 00677 sprite->y = sprite->def->y; 00678 } 00679 00680 sprite->y += sprite->def->y_rndm * (RANDOM() / (RAND_MAX + 1.0) * sprite->def->y_mod); 00681 00682 sprite->x += sprite->def->xpos; 00683 sprite->y += sprite->def->ypos; 00684 00685 if (sprite->def->sound_file[0] != '\0') 00686 { 00687 sound_play_effect(sprite->def->sound_file, sprite->def->sound_volume); 00688 } 00689 00690 sprite->created_tick = ticks; 00691 map_redraw_flag = 1; 00692 } 00693 00694 current_effect->delay_ticks = ticks; 00695 } 00696 } 00697 00703 int effect_start(const char *name) 00704 { 00705 effect_struct *tmp; 00706 00707 /* Stop playing any effect. */ 00708 if (!strcmp(name, "none")) 00709 { 00710 effect_stop(); 00711 return 1; 00712 } 00713 00714 /* Already playing the same effect? */ 00715 if (current_effect && !strcmp(current_effect->name, name)) 00716 { 00717 return 1; 00718 } 00719 00720 /* Find the effect... */ 00721 for (tmp = effects; tmp; tmp = tmp->next) 00722 { 00723 /* Found it? */ 00724 if (!strcmp(tmp->name, name)) 00725 { 00726 /* Stop current effect (if any) */ 00727 effect_stop(); 00728 /* Reset wind direction. */ 00729 tmp->wind = 0; 00730 /* Load it up. */ 00731 current_effect = tmp; 00732 00733 /* Does this effect have an overlay? If so, we need to free 00734 * old dark levels, as they are rendered without the image 00735 * overlay. */ 00736 if (current_effect->overlay) 00737 { 00738 size_t i, dark; 00739 00740 for (i = 0; i < MAX_FACE_TILES; i++) 00741 { 00742 if (!FaceList[i].sprite) 00743 { 00744 continue; 00745 } 00746 00747 if (FaceList[i].sprite->effect) 00748 { 00749 SDL_FreeSurface(FaceList[i].sprite->effect); 00750 FaceList[i].sprite->effect = NULL; 00751 } 00752 00753 /* Free all dark levels. */ 00754 for (dark = 0; dark < DARK_LEVELS; dark++) 00755 { 00756 if (FaceList[i].sprite->dark_level[dark]) 00757 { 00758 SDL_FreeSurface(FaceList[i].sprite->dark_level[dark]); 00759 FaceList[i].sprite->dark_level[dark] = NULL; 00760 } 00761 } 00762 } 00763 } 00764 00765 return 1; 00766 } 00767 } 00768 00769 return 0; 00770 } 00771 00775 void effect_debug(const char *type) 00776 { 00777 if (!strcmp(type, "num")) 00778 { 00779 uint32 num = 0; 00780 uint64 bytes; 00781 double kbytes; 00782 effect_sprite *tmp; 00783 00784 if (!current_effect) 00785 { 00786 draw_info(COLOR_RED, "No effect is currently playing."); 00787 return; 00788 } 00789 00790 for (tmp = current_effect->sprites; tmp; tmp = tmp->next) 00791 { 00792 num++; 00793 } 00794 00795 bytes = ((uint64) sizeof(effect_sprite)) * num; 00796 kbytes = (double) bytes / 1024; 00797 00798 draw_info_format(COLOR_WHITE, "Visible sprites: <green>%d</green> using <green>%"FMT64U"</green> bytes (<green>%2.2f</green> KB)", num, bytes, kbytes); 00799 } 00800 else if (!strcmp(type, "sizeof")) 00801 { 00802 draw_info(COLOR_WHITE, "Information about various data structures used by effects:\n"); 00803 draw_info_format(COLOR_WHITE, "Size of a single sprite definition: <green>%"FMT64U"</green>", (uint64) sizeof(effect_sprite_def)); 00804 draw_info_format(COLOR_WHITE, "Size of a single visible sprite: <green>%"FMT64U"</green>", (uint64) sizeof(effect_sprite)); 00805 draw_info_format(COLOR_WHITE, "Size of a single effect structure: <green>%"FMT64U"</green>", (uint64) sizeof(effect_struct)); 00806 draw_info_format(COLOR_WHITE, "Size of a single overlay: <green>%"FMT64U"</green>", (uint64) sizeof(effect_overlay)); 00807 } 00808 else 00809 { 00810 draw_info_format(COLOR_RED, "No such debug option '%s'.", type); 00811 } 00812 } 00813 00816 void effect_stop() 00817 { 00818 if (!current_effect) 00819 { 00820 return; 00821 } 00822 00823 effect_sprites_free(current_effect); 00824 current_effect = NULL; 00825 } 00826 00830 uint8 effect_has_overlay() 00831 { 00832 if (!current_effect) 00833 { 00834 return 0; 00835 } 00836 00837 return current_effect->overlay ? 1 : 0; 00838 } 00839 00843 void effect_scale(_Sprite *sprite) 00844 { 00845 int j, k, r, g, b, a, idx; 00846 Uint8 vals[4]; 00847 SDL_Surface *temp = SDL_ConvertSurface(sprite->bitmap, FormatHolder->format, FormatHolder->flags); 00848 00849 for (k = 0; k < temp->h; k++) 00850 { 00851 for (j = 0; j < temp->w; j++) 00852 { 00853 SDL_GetRGBA(getpixel(temp, j, k), temp->format, &vals[0], &vals[1], &vals[2], &vals[3]); 00854 00855 idx = 0; 00856 EFFECT_SCALE_ADJUST(r, current_effect->overlay); 00857 EFFECT_SCALE_ADJUST(g, current_effect->overlay); 00858 EFFECT_SCALE_ADJUST(b, current_effect->overlay); 00859 EFFECT_SCALE_ADJUST(a, current_effect->overlay); 00860 00861 putpixel(temp, j, k, SDL_MapRGBA(temp->format, r, g, b, a)); 00862 } 00863 } 00864 00865 sprite->effect = SDL_DisplayFormatAlpha(temp); 00866 SDL_FreeSurface(temp); 00867 }
1.7.4