|
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 #include <region_map.h> 00032 00034 static curl_data *data_png = NULL; 00036 static curl_data *data_def = NULL; 00038 static SDL_Surface *region_map_png = NULL; 00043 static SDL_Surface *region_map_png_orig; 00045 static region_map_def *rm_def = NULL; 00047 static char current_map[MAX_BUF]; 00049 static sint16 current_x; 00051 static sint16 current_y; 00053 static char **cmd_labels = NULL; 00055 static size_t num_cmd_labels = 0; 00057 static char **cmd_tooltips = NULL; 00059 static size_t num_cmd_tooltips = 0; 00061 static int region_map_zoom; 00063 static SDL_Rect region_map_pos; 00065 static uint32 region_mouse_ticks = 0; 00066 00068 #define RM_TOOLTIP_HEIGHT 150 00069 00074 static region_map_struct *rm_def_get_map(const char *path) 00075 { 00076 size_t i; 00077 00078 for (i = 0; i < rm_def->num_maps; i++) 00079 { 00080 if (!strcmp(rm_def->maps[i].path, path)) 00081 { 00082 return &rm_def->maps[i]; 00083 } 00084 } 00085 00086 return NULL; 00087 } 00088 00093 static region_label_struct *rm_find_label(const char *name) 00094 { 00095 size_t i; 00096 00097 for (i = 0; i < rm_def->num_labels; i++) 00098 { 00099 if (!strcmp(rm_def->labels[i].name, name)) 00100 { 00101 return &rm_def->labels[i]; 00102 } 00103 } 00104 00105 return NULL; 00106 } 00107 00112 static region_map_tooltip *rm_find_tooltip(const char *name) 00113 { 00114 size_t i; 00115 00116 for (i = 0; i < rm_def->num_tooltips; i++) 00117 { 00118 if (!strcmp(rm_def->tooltips[i].name, name)) 00119 { 00120 return &rm_def->tooltips[i]; 00121 } 00122 } 00123 00124 return NULL; 00125 } 00126 00130 static void rm_def_create(char *str) 00131 { 00132 char *cp; 00133 size_t i; 00134 region_label_struct *label; 00135 00136 rm_def = calloc(1, sizeof(region_map_def)); 00137 rm_def->pixel_size = 1; 00138 rm_def->map_size_x = 24; 00139 rm_def->map_size_y = 24; 00140 00141 cp = strtok(str, "\n"); 00142 00143 while (cp) 00144 { 00145 if (!strncmp(cp, "pixel_size ", 11)) 00146 { 00147 rm_def->pixel_size = atoi(cp + 11); 00148 } 00149 else if (!strncmp(cp, "map_size_x ", 11)) 00150 { 00151 rm_def->map_size_x = atoi(cp + 11); 00152 } 00153 else if (!strncmp(cp, "map_size_y ", 11)) 00154 { 00155 rm_def->map_size_y = atoi(cp + 11); 00156 } 00157 /* Map command, add it to the list of maps. */ 00158 else if (!strncmp(cp, "map ", 4)) 00159 { 00160 uint32 x, y; 00161 char path[HUGE_BUF * 4]; 00162 00163 rm_def->maps = realloc(rm_def->maps, sizeof(*rm_def->maps) * (rm_def->num_maps + 1)); 00164 00165 if (sscanf(cp + 4, "%x %x %s", &x, &y, path) == 3) 00166 { 00167 rm_def->maps[rm_def->num_maps].xpos = x; 00168 rm_def->maps[rm_def->num_maps].ypos = y; 00169 rm_def->maps[rm_def->num_maps].path = strdup(path); 00170 } 00171 00172 rm_def->num_maps++; 00173 } 00174 /* Add label. */ 00175 else if (!strncmp(cp, "label ", 6)) 00176 { 00177 uint32 x, y; 00178 char label_name[MAX_BUF], label_text[HUGE_BUF * 2]; 00179 00180 if (sscanf(cp + 6, "%x %x %s %8191[^\n]", &x, &y, label_name, label_text) == 4) 00181 { 00182 rm_def->labels = realloc(rm_def->labels, sizeof(*rm_def->labels) * (rm_def->num_labels + 1)); 00183 rm_def->labels[rm_def->num_labels].hidden = -1; 00184 rm_def->labels[rm_def->num_labels].x = x; 00185 rm_def->labels[rm_def->num_labels].y = y; 00186 convert_newline(label_text); 00187 rm_def->labels[rm_def->num_labels].name = strdup(label_name); 00188 rm_def->labels[rm_def->num_labels].text = strdup(label_text); 00189 rm_def->num_labels++; 00190 } 00191 } 00192 /* Hide the previously added label. */ 00193 else if (!strncmp(cp, "label_hide", 10)) 00194 { 00195 rm_def->labels[rm_def->num_labels - 1].hidden = 1; 00196 } 00197 /* Add tooltip. */ 00198 else if (!strncmp(cp, "tooltip ", 8)) 00199 { 00200 uint32 x, y, w, h; 00201 char tooltip_name[MAX_BUF], tooltip[HUGE_BUF * 2]; 00202 00203 if (sscanf(cp + 8, "%x %x %x %x %s %8191[^\n]", &x, &y, &w, &h, tooltip_name, tooltip) == 6) 00204 { 00205 rm_def->tooltips = realloc(rm_def->tooltips, sizeof(*rm_def->tooltips) * (rm_def->num_tooltips + 1)); 00206 rm_def->tooltips[rm_def->num_tooltips].hidden = -1; 00207 rm_def->tooltips[rm_def->num_tooltips].outline = 0; 00208 rm_def->tooltips[rm_def->num_tooltips].x = x; 00209 rm_def->tooltips[rm_def->num_tooltips].y = y; 00210 rm_def->tooltips[rm_def->num_tooltips].w = w; 00211 rm_def->tooltips[rm_def->num_tooltips].h = h; 00212 convert_newline(tooltip); 00213 00214 rm_def->tooltips[rm_def->num_tooltips].text = strdup(tooltip); 00215 rm_def->tooltips[rm_def->num_tooltips].name = strdup(tooltip_name); 00216 rm_def->num_tooltips++; 00217 } 00218 } 00219 else if (!strncmp(cp, "tooltip_hide", 12)) 00220 { 00221 rm_def->tooltips[rm_def->num_tooltips - 1].hidden = 1; 00222 } 00223 else if (!strncmp(cp, "t_outline ", 10)) 00224 { 00225 uint32 r, g, b; 00226 int outline_size = 1; 00227 00228 if (sscanf(cp + 10, "#%2X%2X%2X %d", &r, &g, &b, &outline_size) >= 3) 00229 { 00230 rm_def->tooltips[rm_def->num_tooltips - 1].outline = 1; 00231 rm_def->tooltips[rm_def->num_tooltips - 1].outline_color.r = r; 00232 rm_def->tooltips[rm_def->num_tooltips - 1].outline_color.g = g; 00233 rm_def->tooltips[rm_def->num_tooltips - 1].outline_color.b = b; 00234 rm_def->tooltips[rm_def->num_tooltips - 1].outline_size = outline_size; 00235 } 00236 } 00237 else if (!strncmp(cp, "t_outline", 9)) 00238 { 00239 rm_def->tooltips[rm_def->num_tooltips - 1].outline = 1; 00240 rm_def->tooltips[rm_def->num_tooltips - 1].outline_size = 1; 00241 rm_def->tooltips[rm_def->num_tooltips - 1].outline_color.r = 255; 00242 rm_def->tooltips[rm_def->num_tooltips - 1].outline_color.g = 0; 00243 rm_def->tooltips[rm_def->num_tooltips - 1].outline_color.b = 0; 00244 } 00245 00246 cp = strtok(NULL, "\n"); 00247 } 00248 00249 /* Parse the labels from the server command. */ 00250 for (i = 0; i < num_cmd_labels; i++) 00251 { 00252 label = rm_find_label(cmd_labels[i]); 00253 00254 /* Unhide the label if we found it. */ 00255 if (label) 00256 { 00257 label->hidden = 0; 00258 } 00259 00260 free(cmd_labels[i]); 00261 } 00262 00263 /* Don't need the labels from the command anymore, free them. */ 00264 if (cmd_labels) 00265 { 00266 free(cmd_labels); 00267 cmd_labels = NULL; 00268 } 00269 00270 num_cmd_labels = 0; 00271 00272 /* Parse the tooltips from the server command. */ 00273 for (i = 0; i < num_cmd_tooltips; i++) 00274 { 00275 region_map_tooltip *tooltip = rm_find_tooltip(cmd_tooltips[i]); 00276 00277 /* Unhide the tooltip if we found it. */ 00278 if (tooltip) 00279 { 00280 tooltip->hidden = 0; 00281 } 00282 00283 free(cmd_tooltips[i]); 00284 } 00285 00286 /* Don't need the tooltip from the command anymore, free them. */ 00287 if (cmd_tooltips) 00288 { 00289 free(cmd_tooltips); 00290 cmd_tooltips = NULL; 00291 } 00292 00293 num_cmd_tooltips = 0; 00294 } 00295 00298 static void rm_def_free() 00299 { 00300 size_t i; 00301 00302 if (!rm_def) 00303 { 00304 return; 00305 } 00306 00307 /* Free all maps. */ 00308 for (i = 0; i < rm_def->num_maps; i++) 00309 { 00310 free(rm_def->maps[i].path); 00311 } 00312 00313 free(rm_def->maps); 00314 00315 /* Free labels. */ 00316 for (i = 0; i < rm_def->num_labels; i++) 00317 { 00318 free(rm_def->labels[i].name); 00319 free(rm_def->labels[i].text); 00320 } 00321 00322 if (rm_def->labels) 00323 { 00324 free(rm_def->labels); 00325 } 00326 00327 /* Free tooltips. */ 00328 for (i = 0; i < rm_def->num_tooltips; i++) 00329 { 00330 free(rm_def->tooltips[i].name); 00331 free(rm_def->tooltips[i].text); 00332 } 00333 00334 if (rm_def->tooltips) 00335 { 00336 free(rm_def->tooltips); 00337 } 00338 00339 free(rm_def); 00340 rm_def = NULL; 00341 } 00342 00347 static int rm_label_in_cmd(const char *name) 00348 { 00349 size_t i; 00350 00351 for (i = 0; i < num_cmd_labels; i++) 00352 { 00353 if (!strcmp(cmd_labels[i], name)) 00354 { 00355 return 1; 00356 } 00357 } 00358 00359 return 0; 00360 } 00361 00366 static int rm_tooltip_in_cmd(const char *name) 00367 { 00368 size_t i; 00369 00370 for (i = 0; i < num_cmd_tooltips; i++) 00371 { 00372 if (!strcmp(cmd_tooltips[i], name)) 00373 { 00374 return 1; 00375 } 00376 } 00377 00378 return 0; 00379 } 00380 00386 static int region_map_is_same(const char *url) 00387 { 00388 if (setting_get_int(OPT_CAT_DEVEL, OPT_DISABLE_RM_CACHE)) 00389 { 00390 return 0; 00391 } 00392 00393 /* Try to check labels from definitions. */ 00394 if (rm_def) 00395 { 00396 size_t i; 00397 uint8 in_cmd; 00398 00399 for (i = 0; i < rm_def->num_labels; i++) 00400 { 00401 in_cmd = rm_label_in_cmd(rm_def->labels[i].name); 00402 00403 /* Not the same if the label should be shown or 00404 * re-hidden. */ 00405 if ((rm_def->labels[i].hidden == 1 && in_cmd) || (rm_def->labels[i].hidden == 0 && !in_cmd)) 00406 { 00407 return 0; 00408 } 00409 } 00410 00411 for (i = 0; i < rm_def->num_tooltips; i++) 00412 { 00413 in_cmd = rm_tooltip_in_cmd(rm_def->tooltips[i].name); 00414 00415 /* Not the same if the tooltip should be shown or 00416 * re-hidden. */ 00417 if ((rm_def->tooltips[i].hidden == 1 && in_cmd) || (rm_def->tooltips[i].hidden == 0 && !in_cmd)) 00418 { 00419 return 0; 00420 } 00421 } 00422 } 00423 00424 /* Is the image URL the same? */ 00425 if (data_png && !strcmp(url, data_png->url) && curl_download_finished(data_png) == 1 && curl_download_finished(data_def) == 1) 00426 { 00427 return 1; 00428 } 00429 00430 return 0; 00431 } 00432 00437 void RegionMapCmd(uint8 *data, int len) 00438 { 00439 char region[MAX_BUF], url_base[HUGE_BUF], url[HUGE_BUF], text[HUGE_BUF]; 00440 int pos = 0; 00441 00442 /* Get the player's map, X and Y. */ 00443 GetString_String(data, &pos, current_map, sizeof(current_map)); 00444 current_x = GetShort_String(data + pos); 00445 pos += 2; 00446 current_y = GetShort_String(data + pos); 00447 pos += 2; 00448 /* Get the region and the URL base for the maps. */ 00449 GetString_String(data, &pos, region, sizeof(region)); 00450 GetString_String(data, &pos, url_base, sizeof(url_base)); 00451 00452 /* Rest of the data packet may be labels/tooltips/etc. */ 00453 while (pos < len) 00454 { 00455 uint8 type = data[pos++]; 00456 00457 GetString_String(data, &pos, text, sizeof(text)); 00458 00459 if (type == RM_TYPE_LABEL) 00460 { 00461 cmd_labels = realloc(cmd_labels, sizeof(*cmd_labels) * (num_cmd_labels + 1)); 00462 cmd_labels[num_cmd_labels] = strdup(text); 00463 num_cmd_labels++; 00464 } 00465 else if (type == RM_TYPE_TOOLTIP) 00466 { 00467 cmd_tooltips = realloc(cmd_tooltips, sizeof(*cmd_tooltips) * (num_cmd_tooltips + 1)); 00468 cmd_tooltips[num_cmd_tooltips] = strdup(text); 00469 num_cmd_tooltips++; 00470 } 00471 } 00472 00473 cpl.menustatus = MENU_REGION_MAP; 00474 00475 /* Construct URL for the image. */ 00476 snprintf(url, sizeof(url), "%s/%s.png", url_base, region); 00477 00478 /* Free old map surface. */ 00479 if (region_map_png) 00480 { 00481 /* If zoom was used, we have to free both. */ 00482 if (region_map_png != region_map_png_orig) 00483 { 00484 SDL_FreeSurface(region_map_png); 00485 } 00486 00487 SDL_FreeSurface(region_map_png_orig); 00488 region_map_png = NULL; 00489 region_map_png_orig = NULL; 00490 } 00491 00492 /* Default zoom. */ 00493 region_map_zoom = RM_ZOOM_DEFAULT; 00494 00495 region_map_pos.x = 0; 00496 region_map_pos.y = 0; 00497 region_map_pos.w = Bitmaps[BITMAP_REGION_MAP]->bitmap->w - RM_BORDER_SIZE * 2; 00498 region_map_pos.h = Bitmaps[BITMAP_REGION_MAP]->bitmap->h - RM_BORDER_SIZE * 2 -RM_TOOLTIP_HEIGHT; 00499 00500 /* The map is the same, no downloading needed. */ 00501 if (region_map_is_same(url)) 00502 { 00503 if (cmd_labels) 00504 { 00505 free(cmd_labels); 00506 cmd_labels = NULL; 00507 } 00508 00509 if (cmd_tooltips) 00510 { 00511 free(cmd_tooltips); 00512 cmd_tooltips = NULL; 00513 } 00514 00515 num_cmd_labels = 0; 00516 num_cmd_tooltips = 0; 00517 return; 00518 } 00519 00520 region_map_clear(); 00521 00522 /* Start the downloads. */ 00523 data_png = curl_download_start(url); 00524 snprintf(url, sizeof(url), "%s/%s.def", url_base, region); 00525 data_def = curl_download_start(url); 00526 } 00527 00530 void region_map_clear() 00531 { 00532 /* Free old cURL data and the parsed definitions. */ 00533 if (data_png) 00534 { 00535 curl_data_free(data_png); 00536 data_png = NULL; 00537 } 00538 00539 if (data_def) 00540 { 00541 curl_data_free(data_def); 00542 data_def = NULL; 00543 } 00544 00545 rm_def_free(); 00546 } 00547 00551 static void region_map_resize(int adjust) 00552 { 00553 float delta; 00554 00555 region_map_zoom += adjust; 00556 00557 /* Free old zoomed surface if applicable. */ 00558 if (region_map_png != region_map_png_orig) 00559 { 00560 SDL_FreeSurface(region_map_png); 00561 } 00562 00563 /* Zoom the surface. */ 00564 region_map_png = zoomSurface(region_map_png_orig, region_map_zoom / 100.0, region_map_zoom / 100.0, setting_get_int(OPT_CAT_MAP, OPT_ZOOM_SMOOTH)); 00565 00566 if (adjust > 0) 00567 { 00568 delta = (region_map_zoom / 100.0 - 0.1f); 00569 } 00570 else 00571 { 00572 delta = (region_map_zoom / 100.0 + 0.1f); 00573 } 00574 00575 region_map_pos.x += region_map_pos.x / delta * (adjust / 100.0) + region_map_pos.w / delta * (adjust / 100.0) / 2; 00576 region_map_pos.y += region_map_pos.y / delta * (adjust / 100.0) + region_map_pos.h / delta * (adjust / 100.0) / 2; 00577 00578 surface_pan(region_map_png, ®ion_map_pos); 00579 } 00580 00584 void region_map_handle_key(SDLKey key) 00585 { 00586 int pos = RM_SCROLL; 00587 00588 if (!region_map_png) 00589 { 00590 return; 00591 } 00592 00593 /* Shift is held, increase the scrolling 'speed'. */ 00594 if (SDL_GetModState() & KMOD_SHIFT) 00595 { 00596 pos = RM_SCROLL_SHIFT; 00597 } 00598 00599 if (key == SDLK_UP) 00600 { 00601 region_map_pos.y -= pos; 00602 } 00603 else if (key == SDLK_DOWN) 00604 { 00605 region_map_pos.y += pos; 00606 } 00607 else if (key == SDLK_LEFT) 00608 { 00609 region_map_pos.x -= pos; 00610 } 00611 else if (key == SDLK_RIGHT) 00612 { 00613 region_map_pos.x += pos; 00614 } 00615 else if (key == SDLK_PAGEUP) 00616 { 00617 if (region_map_zoom < RM_ZOOM_MAX) 00618 { 00619 region_map_resize(RM_ZOOM_PROGRESS); 00620 } 00621 } 00622 else if (key == SDLK_PAGEDOWN) 00623 { 00624 if (region_map_zoom > RM_ZOOM_MIN) 00625 { 00626 region_map_resize(-RM_ZOOM_PROGRESS); 00627 } 00628 } 00629 else 00630 { 00631 return; 00632 } 00633 00634 surface_pan(region_map_png, ®ion_map_pos); 00635 } 00636 00640 void region_map_handle_event(SDL_Event *event) 00641 { 00642 if (!region_map_png) 00643 { 00644 return; 00645 } 00646 00647 if (event->type == SDL_MOUSEBUTTONDOWN) 00648 { 00649 /* Zoom in. */ 00650 if (event->button.button == SDL_BUTTON_WHEELUP) 00651 { 00652 if (region_map_zoom < RM_ZOOM_MAX) 00653 { 00654 region_map_resize(RM_ZOOM_PROGRESS); 00655 } 00656 } 00657 /* Zoom out. */ 00658 else if (event->button.button == SDL_BUTTON_WHEELDOWN) 00659 { 00660 if (region_map_zoom > RM_ZOOM_MIN) 00661 { 00662 region_map_resize(-RM_ZOOM_PROGRESS); 00663 } 00664 } 00665 } 00666 } 00667 00670 void region_map_show() 00671 { 00672 int x, y, ret_png, ret_def; 00673 SDL_Rect box, dest; 00674 int state, mx, my; 00675 size_t i; 00676 00677 /* Show the background. */ 00678 x = (ScreenSurface->w / 2 - Bitmaps[BITMAP_REGION_MAP]->bitmap->w / 2); 00679 y = (ScreenSurface->h / 2 - Bitmaps[BITMAP_REGION_MAP]->bitmap->h / 2); 00680 sprite_blt(Bitmaps[BITMAP_REGION_MAP], x, y, NULL, NULL); 00681 00682 box.x = x + RM_BORDER_SIZE; 00683 box.y = y + RM_BORDER_SIZE; 00684 box.w = region_map_pos.w; 00685 box.h = region_map_pos.h; 00686 00687 /* Show a close button. */ 00688 if (button_show(BITMAP_BUTTON_ROUND, -1, BITMAP_BUTTON_ROUND_DOWN, box.x + box.w, y + 10, "X", FONT_ARIAL10, COLOR_WHITE, COLOR_BLACK, COLOR_HGOLD, COLOR_BLACK, 0)) 00689 { 00690 cpl.menustatus = MENU_NO; 00691 map_udate_flag = 2; 00692 reset_keys(); 00693 } 00694 00695 /* Show direction markers. */ 00696 string_blt(ScreenSurface, FONT_SERIF14, "N", box.x, y + RM_BORDER_SIZE / 2 - FONT_HEIGHT(FONT_SERIF14) / 2, COLOR_HGOLD, TEXT_ALIGN_CENTER | TEXT_OUTLINE, &box); 00697 string_blt(ScreenSurface, FONT_SERIF14, "E", x + Bitmaps[BITMAP_REGION_MAP]->bitmap->w - RM_BORDER_SIZE / 2 - string_get_width(FONT_SERIF14, "E", 0) / 2, y + (Bitmaps[BITMAP_REGION_MAP]->bitmap->h - RM_TOOLTIP_HEIGHT) / 2 - FONT_HEIGHT(FONT_SERIF14), COLOR_HGOLD, TEXT_OUTLINE, &box); 00698 string_blt(ScreenSurface, FONT_SERIF14, "S", box.x, y + Bitmaps[BITMAP_REGION_MAP]->bitmap->h - RM_BORDER_SIZE / 2 - FONT_HEIGHT(FONT_SERIF14) / 2 - RM_TOOLTIP_HEIGHT, COLOR_HGOLD, TEXT_ALIGN_CENTER | TEXT_OUTLINE, &box); 00699 string_blt(ScreenSurface, FONT_SERIF14, "W", x + RM_BORDER_SIZE / 2 - string_get_width(FONT_SERIF14, "W", 0) / 2, y + (Bitmaps[BITMAP_REGION_MAP]->bitmap->h - RM_TOOLTIP_HEIGHT) / 2 - FONT_HEIGHT(FONT_SERIF14), COLOR_HGOLD, TEXT_OUTLINE, &box); 00700 00701 /* Check the status of the downloads. */ 00702 ret_png = curl_download_finished(data_png); 00703 ret_def = curl_download_finished(data_def); 00704 00705 /* We failed. */ 00706 if (ret_png == -1 || ret_def == -1) 00707 { 00708 string_blt(ScreenSurface, FONT_SERIF14, "Connection timed out.", box.x, box.y, COLOR_WHITE, TEXT_ALIGN_CENTER | TEXT_VALIGN_CENTER | TEXT_OUTLINE, &box); 00709 return; 00710 } 00711 00712 /* Still in progress. */ 00713 if (ret_png == 0 || ret_def == 0) 00714 { 00715 string_blt(ScreenSurface, FONT_SERIF14, "Downloading the map, please wait...", box.x, box.y, COLOR_WHITE, TEXT_ALIGN_CENTER | TEXT_VALIGN_CENTER | TEXT_OUTLINE, &box); 00716 return; 00717 } 00718 00719 /* Parse the definitions. */ 00720 if (!rm_def) 00721 { 00722 rm_def_create(data_def->memory); 00723 } 00724 00725 /* Create the map surface. */ 00726 if (!region_map_png) 00727 { 00728 SDL_Rect marker; 00729 region_map_struct *map; 00730 SDL_Surface *img; 00731 00732 /* Create the surface from downloaded data. */ 00733 img = IMG_Load_RW(SDL_RWFromMem(data_png->memory, data_png->size), 1); 00734 region_map_png = region_map_png_orig = SDL_DisplayFormat(img); 00735 SDL_FreeSurface(img); 00736 00737 map = rm_def_get_map(current_map); 00738 00739 /* Valid map? */ 00740 if (map) 00741 { 00742 /* Calculate the player's marker position. */ 00743 marker.x = map->xpos + current_x * rm_def->pixel_size - Bitmaps[BITMAP_MAP_MARKER]->bitmap->w / 2 + rm_def->pixel_size / 2; 00744 marker.y = map->ypos + current_y * rm_def->pixel_size - Bitmaps[BITMAP_MAP_MARKER]->bitmap->h + rm_def->pixel_size; 00745 SDL_BlitSurface(Bitmaps[BITMAP_MAP_MARKER]->bitmap, NULL, region_map_png, &marker); 00746 00747 /* Center the map on the player. */ 00748 region_map_pos.x = (map->xpos + current_x * rm_def->pixel_size) - region_map_pos.w / 2; 00749 region_map_pos.y = (map->ypos + current_y * rm_def->pixel_size) - region_map_pos.h / 2; 00750 } 00751 else 00752 { 00753 region_map_pos.x = region_map_png->w / 2 - region_map_pos.w / 2; 00754 region_map_pos.y = region_map_png->h / 2 - region_map_pos.h / 2; 00755 surface_pan(region_map_png, ®ion_map_pos); 00756 } 00757 00758 surface_pan(region_map_png, ®ion_map_pos); 00759 00760 /* Blit the labels. */ 00761 for (i = 0; i < rm_def->num_labels; i++) 00762 { 00763 if (rm_def->labels[i].hidden < 1) 00764 { 00765 string_blt(region_map_png, FONT_SERIF20, rm_def->labels[i].text, rm_def->labels[i].x, rm_def->labels[i].y, COLOR_HGOLD, TEXT_MARKUP | TEXT_OUTLINE, NULL); 00766 } 00767 } 00768 00769 for (i = 0; i < rm_def->num_tooltips; i++) 00770 { 00771 if (rm_def->tooltips[i].hidden < 1 && rm_def->tooltips[i].outline) 00772 { 00773 border_create(region_map_png, rm_def->tooltips[i].x, rm_def->tooltips[i].y, rm_def->tooltips[i].w, rm_def->tooltips[i].h, SDL_MapRGB(region_map_png->format, rm_def->tooltips[i].outline_color.r, rm_def->tooltips[i].outline_color.g, rm_def->tooltips[i].outline_color.b), rm_def->tooltips[i].outline_size); 00774 } 00775 } 00776 } 00777 00778 state = SDL_GetMouseState(&mx, &my); 00779 00780 /* Move the map around with the mouse. */ 00781 if ((state == SDL_BUTTON(SDL_BUTTON_LEFT) || state == SDL_BUTTON(SDL_BUTTON_MIDDLE)) && mx > box.x && my < box.x + box.w && my > box.y && my < box.y + box.h && (!region_mouse_ticks || state == SDL_BUTTON(SDL_BUTTON_MIDDLE) || SDL_GetTicks() - region_mouse_ticks > 125)) 00782 { 00783 region_mouse_ticks = SDL_GetTicks(); 00784 00785 if (state == SDL_BUTTON(SDL_BUTTON_LEFT)) 00786 { 00787 /* The clicked position will become centered, unless it's too 00788 * close to an edge of the map, of course. */ 00789 region_map_pos.x += mx - box.x - region_map_pos.w / 2; 00790 region_map_pos.y += my - box.y - region_map_pos.h / 2; 00791 surface_pan(region_map_png, ®ion_map_pos); 00792 } 00793 else if (state == SDL_BUTTON(SDL_BUTTON_MIDDLE) && setting_get_int(OPT_CAT_DEVEL, OPT_QUICKPORT)) 00794 { 00795 int xpos, ypos; 00796 00797 xpos = region_map_pos.x + mx - box.x; 00798 ypos = region_map_pos.y + my - box.y; 00799 00800 for (i = 0; i < rm_def->num_maps; i++) 00801 { 00802 if (xpos >= rm_def->maps[i].xpos * (region_map_zoom / 100.0) && xpos <= (rm_def->maps[i].xpos + (rm_def->map_size_x * rm_def->pixel_size)) * (region_map_zoom / 100.0) && ypos >= rm_def->maps[i].ypos * (region_map_zoom / 100.0) && ypos <= (rm_def->maps[i].ypos + (rm_def->map_size_y * rm_def->pixel_size)) * (region_map_zoom / 100.0)) 00803 { 00804 char buf[HUGE_BUF]; 00805 00806 xpos = (xpos - rm_def->maps[i].xpos * (region_map_zoom / 100.0)) / (rm_def->pixel_size * (region_map_zoom / 100.0)); 00807 ypos = (ypos - rm_def->maps[i].ypos * (region_map_zoom / 100.0)) / (rm_def->pixel_size * (region_map_zoom / 100.0)); 00808 snprintf(buf, sizeof(buf), "/goto %s %d %d", rm_def->maps[i].path, xpos, ypos); 00809 send_command(buf); 00810 00811 cpl.menustatus = MENU_NO; 00812 map_udate_flag = 2; 00813 reset_keys(); 00814 /* Workaround so the middle click doesn't also trigger a 00815 * fire action. */ 00816 cpl.action_timer = 0.0001f; 00817 break; 00818 } 00819 } 00820 } 00821 } 00822 00823 dest.x = box.x; 00824 dest.y = box.y; 00825 00826 /* Actually blit the map. */ 00827 SDL_BlitSurface(region_map_png, ®ion_map_pos, ScreenSurface, &dest); 00828 00829 string_blt(ScreenSurface, FONT_ARIAL11, "Move the mouse cursor over buildings to see additional information about them, if any. Scroll the map by pressing left mouse click.", box.x + 3, y + Bitmaps[BITMAP_REGION_MAP]->bitmap->h - RM_BORDER_SIZE - FONT_HEIGHT(FONT_ARIAL11) - 3, COLOR_WHITE, TEXT_OUTLINE, NULL); 00830 00831 if (mx >= box.x && mx <= box.x + box.w && my >= box.y && my <= box.y + box.h) 00832 { 00833 SDL_Rect tooltip_box; 00834 00835 tooltip_box.x = box.x + 3; 00836 tooltip_box.y = box.y + box.h + RM_BORDER_SIZE + 3; 00837 tooltip_box.w = box.w; 00838 tooltip_box.h = RM_TOOLTIP_HEIGHT - RM_BORDER_SIZE * 2; 00839 00840 for (i = 0; i < rm_def->num_tooltips; i++) 00841 { 00842 if (rm_def->tooltips[i].hidden < 1 && region_map_pos.x + mx - box.x >= rm_def->tooltips[i].x * (region_map_zoom / 100.0) && region_map_pos.x + mx - box.x <= (rm_def->tooltips[i].x + rm_def->tooltips[i].w) * (region_map_zoom / 100.0) && region_map_pos.y + my - box.y >= rm_def->tooltips[i].y * (region_map_zoom / 100.0) && region_map_pos.y + my - box.y <= (rm_def->tooltips[i].y + rm_def->tooltips[i].h) * (region_map_zoom / 100.0)) 00843 { 00844 string_blt(ScreenSurface, FONT_ARIAL11, rm_def->tooltips[i].text, tooltip_box.x, tooltip_box.y, COLOR_WHITE, TEXT_MARKUP | TEXT_WORD_WRAP | TEXT_OUTLINE, &tooltip_box); 00845 break; 00846 } 00847 } 00848 } 00849 }
1.7.4