|
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 SDL_Surface *ScreenSurface; 00035 struct sockaddr_in insock; 00037 ClientSocket csocket; 00038 00039 struct _fire_mode fire_mode_tab[FIRE_MODE_INIT]; 00040 int RangeFireMode; 00041 00043 server_struct *selected_server = NULL; 00044 00046 static char argServerName[2048]; 00048 static int argServerPort; 00049 00051 uint32 LastTick; 00052 00053 int f_custom_cursor = 0; 00054 int x_custom_cursor = 0; 00055 int y_custom_cursor = 0; 00056 00057 /* update map area */ 00058 int map_udate_flag, map_redraw_flag; 00059 00061 help_files_struct *help_files; 00063 _game_status GameStatus; 00065 _anim_table *anim_table = NULL; 00066 Animations *animations = NULL; 00068 size_t animations_num = 0; 00069 00071 struct screensize *Screensize; 00072 00074 _face_struct FaceList[MAX_FACE_TILES]; 00075 00077 struct msg_anim_struct msg_anim; 00079 static time_t last_keepalive; 00080 00082 static _bitmap_name bitmap_name[BITMAP_INIT] = 00083 { 00084 {"intro.png", PIC_TYPE_DEFAULT}, 00085 00086 {"player_doll_bg.png", PIC_TYPE_TRANS}, 00087 {"login_inp.png", PIC_TYPE_DEFAULT}, 00088 {"invslot.png", PIC_TYPE_TRANS}, 00089 00090 {"hp.png", PIC_TYPE_TRANS}, 00091 {"sp.png", PIC_TYPE_TRANS}, 00092 {"grace.png", PIC_TYPE_TRANS}, 00093 {"food.png", PIC_TYPE_TRANS}, 00094 {"hp_back.png", PIC_TYPE_DEFAULT}, 00095 {"sp_back.png", PIC_TYPE_DEFAULT}, 00096 {"grace_back.png", PIC_TYPE_DEFAULT}, 00097 {"food_back.png", PIC_TYPE_DEFAULT}, 00098 00099 {"apply.png", PIC_TYPE_DEFAULT}, 00100 {"unpaid.png", PIC_TYPE_DEFAULT}, 00101 {"cursed.png", PIC_TYPE_DEFAULT}, 00102 {"damned.png", PIC_TYPE_DEFAULT}, 00103 {"lock.png", PIC_TYPE_DEFAULT}, 00104 {"magic.png", PIC_TYPE_DEFAULT}, 00105 {"fire_ready.png", PIC_TYPE_DEFAULT}, 00106 00107 {"range.png", PIC_TYPE_TRANS}, 00108 {"range_marker.png", PIC_TYPE_TRANS}, 00109 {"range_skill.png", PIC_TYPE_TRANS}, 00110 {"range_skill_no.png", PIC_TYPE_TRANS}, 00111 {"range_throw.png", PIC_TYPE_TRANS}, 00112 {"range_throw_no.png", PIC_TYPE_TRANS}, 00113 {"range_tool.png", PIC_TYPE_TRANS}, 00114 {"range_tool_no.png", PIC_TYPE_TRANS}, 00115 {"range_wizard.png", PIC_TYPE_TRANS}, 00116 {"range_wizard_no.png", PIC_TYPE_TRANS}, 00117 00118 {"cmark_start.png", PIC_TYPE_TRANS}, 00119 {"cmark_end.png", PIC_TYPE_TRANS}, 00120 {"cmark_middle.png", PIC_TYPE_TRANS}, 00121 00122 {"textwin_scroll.png", PIC_TYPE_DEFAULT}, 00123 {"inv_scroll.png", PIC_TYPE_DEFAULT}, 00124 {"below_scroll.png", PIC_TYPE_DEFAULT}, 00125 00126 {"number.png", PIC_TYPE_DEFAULT}, 00127 {"invslot_u.png", PIC_TYPE_TRANS}, 00128 00129 {"death.png", PIC_TYPE_TRANS}, 00130 {"sleep.png", PIC_TYPE_TRANS}, 00131 {"confused.png", PIC_TYPE_TRANS}, 00132 {"paralyzed.png", PIC_TYPE_TRANS}, 00133 {"scared.png", PIC_TYPE_TRANS}, 00134 {"blind.png", PIC_TYPE_TRANS}, 00135 00136 {"quickslots.png", PIC_TYPE_DEFAULT}, 00137 {"quickslotsv.png", PIC_TYPE_DEFAULT}, 00138 {"inventory.png", PIC_TYPE_DEFAULT}, 00139 {"inventory_bg.png", PIC_TYPE_DEFAULT}, 00140 00141 {"exp_border.png", PIC_TYPE_DEFAULT}, 00142 {"exp_line.png", PIC_TYPE_DEFAULT}, 00143 {"exp_bubble.png", PIC_TYPE_TRANS}, 00144 {"exp_bubble2.png", PIC_TYPE_TRANS}, 00145 00146 {"main_stats.png", PIC_TYPE_DEFAULT}, 00147 {"below.png", PIC_TYPE_DEFAULT}, 00148 00149 {"target_attack.png", PIC_TYPE_TRANS}, 00150 {"target_talk.png", PIC_TYPE_TRANS}, 00151 {"target_normal.png", PIC_TYPE_TRANS}, 00152 00153 {"warn_hp.png", PIC_TYPE_DEFAULT}, 00154 {"warn_food.png", PIC_TYPE_DEFAULT}, 00155 00156 {"range_buttons_off.png", PIC_TYPE_DEFAULT}, 00157 {"range_buttons_left.png", PIC_TYPE_DEFAULT}, 00158 {"range_buttons_right.png", PIC_TYPE_DEFAULT}, 00159 00160 {"target_hp.png", PIC_TYPE_DEFAULT}, 00161 {"target_hp_b.png", PIC_TYPE_DEFAULT}, 00162 00163 {"textwin_mask.png", PIC_TYPE_DEFAULT}, 00164 {"slider_up.png", PIC_TYPE_TRANS}, 00165 {"slider_down.png", PIC_TYPE_TRANS}, 00166 {"slider.png", PIC_TYPE_TRANS}, 00167 00168 {"exp_skill_border.png", PIC_TYPE_DEFAULT}, 00169 {"exp_skill_line.png", PIC_TYPE_DEFAULT}, 00170 {"exp_skill_bubble.png", PIC_TYPE_TRANS}, 00171 00172 {"trapped.png", PIC_TYPE_TRANS}, 00173 {"pray.png", PIC_TYPE_TRANS}, 00174 {"book.png", PIC_TYPE_ALPHA}, 00175 {"region_map.png", PIC_TYPE_TRANS}, 00176 {"slider_long.png", PIC_TYPE_DEFAULT}, 00177 {"invslot_marked.png", PIC_TYPE_TRANS}, 00178 {"mouse_cursor_move.png", PIC_TYPE_TRANS}, 00179 {"resist_bg.png", PIC_TYPE_DEFAULT}, 00180 {"main_level_bg.png",PIC_TYPE_DEFAULT}, 00181 {"skill_exp_bg.png",PIC_TYPE_DEFAULT}, 00182 {"regen_bg.png",PIC_TYPE_DEFAULT}, 00183 {"skill_lvl_bg.png",PIC_TYPE_DEFAULT}, 00184 {"menu_buttons.png",PIC_TYPE_DEFAULT}, 00185 {"player_info_bg.png",PIC_TYPE_DEFAULT}, 00186 {"target_bg.png", PIC_TYPE_DEFAULT}, 00187 {"textinput.png", PIC_TYPE_DEFAULT}, 00188 00189 {"square_highlight.png", PIC_TYPE_DEFAULT}, 00190 {"servers_bg.png", PIC_TYPE_DEFAULT}, 00191 {"servers_bg_over.png", PIC_TYPE_TRANS}, 00192 {"news_bg.png", PIC_TYPE_DEFAULT}, 00193 {"eyes.png", PIC_TYPE_DEFAULT}, 00194 {"popup.png", PIC_TYPE_ALPHA}, 00195 {"arrow_up.png", PIC_TYPE_DEFAULT}, 00196 {"arrow_up2.png", PIC_TYPE_DEFAULT}, 00197 {"arrow_down.png", PIC_TYPE_DEFAULT}, 00198 {"arrow_down2.png", PIC_TYPE_DEFAULT}, 00199 {"button_round.png", PIC_TYPE_DEFAULT}, 00200 {"button_round_down.png", PIC_TYPE_DEFAULT}, 00201 {"button_rect.png", PIC_TYPE_DEFAULT}, 00202 {"button_rect_hover.png", PIC_TYPE_DEFAULT}, 00203 {"button_rect_down.png", PIC_TYPE_DEFAULT}, 00204 {"map_marker.png", PIC_TYPE_DEFAULT}, 00205 {"loading_off.png", PIC_TYPE_DEFAULT}, 00206 {"loading_on.png", PIC_TYPE_DEFAULT}, 00207 {"button.png", PIC_TYPE_DEFAULT}, 00208 {"button_down.png", PIC_TYPE_DEFAULT}, 00209 {"checkbox.png", PIC_TYPE_TRANS}, 00210 {"checkbox_on.png", PIC_TYPE_TRANS}, 00211 {"content.png", PIC_TYPE_DEFAULT}, 00212 {"icon_music.png", PIC_TYPE_ALPHA}, 00213 {"icon_magic.png", PIC_TYPE_ALPHA}, 00214 {"icon_skill.png", PIC_TYPE_ALPHA}, 00215 {"icon_party.png", PIC_TYPE_ALPHA}, 00216 {"icon_map.png", PIC_TYPE_ALPHA}, 00217 {"icon_cogs.png", PIC_TYPE_ALPHA}, 00218 {"icon_quest.png", PIC_TYPE_ALPHA}, 00219 {"fps.png", PIC_TYPE_DEFAULT} 00220 }; 00221 00223 #define BITMAP_MAX (sizeof(bitmap_name) / sizeof(_bitmap_name)) 00224 00225 _Sprite *Bitmaps[BITMAP_MAX]; 00226 00227 static void init_game_data(); 00228 static void delete_player_lists(); 00229 static int load_bitmap(int index); 00230 00233 static void delete_player_lists() 00234 { 00235 size_t i; 00236 00237 for (i = 0; i < FIRE_MODE_INIT; i++) 00238 { 00239 fire_mode_tab[i].amun = FIRE_ITEM_NO; 00240 fire_mode_tab[i].item = FIRE_ITEM_NO; 00241 fire_mode_tab[i].skill = NULL; 00242 fire_mode_tab[i].spell = NULL; 00243 fire_mode_tab[i].name[0] = '\0'; 00244 } 00245 } 00246 00249 static void init_game_data() 00250 { 00251 size_t i; 00252 00253 memset(&fire_mode_tab, 0, sizeof(fire_mode_tab)); 00254 00255 init_widgets_fromCurrent(); 00256 00257 init_map_data(0, 0, 0, 0); 00258 00259 for (i = 0; i < BITMAP_MAX; i++) 00260 { 00261 Bitmaps[i] = NULL; 00262 } 00263 00264 memset(FaceList, 0, sizeof(struct _face_struct) * MAX_FACE_TILES); 00265 00266 init_keys(); 00267 clear_player(); 00268 text_input_clear(); 00269 00270 msg_anim.message[0] = '\0'; 00271 00272 start_anim = NULL; 00273 00274 argServerName[0] = '\0'; 00275 argServerPort = 13327; 00276 00277 GameStatus = GAME_STATUS_INIT; 00278 map_udate_flag = 2; 00279 map_redraw_flag = 1; 00280 text_input_string_flag = 0; 00281 text_input_string_end_flag = 0; 00282 text_input_string_esc_flag = 0; 00283 csocket.fd = -1; 00284 RangeFireMode = 0; 00285 help_files = NULL; 00286 00287 text_input_history_clear(); 00288 delete_player_lists(); 00289 metaserver_init(); 00290 00291 if (!setting_get_int(OPT_CAT_CLIENT, OPT_OFFSCREEN_WIDGETS)) 00292 { 00293 widgets_ensure_onscreen(); 00294 } 00295 00296 SRANDOM(time(NULL)); 00297 } 00298 00300 #ifndef WIN32 00301 00302 static void fatal_signal(int make_core) 00303 { 00304 if (make_core) 00305 { 00306 abort(); 00307 } 00308 00309 exit(0); 00310 } 00311 00312 static void rec_sigsegv(int i) 00313 { 00314 (void) i; 00315 00316 LOG(llevInfo, "\nSIGSEGV received.\n"); 00317 fatal_signal(1); 00318 } 00319 00320 static void rec_sighup(int i) 00321 { 00322 (void) i; 00323 00324 LOG(llevInfo, "\nSIGHUP received\n"); 00325 exit(0); 00326 } 00327 00328 static void rec_sigquit(int i) 00329 { 00330 (void) i; 00331 00332 LOG(llevInfo, "\nSIGQUIT received\n"); 00333 fatal_signal(1); 00334 } 00335 00336 static void rec_sigterm(int i) 00337 { 00338 (void) i; 00339 00340 LOG(llevInfo, "\nSIGTERM received\n"); 00341 fatal_signal(0); 00342 } 00343 #endif 00344 00349 static void init_signals() 00350 { 00351 #ifndef WIN32 00352 signal(SIGHUP, rec_sighup); 00353 signal(SIGQUIT, rec_sigquit); 00354 signal(SIGSEGV, rec_sigsegv); 00355 signal(SIGTERM, rec_sigterm); 00356 #endif 00357 } 00358 00362 static int game_status_chain() 00363 { 00364 char buf[1024]; 00365 00366 if (GameStatus == GAME_STATUS_INIT) 00367 { 00368 cpl.mark_count = -1; 00369 LOG(llevInfo, "GAMES_STATUS_INIT_1\n"); 00370 00371 map_udate_flag = 2; 00372 delete_player_lists(); 00373 LOG(llevInfo, "GAMES_STATUS_INIT_2\n"); 00374 sound_start_bg_music("orchestral.ogg", setting_get_int(OPT_CAT_SOUND, OPT_VOLUME_MUSIC), -1); 00375 clear_map(); 00376 LOG(llevInfo, "GAMES_STATUS_INIT_3\n"); 00377 LOG(llevInfo, "GAMES_STATUS_INIT_4\n"); 00378 GameStatus = GAME_STATUS_META; 00379 } 00380 else if (GameStatus == GAME_STATUS_META) 00381 { 00382 metaserver_clear_data(); 00383 map_udate_flag = 2; 00384 00385 metaserver_add("127.0.0.1", 13327, "Localhost", -1, "local", "Localhost. Start server before you try to connect."); 00386 00387 if (argServerName[0] != '\0') 00388 { 00389 metaserver_add(argServerName, argServerPort, argServerName, -1, "user server", "Server from command line -server option."); 00390 } 00391 00392 metaserver_get_servers(); 00393 GameStatus = GAME_STATUS_START; 00394 } 00395 else if (GameStatus == GAME_STATUS_START) 00396 { 00397 map_udate_flag = 2; 00398 00399 if (csocket.fd != -1) 00400 { 00401 socket_close(&csocket); 00402 } 00403 00404 clear_map(); 00405 map_redraw_flag = 1; 00406 clear_player(); 00407 reset_keys(); 00408 GameStatus = GAME_STATUS_WAITLOOP; 00409 } 00410 else if (GameStatus == GAME_STATUS_STARTCONNECT) 00411 { 00412 map_udate_flag = 2; 00413 draw_info_format(COLOR_GREEN, "Trying server %s (%d)...", selected_server->name, selected_server->port); 00414 last_keepalive = time(NULL); 00415 GameStatus = GAME_STATUS_CONNECT; 00416 } 00417 else if (GameStatus == GAME_STATUS_CONNECT) 00418 { 00419 if (!socket_open(&csocket, selected_server->ip, selected_server->port)) 00420 { 00421 draw_info(COLOR_RED, "Connection failed!"); 00422 GameStatus = GAME_STATUS_START; 00423 return 1; 00424 } 00425 00426 socket_thread_start(); 00427 GameStatus = GAME_STATUS_VERSION; 00428 draw_info(COLOR_GREEN, "Connected. Exchange version."); 00429 cpl.name[0] = '\0'; 00430 cpl.password[0] = '\0'; 00431 region_map_clear(); 00432 } 00433 else if (GameStatus == GAME_STATUS_VERSION) 00434 { 00435 SendVersion(); 00436 GameStatus = GAME_STATUS_SETUP; 00437 } 00438 else if (GameStatus == GAME_STATUS_SETUP) 00439 { 00440 snprintf(buf, sizeof(buf), "setup sound 1 mapsize %"FMT64"x%"FMT64, setting_get_int(OPT_CAT_MAP, OPT_MAP_WIDTH), setting_get_int(OPT_CAT_MAP, OPT_MAP_HEIGHT)); 00441 server_files_setup_add(buf, sizeof(buf)); 00442 cs_write_string(buf, strlen(buf)); 00443 00444 GameStatus = GAME_STATUS_WAITSETUP; 00445 } 00446 else if (GameStatus == GAME_STATUS_REQUEST_FILES) 00447 { 00448 if (!server_files_updating()) 00449 { 00450 server_files_load(1); 00451 GameStatus = GAME_STATUS_ADDME; 00452 } 00453 } 00454 else if (GameStatus == GAME_STATUS_ADDME) 00455 { 00456 cpl.mark_count = -1; 00457 SendAddMe(); 00458 GameStatus = GAME_STATUS_LOGIN; 00459 /* Now wait for login request of the server */ 00460 } 00461 else if (GameStatus == GAME_STATUS_LOGIN) 00462 { 00463 if (text_input_string_esc_flag) 00464 { 00465 draw_info(COLOR_RED, "Break login."); 00466 GameStatus = GAME_STATUS_START; 00467 } 00468 00469 text_input_clear(); 00470 } 00471 else if (GameStatus == GAME_STATUS_NAME) 00472 { 00473 /* We have a finished console input */ 00474 if (text_input_string_esc_flag) 00475 { 00476 GameStatus = GAME_STATUS_LOGIN; 00477 } 00478 else if (text_input_string_flag == 0 && text_input_string_end_flag) 00479 { 00480 strcpy(cpl.name, text_input_string); 00481 LOG(llevInfo, "Login: send name %s\n", text_input_string); 00482 send_reply(text_input_string); 00483 GameStatus = GAME_STATUS_LOGIN; 00484 } 00485 } 00486 else if (GameStatus == GAME_STATUS_PSWD) 00487 { 00488 /* We have a finished console input */ 00489 if (text_input_string_esc_flag) 00490 { 00491 GameStatus = GAME_STATUS_LOGIN; 00492 } 00493 else if (text_input_string_flag == 0 && text_input_string_end_flag) 00494 { 00495 strncpy(cpl.password, text_input_string, 39); 00496 cpl.password[39] = '\0'; 00497 00498 LOG(llevInfo, "Login: send password <*****>\n"); 00499 send_reply(cpl.password); 00500 GameStatus = GAME_STATUS_LOGIN; 00501 } 00502 } 00503 else if (GameStatus == GAME_STATUS_VERIFYPSWD) 00504 { 00505 /* We have a finished console input */ 00506 if (text_input_string_esc_flag) 00507 { 00508 GameStatus = GAME_STATUS_LOGIN; 00509 } 00510 else if (text_input_string_flag == 0 && text_input_string_end_flag) 00511 { 00512 LOG(llevInfo, "Login: send verify password <*****>\n"); 00513 send_reply(text_input_string); 00514 GameStatus = GAME_STATUS_LOGIN; 00515 } 00516 } 00517 else if (GameStatus == GAME_STATUS_WAITFORPLAY) 00518 { 00519 clear_map(); 00520 map_udate_flag = 2; 00521 } 00522 00523 return 1; 00524 } 00525 00528 static void load_bitmaps() 00529 { 00530 int i; 00531 00532 /* add later better error handling here */ 00533 for (i = 0; i <= BITMAP_INTRO; i++) 00534 { 00535 load_bitmap(i); 00536 } 00537 } 00538 00543 static int load_bitmap(int idx) 00544 { 00545 char buf[2048]; 00546 uint32 flags = 0; 00547 00548 snprintf(buf, sizeof(buf), DIRECTORY_BITMAPS"/%s", bitmap_name[idx].name); 00549 00550 if (bitmap_name[idx].type == PIC_TYPE_PALETTE) 00551 { 00552 flags |= SURFACE_FLAG_PALETTE; 00553 } 00554 00555 if (bitmap_name[idx].type == PIC_TYPE_TRANS) 00556 { 00557 flags |= SURFACE_FLAG_COLKEY_16M; 00558 } 00559 00560 if (idx >= BITMAP_INTRO && idx != BITMAP_TEXTWIN_MASK) 00561 { 00562 flags |= bitmap_name[idx].type == PIC_TYPE_ALPHA ? SURFACE_FLAG_DISPLAYFORMATALPHA : SURFACE_FLAG_DISPLAYFORMAT; 00563 } 00564 00565 Bitmaps[idx] = sprite_load_file(buf, flags); 00566 00567 if (!Bitmaps[idx] || !Bitmaps[idx]->bitmap) 00568 { 00569 LOG(llevBug, "load_bitmap(): Can't load bitmap %s\n", buf); 00570 return 0; 00571 } 00572 00573 return 1; 00574 } 00575 00578 void free_bitmaps() 00579 { 00580 size_t i; 00581 00582 for (i = 0; i < BITMAP_MAX; i++) 00583 { 00584 sprite_free_sprite(Bitmaps[i]); 00585 } 00586 } 00587 00590 static void play_action_sounds() 00591 { 00592 if (cpl.warn_statdown) 00593 { 00594 sound_play_effect("warning_statdown.ogg", 100); 00595 cpl.warn_statdown = 0; 00596 } 00597 00598 if (cpl.warn_statup) 00599 { 00600 sound_play_effect("warning_statup.ogg", 100); 00601 cpl.warn_statup = 0; 00602 } 00603 00604 if (cpl.warn_hp) 00605 { 00606 if (cpl.warn_hp == 2) 00607 { 00608 sound_play_effect("warning_hp2.ogg", 100); 00609 } 00610 else 00611 { 00612 sound_play_effect("warning_hp.ogg", 100); 00613 } 00614 00615 cpl.warn_hp = 0; 00616 } 00617 } 00618 00621 void list_vid_modes() 00622 { 00623 const SDL_VideoInfo* vinfo = NULL; 00624 SDL_Rect **modes; 00625 int i; 00626 00627 LOG(llevInfo, "List Video Modes\n"); 00628 00629 /* Get available fullscreen/hardware modes */ 00630 modes = SDL_ListModes(NULL, SDL_HWACCEL); 00631 00632 /* Check if there are any modes available */ 00633 if (modes == (SDL_Rect **) 0) 00634 { 00635 LOG(llevError, "No modes available!\n"); 00636 } 00637 00638 /* Check if resolution is restricted */ 00639 if (modes == (SDL_Rect **) -1) 00640 { 00641 LOG(llevInfo, "All resolutions available.\n"); 00642 } 00643 else 00644 { 00645 /* Print valid modes */ 00646 LOG(llevInfo, "Available Modes\n"); 00647 00648 for (i = 0; modes[i]; ++i) 00649 { 00650 LOG(llevInfo, " %d x %d\n", modes[i]->w, modes[i]->h); 00651 } 00652 } 00653 00654 vinfo = SDL_GetVideoInfo(); 00655 LOG(llevInfo, "VideoInfo: hardware surfaces? %s\n", vinfo->hw_available ? "yes" : "no"); 00656 LOG(llevInfo, "VideoInfo: windows manager? %s\n", vinfo->wm_available ? "yes" : "no"); 00657 LOG(llevInfo, "VideoInfo: hw to hw blit? %s\n", vinfo->blit_hw ? "yes" : "no"); 00658 LOG(llevInfo, "VideoInfo: hw to hw ckey blit? %s\n", vinfo->blit_hw_CC ? "yes" : "no"); 00659 LOG(llevInfo, "VideoInfo: hw to hw alpha blit? %s\n", vinfo->blit_hw_A ? "yes" : "no"); 00660 LOG(llevInfo, "VideoInfo: sw to hw blit? %s\n", vinfo->blit_sw ? "yes" : "no"); 00661 LOG(llevInfo, "VideoInfo: sw to hw ckey blit? %s\n", vinfo->blit_sw_CC ? "yes" : "no"); 00662 LOG(llevInfo, "VideoInfo: sw to hw alpha blit? %s\n", vinfo->blit_sw_A ? "yes": "no"); 00663 LOG(llevInfo, "VideoInfo: color fill? %s\n", vinfo->blit_fill ? "yes" : "no"); 00664 LOG(llevInfo, "VideoInfo: video memory: %dKB\n", vinfo->video_mem); 00665 } 00666 00669 static void display_layer1() 00670 { 00671 SDL_FillRect(ScreenSurface, NULL, 0); 00672 00673 if (GameStatus == GAME_STATUS_PLAY) 00674 { 00675 widget_map_render(cur_widget[MAP_ID]); 00676 } 00677 } 00678 00681 static void display_layer2() 00682 { 00683 cpl.container = NULL; 00684 00685 if (GameStatus == GAME_STATUS_PLAY) 00686 { 00687 cpl.win_inv_tag = get_inventory_data(cpl.ob, &cpl.win_inv_ctag, &cpl.win_inv_slot, &cpl.win_inv_start, &cpl.win_inv_count, INVITEMXLEN, INVITEMYLEN); 00688 00689 cpl.real_weight = cpl.window_weight; 00690 00691 cpl.win_below_tag = get_inventory_data(cpl.below, &cpl.win_below_ctag, &cpl.win_below_slot, &cpl.win_below_start, &cpl.win_below_count, INVITEMBELOWXLEN, INVITEMBELOWYLEN); 00692 } 00693 } 00694 00697 static void display_layer3() 00698 { 00699 /* Process the widgets */ 00700 if (GameStatus == GAME_STATUS_PLAY) 00701 { 00702 process_widgets(); 00703 } 00704 } 00705 00708 static void display_layer4() 00709 { 00710 if (GameStatus == GAME_STATUS_PLAY) 00711 { 00712 /* We have to make sure that these two get hidden right */ 00713 /* sanity checks in case they don't exist */ 00714 if (cur_widget[IN_CONSOLE_ID]) 00715 { 00716 cur_widget[IN_CONSOLE_ID]->show = 0; 00717 } 00718 else 00719 { 00720 create_widget_object(IN_CONSOLE_ID); 00721 } 00722 00723 if (cur_widget[IN_NUMBER_ID]) 00724 { 00725 cur_widget[IN_NUMBER_ID]->show = 0; 00726 } 00727 else 00728 { 00729 create_widget_object(IN_NUMBER_ID); 00730 } 00731 00732 if (cpl.input_mode == INPUT_MODE_CONSOLE) 00733 { 00734 do_console(); 00735 } 00736 else if (cpl.input_mode == INPUT_MODE_NUMBER) 00737 { 00738 do_number(); 00739 } 00740 } 00741 } 00742 00745 static void DisplayCustomCursor() 00746 { 00747 if (f_custom_cursor == MSCURSOR_MOVE) 00748 { 00749 sprite_blt(Bitmaps[BITMAP_MSCURSOR_MOVE], x_custom_cursor - (Bitmaps[BITMAP_MSCURSOR_MOVE]->bitmap->w / 2), y_custom_cursor - (Bitmaps[BITMAP_MSCURSOR_MOVE]->bitmap->h / 2), NULL, NULL); 00750 } 00751 } 00752 00758 int main(int argc, char *argv[]) 00759 { 00760 int x, y, drag, done = 0; 00761 uint32 anim_tick, frame_start_time; 00762 size_t i; 00763 char version[MAX_BUF]; 00764 00765 init_signals(); 00766 #ifndef WIN32 00767 br_init(NULL); 00768 #endif 00769 upgrader_init(); 00770 settings_init(); 00771 init_game_data(); 00772 curl_init(); 00773 00774 while (argc > 1) 00775 { 00776 argc--; 00777 00778 if (strcmp(argv[argc - 1], "-port") == 0) 00779 { 00780 argServerPort = atoi(argv[argc]); 00781 argc--; 00782 } 00783 else if (strcmp(argv[argc - 1], "-server") == 0) 00784 { 00785 strcpy(argServerName, argv[argc]); 00786 00787 if (strchr(argv[argc], ':') != '\0') 00788 { 00789 argServerPort = atoi(strrchr(argv[argc], ':') + 1); 00790 *strchr(argServerName, ':') = '\0'; 00791 } 00792 00793 argc--; 00794 } 00795 else if (!strcmp(argv[argc], "-nometa")) 00796 { 00797 metaserver_disable(); 00798 } 00799 else if (!strcmp(argv[argc], "-text-debug")) 00800 { 00801 text_enable_debug(); 00802 } 00803 else 00804 { 00805 LOG(llevInfo, "Usage: %s [-server <name>] [-port <num>]\n", argv[0]); 00806 exit(1); 00807 } 00808 } 00809 00810 if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO) < 0) 00811 { 00812 LOG(llevBug, "Couldn't initialize SDL: %s\n", SDL_GetError()); 00813 exit(1); 00814 } 00815 00816 /* Start the system after starting SDL */ 00817 system_start(); 00818 list_vid_modes(); 00819 00820 if (!video_set_size()) 00821 { 00822 LOG(llevError, "Couldn't set video size: %s\n", SDL_GetError()); 00823 } 00824 00825 sprite_init_system(); 00826 00827 SDL_EnableUNICODE(1); 00828 00829 text_init(); 00830 00831 load_bitmaps(); 00832 00833 /* TODO: add later better error handling here */ 00834 for (i = BITMAP_DOLL; i < BITMAP_MAX; i++) 00835 { 00836 load_bitmap(i); 00837 } 00838 00839 sound_init(); 00840 keybind_load(); 00841 load_mapdef_dat(); 00842 read_bmaps_p0(); 00843 server_files_init(); 00844 00845 sound_start_bg_music("orchestral.ogg", setting_get_int(OPT_CAT_SOUND, OPT_VOLUME_MUSIC), -1); 00846 00847 script_autoload(); 00848 00849 draw_info_format(COLOR_HGOLD, "Welcome to Atrinik version %s.", package_get_version_full(version, sizeof(version))); 00850 draw_info(COLOR_GREEN, "Init network..."); 00851 00852 if (!socket_initialize()) 00853 { 00854 exit(1); 00855 } 00856 00857 if (!clipboard_init()) 00858 { 00859 draw_info(COLOR_RED, "Failed to initialize clipboard support, clipboard actions will not be possible."); 00860 } 00861 00862 textwin_init(); 00863 fps_init(); 00864 settings_apply(); 00865 00866 LastTick = anim_tick = SDL_GetTicks(); 00867 00868 while (!done) 00869 { 00870 frame_start_time = SDL_GetTicks(); 00871 done = Event_PollInputDevice(); 00872 00873 /* Have we been shutdown? */ 00874 if (handle_socket_shutdown()) 00875 { 00876 GameStatus = GAME_STATUS_INIT; 00877 /* Make sure no popup is visible. */ 00878 popup_destroy_visible(); 00879 list_remove_all(); 00880 continue; 00881 } 00882 00883 if (GameStatus > GAME_STATUS_CONNECT) 00884 { 00885 /* Send keepalive command every 2 minutes. */ 00886 if (time(NULL) - last_keepalive > 2 * 60) 00887 { 00888 cs_write_string("ka", 2); 00889 last_keepalive = time(NULL); 00890 } 00891 00892 DoClient(); 00893 } 00894 00895 if (GameStatus == GAME_STATUS_PLAY) 00896 { 00897 if (LastTick - anim_tick > 110) 00898 { 00899 anim_tick = LastTick; 00900 animate_objects(); 00901 map_udate_flag = 2; 00902 } 00903 00904 play_action_sounds(); 00905 } 00906 00907 map_udate_flag = 2; 00908 00909 if (map_udate_flag > 0) 00910 { 00911 display_layer1(); 00912 display_layer2(); 00913 display_layer3(); 00914 display_layer4(); 00915 00916 if (GameStatus != GAME_STATUS_PLAY) 00917 { 00918 SDL_FillRect(ScreenSurface, NULL, 0); 00919 } 00920 00921 map_udate_flag = 0; 00922 } 00923 00924 /* If not connected, walk through connection chain and/or wait for action */ 00925 if (GameStatus != GAME_STATUS_PLAY) 00926 { 00927 if (!game_status_chain()) 00928 { 00929 LOG(llevError, "Error connecting: GameStatus: %d SocketError: %d\n", GameStatus, socket_get_error()); 00930 } 00931 } 00932 00933 /* Show the current dragged item */ 00934 if ((drag = draggingInvItem(DRAG_GET_STATUS))) 00935 { 00936 object *Item = NULL; 00937 00938 if (drag == DRAG_IWIN_INV) 00939 { 00940 Item = object_find(cpl.win_inv_tag); 00941 } 00942 else if (drag == DRAG_IWIN_BELOW) 00943 { 00944 Item = object_find(cpl.win_below_tag); 00945 } 00946 else if (drag == DRAG_QUICKSLOT) 00947 { 00948 Item = object_find(cpl.dragging.tag); 00949 } 00950 else if (drag == DRAG_PDOLL) 00951 { 00952 Item = object_find(cpl.win_pdoll_tag); 00953 } 00954 00955 SDL_GetMouseState(&x, &y); 00956 00957 if (drag == DRAG_QUICKSLOT_SPELL) 00958 { 00959 blit_face(cpl.dragging.spell->icon, x, y); 00960 } 00961 else 00962 { 00963 blt_inv_item_centered(Item, x, y); 00964 } 00965 } 00966 00967 if (GameStatus <= GAME_STATUS_WAITFORPLAY) 00968 { 00969 show_meta_server(); 00970 } 00971 00972 /* Show all kind of the big dialog windows */ 00973 show_menu(); 00974 00975 tooltip_show(); 00976 00977 if (f_custom_cursor) 00978 { 00979 DisplayCustomCursor(); 00980 } 00981 00982 LastTick = SDL_GetTicks(); 00983 00984 script_process(); 00985 popup_draw(); 00986 00987 SDL_Flip(ScreenSurface); 00988 00989 if (!setting_get_int(OPT_CAT_CLIENT, OPT_SLEEP_TIME)) 00990 { 00991 uint32 elapsed_time = SDL_GetTicks() - frame_start_time; 00992 00993 if (elapsed_time < 1000 / FRAMES_PER_SECOND) 00994 { 00995 SDL_Delay(1000 / FRAMES_PER_SECOND - elapsed_time); 00996 } 00997 } 00998 else 00999 { 01000 SDL_Delay(setting_get_int(OPT_CAT_CLIENT, OPT_SLEEP_TIME)); 01001 } 01002 01003 fps_do(); 01004 } 01005 01006 system_end(); 01007 01008 return 0; 01009 }
1.7.4