• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

client/main.c

Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2010 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 <include.h>
00031 
00032 /* list of possible chars/race with setup when we want create a char */
00033 _server_char *first_server_char = NULL;
00034 /* if we login as new char, thats the values of it we set */
00035 _server_char new_character;
00036 
00038 SDL_Surface *ScreenSurface;
00040 SDL_Surface *ScreenSurfaceMap;
00042 SDL_Surface *zoomed;
00043 _Font MediumFont;
00044 /* our main font */
00045 _Font SystemFont;
00046 /* our main font - black outlined */
00047 _Font SystemFontOut;
00048 /* bigger special font */
00049 _Font BigFont;
00050 /* our main font with shadow */
00051 _Font Font6x3Out;
00053 struct sockaddr_in insock;
00055 ClientSocket csocket;
00056 
00057 Uint32 sdl_dgreen, sdl_gray1, sdl_gray2, sdl_gray3, sdl_gray4, sdl_blue1;
00058 
00059 int music_global_fade = 0;
00061 int mb_clicked = 0;
00062 
00064 int bmaptype_table_size;
00066 _srv_client_files srv_client_files[SRV_CLIENT_FILES];
00068 struct _options options;
00069 Uint32 videoflags_full, videoflags_win;
00070 
00071 struct _fire_mode fire_mode_tab[FIRE_MODE_INIT];
00072 int RangeFireMode;
00073 
00074 int current_intro = 0;
00075 
00076 /* cache status... set this in hardware depend */
00077 int CacheStatus;
00078 /* SoundStatus 0=no 1= yes */
00079 int SoundStatus;
00080 /* map x,y len */
00081 int MapStatusX;
00082 int MapStatusY;
00083 
00085 server_struct *selected_server = NULL;
00086 
00088 static char argServerName[2048];
00090 static int argServerPort;
00091 
00093 uint32 LastTick;
00095 static uint32 GameTicksSec;
00097 uint32 tmpGameTick;
00099 uint32 FrameCount = 0;
00100 
00102 int esc_menu_flag;
00104 int esc_menu_index;
00105 
00106 int f_custom_cursor = 0;
00107 int x_custom_cursor = 0;
00108 int y_custom_cursor = 0;
00109 
00111 _bmaptype *bmap_table[BMAPTABLE];
00112 
00113 /* update map area */
00114 int map_udate_flag, map_transfer_flag, map_redraw_flag;
00115 int request_file_chain;
00116 
00117 int ToggleScreenFlag;
00118 char InputString[MAX_INPUT_STRING];
00119 char InputHistory[MAX_HISTORY_LINES][MAX_INPUT_STRING];
00120 int HistoryPos;
00121 int CurrentCursorPos;
00122 
00123 int InputCount, InputMax;
00125 int InputStringFlag;
00127 int InputStringEndFlag;
00129 int InputStringEscFlag;
00131 struct gui_book_struct *gui_interface_book;
00133 struct gui_party_struct *gui_interface_party;
00135 help_files_struct *help_files;
00137 _game_status GameStatus;
00139 _anim_table *anim_table = NULL;
00140 Animations *animations = NULL;
00142 size_t animations_num = 0;
00143 
00145 struct screensize *Screensize;
00146 
00148 _face_struct FaceList[MAX_FACE_TILES];
00149 
00151 server_struct *start_server;
00152 int metaserver_sel, metaserver_count = 0;
00153 
00155 struct msg_anim_struct msg_anim;
00156 
00158 static _bitmap_name bitmap_name[BITMAP_INIT] =
00159 {
00160     {"palette.png", PIC_TYPE_PALETTE},
00161     {"font7x4.png", PIC_TYPE_PALETTE},
00162     {"font6x3out.png", PIC_TYPE_PALETTE},
00163     {"font_big.png", PIC_TYPE_PALETTE},
00164     {"font7x4out.png", PIC_TYPE_PALETTE},
00165     {"font11x15.png", PIC_TYPE_PALETTE},
00166     {"intro.png", PIC_TYPE_DEFAULT},
00167 
00168     {"progress.png", PIC_TYPE_DEFAULT},
00169     {"progress_back.png", PIC_TYPE_DEFAULT},
00170 
00171     {"player_doll_bg.png", PIC_TYPE_TRANS},
00172     {"black_tile.png", PIC_TYPE_DEFAULT},
00173     {"textwin.png", PIC_TYPE_DEFAULT},
00174     {"login_inp.png", PIC_TYPE_DEFAULT},
00175     {"invslot.png", PIC_TYPE_TRANS},
00176 
00177     {"hp.png", PIC_TYPE_TRANS},
00178     {"sp.png", PIC_TYPE_TRANS},
00179     {"grace.png", PIC_TYPE_TRANS},
00180     {"food.png", PIC_TYPE_TRANS},
00181     {"hp_back.png", PIC_TYPE_DEFAULT},
00182     {"sp_back.png", PIC_TYPE_DEFAULT},
00183     {"grace_back.png", PIC_TYPE_DEFAULT},
00184     {"food_back.png", PIC_TYPE_DEFAULT},
00185 
00186     {"apply.png", PIC_TYPE_DEFAULT},
00187     {"unpaid.png", PIC_TYPE_DEFAULT},
00188     {"cursed.png", PIC_TYPE_DEFAULT},
00189     {"damned.png", PIC_TYPE_DEFAULT},
00190     {"lock.png", PIC_TYPE_DEFAULT},
00191     {"magic.png", PIC_TYPE_DEFAULT},
00192 
00193     {"range.png", PIC_TYPE_TRANS},
00194     {"range_marker.png", PIC_TYPE_TRANS},
00195     {"range_ctrl.png", PIC_TYPE_TRANS},
00196     {"range_ctrl_no.png", PIC_TYPE_TRANS},
00197     {"range_skill.png", PIC_TYPE_TRANS},
00198     {"range_skill_no.png", PIC_TYPE_TRANS},
00199     {"range_throw.png", PIC_TYPE_TRANS},
00200     {"range_throw_no.png", PIC_TYPE_TRANS},
00201     {"range_tool.png", PIC_TYPE_TRANS},
00202     {"range_tool_no.png", PIC_TYPE_TRANS},
00203     {"range_wizard.png", PIC_TYPE_TRANS},
00204     {"range_wizard_no.png", PIC_TYPE_TRANS},
00205     {"range_priest.png", PIC_TYPE_TRANS},
00206     {"range_priest_no.png", PIC_TYPE_TRANS},
00207 
00208     {"cmark_start.png", PIC_TYPE_TRANS},
00209     {"cmark_end.png", PIC_TYPE_TRANS},
00210     {"cmark_middle.png", PIC_TYPE_TRANS},
00211 
00212     {"textwin_scroll.png", PIC_TYPE_DEFAULT},
00213     {"inv_scroll.png", PIC_TYPE_DEFAULT},
00214     {"below_scroll.png", PIC_TYPE_DEFAULT},
00215 
00216     {"number.png", PIC_TYPE_DEFAULT},
00217     {"invslot_u.png", PIC_TYPE_TRANS},
00218 
00219     {"death.png", PIC_TYPE_TRANS},
00220     {"sleep.png", PIC_TYPE_TRANS},
00221     {"confused.png", PIC_TYPE_TRANS},
00222     {"paralyzed.png", PIC_TYPE_TRANS},
00223     {"scared.png", PIC_TYPE_TRANS},
00224     {"blind.png", PIC_TYPE_TRANS},
00225 
00226     {"enemy1.png", PIC_TYPE_TRANS},
00227     {"enemy2.png", PIC_TYPE_TRANS},
00228     {"probe.png", PIC_TYPE_TRANS},
00229 
00230     {"quickslots.png", PIC_TYPE_DEFAULT},
00231     {"quickslotsv.png", PIC_TYPE_DEFAULT},
00232     {"inventory.png", PIC_TYPE_DEFAULT},
00233     {"inventory_bg.png", PIC_TYPE_DEFAULT},
00234 
00235     {"exp_border.png", PIC_TYPE_DEFAULT},
00236     {"exp_line.png", PIC_TYPE_DEFAULT},
00237     {"exp_bubble.png", PIC_TYPE_TRANS},
00238     {"exp_bubble2.png", PIC_TYPE_TRANS},
00239 
00240     {"main_stats.png", PIC_TYPE_DEFAULT},
00241     {"below.png", PIC_TYPE_DEFAULT},
00242     {"frame_line.png", PIC_TYPE_DEFAULT},
00243 
00244     {"target_attack.png", PIC_TYPE_TRANS},
00245     {"target_talk.png", PIC_TYPE_TRANS},
00246     {"target_normal.png", PIC_TYPE_TRANS},
00247 
00248     {"loading.png", PIC_TYPE_TRANS},
00249     {"warn_hp.png", PIC_TYPE_DEFAULT},
00250     {"warn_food.png", PIC_TYPE_DEFAULT},
00251     {"logo270.png", PIC_TYPE_DEFAULT},
00252 
00253     {"dialog_bg.png", PIC_TYPE_DEFAULT},
00254     {"dialog_title_options.png", PIC_TYPE_DEFAULT},
00255     {"dialog_title_keybind.png", PIC_TYPE_DEFAULT},
00256     {"dialog_title_skill.png", PIC_TYPE_DEFAULT},
00257     {"dialog_title_spell.png", PIC_TYPE_DEFAULT},
00258     {"dialog_title_creation.png", PIC_TYPE_DEFAULT},
00259     {"dialog_title_login.png", PIC_TYPE_DEFAULT},
00260     {"dialog_title_server.png", PIC_TYPE_DEFAULT},
00261     {"dialog_title_party.png", PIC_TYPE_DEFAULT},
00262     {"dialog_button_up.png", PIC_TYPE_DEFAULT},
00263     {"dialog_button_down.png", PIC_TYPE_DEFAULT},
00264     {"dialog_tab_start.png", PIC_TYPE_DEFAULT},
00265     {"dialog_tab.png", PIC_TYPE_DEFAULT},
00266     {"dialog_tab_stop.png", PIC_TYPE_DEFAULT},
00267     {"dialog_tab_sel.png", PIC_TYPE_DEFAULT},
00268     {"dialog_checker.png", PIC_TYPE_DEFAULT},
00269     {"dialog_range_off.png", PIC_TYPE_DEFAULT},
00270     {"dialog_range_l.png", PIC_TYPE_DEFAULT},
00271     {"dialog_range_r.png", PIC_TYPE_DEFAULT},
00272 
00273     {"target_hp.png", PIC_TYPE_DEFAULT},
00274     {"target_hp_b.png", PIC_TYPE_DEFAULT},
00275 
00276     {"textwin_mask.png", PIC_TYPE_DEFAULT},
00277     {"slider_up.png", PIC_TYPE_TRANS},
00278     {"slider_down.png", PIC_TYPE_TRANS},
00279     {"slider.png", PIC_TYPE_TRANS},
00280 
00281     {"exp_skill_border.png", PIC_TYPE_DEFAULT},
00282     {"exp_skill_line.png", PIC_TYPE_DEFAULT},
00283     {"exp_skill_bubble.png", PIC_TYPE_TRANS},
00284 
00285     {"options_head.png", PIC_TYPE_TRANS},
00286     {"options_keys.png", PIC_TYPE_TRANS},
00287     {"options_settings.png", PIC_TYPE_TRANS},
00288     {"options_logout.png", PIC_TYPE_TRANS},
00289     {"options_back.png", PIC_TYPE_TRANS},
00290     {"options_mark_left.png", PIC_TYPE_TRANS},
00291     {"options_mark_right.png", PIC_TYPE_TRANS},
00292     {"options_alpha.png", PIC_TYPE_DEFAULT},
00293 
00294     {"pentagram.png", PIC_TYPE_DEFAULT},
00295     {"quad_button_up.png", PIC_TYPE_DEFAULT},
00296     {"quad_button_down.png", PIC_TYPE_DEFAULT},
00297     {"nchar_marker.png", PIC_TYPE_TRANS},
00298 
00299     {"trapped.png", PIC_TYPE_TRANS},
00300     {"pray.png", PIC_TYPE_TRANS},
00301     {"wand.png", PIC_TYPE_TRANS},
00302     {"journal.png", PIC_TYPE_TRANS},
00303     {"slider_long.png", PIC_TYPE_DEFAULT},
00304     {"invslot_marked.png", PIC_TYPE_TRANS},
00305     {"mouse_cursor_move.png", PIC_TYPE_TRANS},
00306     {"resist_bg.png", PIC_TYPE_DEFAULT},
00307     {"main_level_bg.png",PIC_TYPE_DEFAULT},
00308     {"skill_exp_bg.png",PIC_TYPE_DEFAULT},
00309     {"regen_bg.png",PIC_TYPE_DEFAULT},
00310     {"skill_lvl_bg.png",PIC_TYPE_DEFAULT},
00311     {"menu_buttons.png",PIC_TYPE_DEFAULT},
00312     {"player_info_bg.png",PIC_TYPE_DEFAULT},
00313     {"target_bg.png", PIC_TYPE_DEFAULT},
00314     {"textinput.png", PIC_TYPE_DEFAULT},
00315     {"shop.png", PIC_TYPE_DEFAULT},
00316     {"shop_input.png", PIC_TYPE_DEFAULT}
00317 };
00318 
00320 #define BITMAP_MAX (sizeof(bitmap_name) / sizeof(_bitmap_name))
00321 
00322 _Sprite *Bitmaps[BITMAP_MAX];
00323 
00324 static void init_game_data();
00325 static void flip_screen();
00326 static void show_intro(char *text);
00327 static void delete_player_lists();
00328 static void reset_input_mode();
00329 static int load_bitmap(int index);
00330 static void free_faces();
00331 static void free_bitmaps();
00332 static void load_options_dat();
00333 
00336 static void delete_player_lists()
00337 {
00338     int i, ii;
00339 
00340     for (i = 0; i < FIRE_MODE_INIT; i++)
00341     {
00342         fire_mode_tab[i].amun = FIRE_ITEM_NO;
00343         fire_mode_tab[i].item = FIRE_ITEM_NO;
00344         fire_mode_tab[i].skill = NULL;
00345         fire_mode_tab[i].spell = NULL;
00346         fire_mode_tab[i].name[0] = '\0';
00347     }
00348 
00349     for (i = 0; i < SKILL_LIST_MAX; i++)
00350     {
00351         for (ii = 0; ii < DIALOG_LIST_ENTRY; ii++)
00352         {
00353             if (skill_list[i].entry[ii].flag == LIST_ENTRY_KNOWN)
00354             {
00355                 skill_list[i].entry[ii].flag = LIST_ENTRY_USED;
00356             }
00357         }
00358     }
00359 
00360     for (i = 0;i < SPELL_LIST_MAX; i++)
00361     {
00362         for (ii = 0; ii < DIALOG_LIST_ENTRY; ii++)
00363         {
00364             if (spell_list[i].entry[0][ii].flag == LIST_ENTRY_KNOWN)
00365             {
00366                 spell_list[i].entry[0][ii].flag = LIST_ENTRY_USED;
00367             }
00368 
00369             if (spell_list[i].entry[1][ii].flag == LIST_ENTRY_KNOWN)
00370             {
00371                 spell_list[i].entry[1][ii].flag = LIST_ENTRY_USED;
00372             }
00373         }
00374     }
00375 }
00376 
00379 static void init_game_data()
00380 {
00381     int i;
00382 
00383     textwin_init();
00384     textwin_flags = 0;
00385     first_server_char = NULL;
00386 
00387     esc_menu_flag = 0;
00388     srand(time(NULL));
00389 
00390     memset(bmaptype_table, 0, sizeof(bmaptype_table));
00391 
00392     ToggleScreenFlag = 0;
00393     KeyScanFlag = 0;
00394 
00395     memset(&fire_mode_tab, 0, sizeof(fire_mode_tab));
00396 
00397     memset(&options, 0, sizeof(struct _options));
00398     init_map_data(0, 0, 0, 0);
00399 
00400     for (i = 0; i < (int) BITMAP_MAX; i++)
00401     {
00402         Bitmaps[i] = NULL;
00403     }
00404 
00405     memset(FaceList, 0, sizeof(struct _face_struct) * MAX_FACE_TILES);
00406     memset(&cpl, 0, sizeof(cpl));
00407     cpl.ob = player_item();
00408 
00409     init_keys();
00410     init_player_data();
00411     metaserver_clear_data();
00412     reset_input_mode();
00413 
00414     msg_anim.message[0] = '\0';
00415 
00416     start_anim = NULL;
00417 
00418     map_transfer_flag = 0;
00419     start_server = NULL;
00420     argServerName[0] = '\0';
00421     argServerPort = 13327;
00422 
00423     SoundSystem = SOUND_SYSTEM_OFF;
00424     GameStatus = GAME_STATUS_INIT;
00425     CacheStatus = CF_FACE_CACHE;
00426     SoundStatus = 1;
00427     MapStatusX = MAP_MAX_SIZE;
00428     MapStatusY = MAP_MAX_SIZE;
00429     map_udate_flag = 2;
00430     map_redraw_flag = 1;
00431     InputStringFlag = 0;
00432     InputStringEndFlag = 0;
00433     InputStringEscFlag = 0;
00434     csocket.fd = SOCKET_NO;
00435     RangeFireMode = 0;
00436     gui_interface_book = NULL;
00437     gui_interface_party = NULL;
00438     help_files = NULL;
00439     options.resolution_x = 800;
00440     options.resolution_y = 600;
00441     options.playerdoll = 0;
00442 #ifdef WIDGET_SNAP
00443     options.widget_snap = 0;
00444 #endif
00445 
00446     txtwin[TW_MIX].size = 50;
00447     txtwin[TW_MSG].size = 16;
00448     txtwin[TW_CHAT].size = 16;
00449     options.zoom = 100;
00450     options.mapstart_x = 0;
00451     options.mapstart_y = 10;
00452 
00453     load_options_dat();
00454 
00455     Screensize = (_screensize *) malloc(sizeof(_screensize));
00456     Screensize->x = options.resolution_x;
00457     Screensize->y = options.resolution_y;
00458 
00459     change_textwin_font(options.chat_font_size);
00460 
00461     init_widgets_fromCurrent();
00462 
00463     textwin_clearhistory();
00464     delete_player_lists();
00465 }
00466 
00469 void save_options_dat()
00470 {
00471     char txtBuffer[20];
00472     int i = -1, j = -1;
00473     FILE *stream;
00474 
00475     if (!(stream = fopen_wrapper(OPTION_FILE, "w")))
00476     {
00477         return;
00478     }
00479 
00480     fputs("##########################################\n", stream);
00481     fputs("# This is the Atrinik client option file #\n", stream);
00482     fputs("##########################################\n", stream);
00483 
00484     snprintf(txtBuffer, sizeof(txtBuffer), "%%21 %d\n", txtwin[TW_MSG].size);
00485     fputs(txtBuffer, stream);
00486 
00487     snprintf(txtBuffer, sizeof(txtBuffer), "%%22 %d\n", txtwin[TW_CHAT].size);
00488     fputs(txtBuffer, stream);
00489 
00490     snprintf(txtBuffer, sizeof(txtBuffer), "%%3x %d\n", options.resolution_x);
00491     fputs(txtBuffer, stream);
00492 
00493     snprintf(txtBuffer, sizeof(txtBuffer), "%%3y %d\n", options.resolution_y);
00494     fputs(txtBuffer, stream);
00495 
00496     while (opt_tab[++i])
00497     {
00498         fputs("\n# ", stream);
00499         fputs(opt_tab[i], stream);
00500         fputs("\n", stream);
00501 
00502         while (opt[++j].name && opt[j].name[0] != '#')
00503         {
00504             fputs(opt[j].name, stream);
00505 
00506             switch (opt[j].value_type)
00507             {
00508                 case VAL_BOOL:
00509                 case VAL_INT:
00510                     snprintf(txtBuffer, sizeof(txtBuffer), " %d",  *((int *) opt[j].value));
00511                     break;
00512 
00513                 case VAL_U32:
00514                     snprintf(txtBuffer, sizeof(txtBuffer), " %d",  *((uint32 *) opt[j].value));
00515                     break;
00516 
00517                 case VAL_CHAR:
00518                     snprintf(txtBuffer, sizeof(txtBuffer), " %d",  *((uint8 *)opt[j].value));
00519                     break;
00520             }
00521 
00522             fputs(txtBuffer, stream);
00523             fputs("\n", stream);
00524         }
00525     }
00526 
00527     fclose(stream);
00528 }
00529 
00532 static void load_options_dat()
00533 {
00534     int i = -1, pos;
00535     FILE *stream;
00536     char line[256], keyword[256], parameter[256];
00537 
00538     /* Fill all options with default values */
00539     while (opt[++i].name)
00540     {
00541         if (opt[i].name[0] == '#')
00542         {
00543             continue;
00544         }
00545 
00546         switch (opt[i].value_type)
00547         {
00548             case VAL_BOOL:
00549             case VAL_INT:
00550                 *((int *) opt[i].value) = opt[i].default_val;
00551                 break;
00552 
00553             case VAL_U32:
00554                 *((uint32 *) opt[i].value) = opt[i].default_val;
00555                 break;
00556 
00557             case VAL_CHAR:
00558                 *((uint8 *) opt[i].value)= (uint8) opt[i].default_val;
00559                 break;
00560         }
00561     }
00562 
00563     txtwin_start_size = txtwin[TW_MIX].size;
00564 
00565     /* Read the options from file */
00566     if (!(stream = fopen_wrapper(OPTION_FILE, "r")))
00567     {
00568         LOG(llevMsg, "Can't find file %s. Using defaults.\n", OPTION_FILE);
00569         return;
00570     }
00571 
00572     while (fgets(line, 255, stream))
00573     {
00574         if (line[0] == '#' || line[0] == '\n')
00575             continue;
00576 
00577         /* This are special settings which won't show in the options window, this has to be reworked in a general way */
00578         if (line[0] == '%')
00579         {
00580             switch (line[1])
00581             {
00582                 case '2':
00583                     switch (line[2])
00584                     {
00585                         case '1':
00586                             txtwin[TW_MSG].size = atoi(line + 4);
00587                             break;
00588 
00589                         case '2':
00590                             txtwin[TW_CHAT].size = atoi(line + 4);
00591                             break;
00592                     }
00593 
00594                     break;
00595 
00596                 case '3':
00597                     switch (line[2])
00598                     {
00599                         case 'x':
00600                             options.resolution_x = atoi(line + 4);
00601                             break;
00602 
00603                         case 'y':
00604                             options.resolution_y = atoi(line + 4);
00605                             break;
00606                     }
00607 
00608                     break;
00609             }
00610 
00611             continue;
00612         }
00613 
00614         i = 0;
00615 
00616         while (line[i] && line[i] != ':')
00617         {
00618             i++;
00619         }
00620 
00621         line[++i] = '\0';
00622         strncpy(keyword, line, sizeof(keyword));
00623         strncpy(parameter, line + i + 1, sizeof(parameter));
00624         i = atoi(parameter);
00625 
00626         pos = -1;
00627 
00628         while (opt[++pos].name)
00629         {
00630             if (!strcmp(keyword, opt[pos].name))
00631             {
00632                 switch (opt[pos].value_type)
00633                 {
00634                     case VAL_BOOL:
00635                     case VAL_INT:
00636                         *((int *) opt[pos].value) = i;
00637                         break;
00638 
00639                     case VAL_U32:
00640                         *((uint32 *) opt[pos].value) = i;
00641                         break;
00642 
00643                     case VAL_CHAR:
00644                         *((uint8 *) opt[pos].value)= (uint8) i;
00645                         break;
00646                 }
00647             }
00648         }
00649     }
00650 
00651     fclose(stream);
00652 }
00653 
00655 #ifndef WIN32
00656 
00657 static void fatal_signal(int make_core)
00658 {
00659     if (make_core)
00660     {
00661         abort();
00662     }
00663 
00664     exit(0);
00665 }
00666 
00667 static void rec_sigsegv(int i)
00668 {
00669     (void) i;
00670 
00671     LOG(llevMsg, "\nSIGSEGV received.\n");
00672     fatal_signal(1);
00673 }
00674 
00675 static void rec_sighup(int i)
00676 {
00677     (void) i;
00678 
00679     LOG(llevMsg, "\nSIGHUP received\n");
00680     exit(0);
00681 }
00682 
00683 static void rec_sigquit(int i)
00684 {
00685     (void) i;
00686 
00687     LOG(llevMsg, "\nSIGQUIT received\n");
00688     fatal_signal(1);
00689 }
00690 
00691 static void rec_sigterm(int i)
00692 {
00693     (void) i;
00694 
00695     LOG(llevMsg, "\nSIGTERM received\n");
00696     fatal_signal(0);
00697 }
00698 #endif
00699 
00704 static void init_signals()
00705 {
00706 #ifndef WIN32
00707     signal(SIGHUP, rec_sighup);
00708     signal(SIGQUIT, rec_sigquit);
00709     signal(SIGSEGV, rec_sigsegv);
00710     signal(SIGTERM, rec_sigterm);
00711 #endif
00712 }
00713 
00717 static int game_status_chain()
00718 {
00719     char buf[1024];
00720 
00721     if (GameStatus == GAME_STATUS_INIT)
00722     {
00723         cpl.mark_count = -1;
00724         LOG(llevMsg, "GAMES_STATUS_INIT_1\n");
00725 
00726         map_udate_flag = 2;
00727         delete_player_lists();
00728         LOG(llevMsg, "GAMES_STATUS_INIT_2\n");
00729 
00730 #ifdef INSTALL_SOUND
00731         if (!music.flag || strcmp(music.name, "orchestral.ogg"))
00732         {
00733             sound_play_music("orchestral.ogg", options.music_volume, 0, -1, MUSIC_MODE_DIRECT);
00734         }
00735 #endif
00736 
00737         clear_map();
00738         LOG(llevMsg, "GAMES_STATUS_INIT_3\n");
00739         metaserver_clear_data();
00740         LOG(llevMsg, "GAMES_STATUS_INIT_4\n");
00741         GameStatus = GAME_STATUS_META;
00742     }
00743     else if (GameStatus == GAME_STATUS_META)
00744     {
00745         map_udate_flag = 2;
00746 
00747         metaserver_add("127.0.0.1", 13327, "Localhost", -1, "local", "Localhost. Start server before you try to connect.");
00748 
00749         if (argServerName[0] != '\0')
00750         {
00751             metaserver_add(argServerName, argServerPort, argServerName, -1, "user server", "Server from command line -server option.");
00752         }
00753 
00754         /* Skip if -nometa in command line */
00755         if (options.no_meta)
00756         {
00757             draw_info("Metaserver ignored.", COLOR_GREEN);
00758             metaserver_connecting = 0;
00759         }
00760         else
00761         {
00762             metaserver_get_servers();
00763         }
00764 
00765         GameStatus = GAME_STATUS_START;
00766     }
00767     else if (GameStatus == GAME_STATUS_START)
00768     {
00769         map_udate_flag = 2;
00770 
00771         if ((int) csocket.fd != SOCKET_NO)
00772         {
00773             socket_close(&csocket);
00774         }
00775 
00776         clear_map();
00777         map_redraw_flag = 1;
00778         clear_player();
00779         reset_keys();
00780         free_faces();
00781         GameStatus = GAME_STATUS_WAITLOOP;
00782     }
00783     else if (GameStatus == GAME_STATUS_STARTCONNECT)
00784     {
00785         char sbuf[256];
00786 
00787         snprintf(sbuf, sizeof(sbuf), "%s%s", GetBitmapDirectory(), bitmap_name[BITMAP_LOADING].name);
00788         FaceList[MAX_FACE_TILES - 1].sprite = sprite_tryload_file(sbuf, 0, NULL);
00789 
00790         map_udate_flag = 2;
00791         snprintf(buf, sizeof(buf), "Trying server %s (%d)...", selected_server->name, selected_server->port);
00792         draw_info(buf, COLOR_GREEN);
00793         GameStatus = GAME_STATUS_CONNECT;
00794     }
00795     else if (GameStatus == GAME_STATUS_CONNECT)
00796     {
00797         if (!socket_open(&csocket, selected_server->ip, selected_server->port))
00798         {
00799             draw_info("Connection failed!", COLOR_RED);
00800             GameStatus = GAME_STATUS_START;
00801             return 1;
00802         }
00803 
00804         socket_thread_start();
00805         GameStatus = GAME_STATUS_VERSION;
00806         draw_info("Connected. Exchange version.", COLOR_GREEN);
00807     }
00808     else if (GameStatus == GAME_STATUS_VERSION)
00809     {
00810         SendVersion();
00811         GameStatus = GAME_STATUS_SETUP;
00812     }
00813     else if (GameStatus == GAME_STATUS_SETUP)
00814     {
00815         map_transfer_flag = 0;
00816 
00817         srv_client_files[SRV_CLIENT_SETTINGS].status = SRV_CLIENT_STATUS_OK;
00818         srv_client_files[SRV_CLIENT_BMAPS].status = SRV_CLIENT_STATUS_OK;
00819         srv_client_files[SRV_CLIENT_ANIMS].status = SRV_CLIENT_STATUS_OK;
00820         srv_client_files[SRV_CLIENT_HFILES].status = SRV_CLIENT_STATUS_OK;
00821         srv_client_files[SRV_CLIENT_SKILLS].status = SRV_CLIENT_STATUS_OK;
00822         srv_client_files[SRV_CLIENT_SPELLS].status = SRV_CLIENT_STATUS_OK;
00823 
00824         snprintf(buf, sizeof(buf), "setup sound %d map2cmd 1 mapsize %dx%d darkness 1 facecache 1 skf %d|%x spf %d|%x bpf %d|%x stf %d|%x amf %d|%x hpf %d|%x", SoundStatus, MapStatusX, MapStatusY, srv_client_files[SRV_CLIENT_SKILLS].len, srv_client_files[SRV_CLIENT_SKILLS].crc, srv_client_files[SRV_CLIENT_SPELLS].len, srv_client_files[SRV_CLIENT_SPELLS].crc, srv_client_files[SRV_CLIENT_BMAPS].len, srv_client_files[SRV_CLIENT_BMAPS].crc, srv_client_files[SRV_CLIENT_SETTINGS].len, srv_client_files[SRV_CLIENT_SETTINGS].crc, srv_client_files[SRV_CLIENT_ANIMS].len, srv_client_files[SRV_CLIENT_ANIMS].crc, srv_client_files[SRV_CLIENT_HFILES].len, srv_client_files[SRV_CLIENT_HFILES].crc);
00825 
00826         cs_write_string(buf, strlen(buf));
00827         request_file_chain = 0;
00828 
00829         GameStatus = GAME_STATUS_WAITSETUP;
00830     }
00831     else if (GameStatus == GAME_STATUS_REQUEST_FILES)
00832     {
00833         if (request_file_chain == 0)
00834         {
00835             if (srv_client_files[SRV_CLIENT_SETTINGS].status == SRV_CLIENT_STATUS_UPDATE)
00836             {
00837                 request_file_chain = 1;
00838                 RequestFile(SRV_CLIENT_SETTINGS);
00839             }
00840             else
00841             {
00842                 request_file_chain = 2;
00843             }
00844         }
00845         else if (request_file_chain == 2)
00846         {
00847             if (srv_client_files[SRV_CLIENT_SPELLS].status == SRV_CLIENT_STATUS_UPDATE)
00848             {
00849                 request_file_chain = 3;
00850                 RequestFile(SRV_CLIENT_SPELLS);
00851             }
00852             else
00853             {
00854                 request_file_chain = 4;
00855             }
00856         }
00857         else if (request_file_chain == 4)
00858         {
00859             if (srv_client_files[SRV_CLIENT_SKILLS].status == SRV_CLIENT_STATUS_UPDATE)
00860             {
00861                 request_file_chain = 5;
00862                 RequestFile(SRV_CLIENT_SKILLS);
00863             }
00864             else
00865             {
00866                 request_file_chain = 6;
00867             }
00868         }
00869         else if (request_file_chain == 6)
00870         {
00871             if (srv_client_files[SRV_CLIENT_BMAPS].status == SRV_CLIENT_STATUS_UPDATE)
00872             {
00873                 request_file_chain = 7;
00874                 RequestFile(SRV_CLIENT_BMAPS);
00875             }
00876             else
00877             {
00878                 request_file_chain = 8;
00879             }
00880         }
00881         else if (request_file_chain == 8)
00882         {
00883             if (srv_client_files[SRV_CLIENT_ANIMS].status == SRV_CLIENT_STATUS_UPDATE)
00884             {
00885                 request_file_chain = 9;
00886                 RequestFile(SRV_CLIENT_ANIMS);
00887             }
00888             else
00889             {
00890                 request_file_chain = 10;
00891             }
00892         }
00893         else if (request_file_chain == 10)
00894         {
00895             if (srv_client_files[SRV_CLIENT_HFILES].status == SRV_CLIENT_STATUS_UPDATE)
00896             {
00897                 request_file_chain = 11;
00898                 RequestFile(SRV_CLIENT_HFILES);
00899             }
00900             else
00901             {
00902                 request_file_chain = 12;
00903             }
00904         }
00905         else if (request_file_chain == 12)
00906         {
00907             read_skills();
00908             read_spells();
00909             read_settings();
00910             read_bmaps();
00911             read_bmap_tmp();
00912             read_anims();
00913             read_anim_tmp();
00914             read_help_files();
00915             load_settings();
00916             GameStatus = GAME_STATUS_ADDME;
00917         }
00918     }
00919     else if (GameStatus == GAME_STATUS_ADDME)
00920     {
00921         cpl.mark_count = -1;
00922         map_transfer_flag = 0;
00923         SendAddMe();
00924         cpl.name[0] = '\0';
00925         cpl.password[0] = '\0';
00926         GameStatus = GAME_STATUS_LOGIN;
00927         /* Now wait for login request of the server */
00928     }
00929     else if (GameStatus == GAME_STATUS_LOGIN)
00930     {
00931         map_transfer_flag = 0;
00932 
00933         if (InputStringEscFlag)
00934         {
00935             draw_info("Break login.", COLOR_RED);
00936             GameStatus = GAME_STATUS_START;
00937         }
00938 
00939         reset_input_mode();
00940     }
00941     else if (GameStatus == GAME_STATUS_NAME)
00942     {
00943         map_transfer_flag = 0;
00944 
00945         /* We have a finished console input */
00946         if (InputStringEscFlag)
00947         {
00948             GameStatus = GAME_STATUS_LOGIN;
00949         }
00950         else if (InputStringFlag == 0 && InputStringEndFlag)
00951         {
00952             strcpy(cpl.name, InputString);
00953             LOG(llevMsg, "Login: send name %s\n", InputString);
00954             send_reply(InputString);
00955             GameStatus = GAME_STATUS_LOGIN;
00956         }
00957     }
00958     else if (GameStatus == GAME_STATUS_PSWD)
00959     {
00960         map_transfer_flag = 0;
00961 
00962         textwin_clearhistory();
00963 
00964         /* We have a finished console input */
00965         if (InputStringEscFlag)
00966         {
00967             GameStatus = GAME_STATUS_LOGIN;
00968         }
00969         else if (InputStringFlag == 0 && InputStringEndFlag)
00970         {
00971             strncpy(cpl.password, InputString, 39);
00972             cpl.password[39] = '\0';
00973 
00974             LOG(llevMsg, "Login: send password <*****>\n");
00975             send_reply(cpl.password);
00976             GameStatus = GAME_STATUS_LOGIN;
00977         }
00978     }
00979     else if (GameStatus == GAME_STATUS_VERIFYPSWD)
00980     {
00981         map_transfer_flag = 0;
00982 
00983         /* We have a finished console input */
00984         if (InputStringEscFlag)
00985         {
00986             GameStatus = GAME_STATUS_LOGIN;
00987         }
00988         else if (InputStringFlag == 0 && InputStringEndFlag)
00989         {
00990             LOG(llevMsg, "Login: send verify password <*****>\n");
00991             send_reply(InputString);
00992             GameStatus = GAME_STATUS_LOGIN;
00993         }
00994     }
00995     else if (GameStatus == GAME_STATUS_WAITFORPLAY)
00996     {
00997         clear_map();
00998         map_draw_map_clear();
00999         map_udate_flag = 2;
01000         map_transfer_flag = 1;
01001     }
01002     else if (GameStatus == GAME_STATUS_NEW_CHAR)
01003     {
01004         map_transfer_flag = 0;
01005     }
01006     else if (GameStatus == GAME_STATUS_QUIT)
01007     {
01008         map_transfer_flag = 0;
01009     }
01010 
01011     return 1;
01012 }
01013 
01016 static void load_bitmaps()
01017 {
01018     int i;
01019 
01020     /* add later better error handling here */
01021     for (i = 0; i <= BITMAP_PROGRESS_BACK; i++)
01022     {
01023         load_bitmap(i);
01024     }
01025 
01026     CreateNewFont(Bitmaps[BITMAP_FONT1], &SystemFont, 16, 16, 1);
01027     CreateNewFont(Bitmaps[BITMAP_FONTMEDIUM], &MediumFont, 16, 16, 1);
01028     CreateNewFont(Bitmaps[BITMAP_FONT1OUT], &SystemFontOut, 16, 16, 1);
01029     CreateNewFont(Bitmaps[BITMAP_FONT6x3OUT], &Font6x3Out, 16, 16, -1);
01030     CreateNewFont(Bitmaps[BITMAP_BIGFONT], &BigFont, 11, 16, 3);
01031 }
01032 
01037 static int load_bitmap(int index)
01038 {
01039     char buf[2048];
01040     uint32 flags = 0;
01041 
01042     snprintf(buf, sizeof(buf), "%s%s", GetBitmapDirectory(), bitmap_name[index].name);
01043 
01044     if (bitmap_name[index].type == PIC_TYPE_PALETTE)
01045     {
01046         flags |= SURFACE_FLAG_PALETTE;
01047     }
01048 
01049     if (bitmap_name[index].type == PIC_TYPE_TRANS)
01050     {
01051         flags |= SURFACE_FLAG_COLKEY_16M;
01052     }
01053 
01054     if (index >= BITMAP_INTRO && index != BITMAP_TEXTWIN_MASK)
01055     {
01056         flags |= SURFACE_FLAG_DISPLAYFORMAT;
01057     }
01058 
01059     Bitmaps[index] = sprite_load_file(buf, flags);
01060 
01061     if (!Bitmaps[index] || !Bitmaps[index]->bitmap)
01062     {
01063         LOG(llevMsg, "load_bitmap(): Can't load bitmap %s\n", buf);
01064         return 0;
01065     }
01066 
01067     return 1;
01068 }
01069 
01072 static void free_bitmaps()
01073 {
01074     int i, ii;
01075 
01076     for (i = 0; i < (int) BITMAP_MAX; i++)
01077     {
01078         sprite_free_sprite(Bitmaps[i]);
01079     }
01080 
01081     for (i = 0; i < SPELL_LIST_MAX; i++)
01082     {
01083         for (ii = 0; ii < DIALOG_LIST_ENTRY; ii++)
01084         {
01085             if ((spell_list[i].entry[0][ii].flag != LIST_ENTRY_UNUSED) && spell_list[i].entry[0][ii].icon)
01086             {
01087                 sprite_free_sprite(spell_list[i].entry[0][ii].icon);
01088             }
01089 
01090             if ((spell_list[i].entry[1][ii].flag != LIST_ENTRY_UNUSED) && spell_list[i].entry[1][ii].icon)
01091             {
01092                 sprite_free_sprite(spell_list[i].entry[1][ii].icon);
01093             }
01094         }
01095     }
01096 
01097     for (i = 0; i < SKILL_LIST_MAX; i++)
01098     {
01099         for (ii = 0; ii < DIALOG_LIST_ENTRY; ii++)
01100         {
01101             if ((skill_list[i].entry[ii].flag != LIST_ENTRY_UNUSED) && skill_list[i].entry[ii].icon)
01102             {
01103                 sprite_free_sprite(skill_list[i].entry[ii].icon);
01104             }
01105         }
01106     }
01107 }
01108 
01111 static void free_faces()
01112 {
01113     int i;
01114 
01115     for (i = 0; i < MAX_FACE_TILES; i++)
01116     {
01117         if (FaceList[i].sprite)
01118         {
01119             sprite_free_sprite(FaceList[i].sprite);
01120             FaceList[i].sprite = NULL;
01121         }
01122 
01123         if (FaceList[i].name)
01124         {
01125             void *tmp_free = &FaceList[i].name;
01126             FreeMemory(tmp_free);
01127         }
01128 
01129         FaceList[i].flags =0;
01130     }
01131 }
01132 
01135 static void reset_input_mode()
01136 {
01137     InputString[0] = '\0';
01138     InputCount = 0;
01139     HistoryPos = 0;
01140     InputHistory[0][0] = '\0';
01141     CurrentCursorPos = 0;
01142     InputStringFlag = 0;
01143     InputStringEndFlag = 0;
01144     InputStringEscFlag = 0;
01145 }
01146 
01150 void open_input_mode(int maxchar)
01151 {
01152     int interval = (options.key_repeat > 0) ? 70 / options.key_repeat : 0;
01153     int delay = (options.key_repeat > 0) ? interval + 280 / options.key_repeat : 0;
01154 
01155     reset_input_mode();
01156     InputMax = maxchar;
01157     SDL_EnableKeyRepeat(delay, interval);
01158 
01159     if (cpl.input_mode != INPUT_MODE_NUMBER)
01160     {
01161         cpl.inventory_win = IWIN_BELOW;
01162     }
01163 
01164     InputStringFlag = 1;
01165 }
01166 
01169 static void play_action_sounds()
01170 {
01171     if (cpl.warn_statdown)
01172     {
01173         sound_play_one_repeat(SOUND_WARN_STATDOWN, SPECIAL_SOUND_STATDOWN);
01174         cpl.warn_statdown = 0;
01175     }
01176 
01177     if (cpl.warn_statup)
01178     {
01179         sound_play_one_repeat(SOUND_WARN_STATUP, SPECIAL_SOUND_STATUP);
01180         cpl.warn_statup = 0;
01181     }
01182 
01183     if (cpl.warn_drain)
01184     {
01185         sound_play_one_repeat(SOUND_WARN_DRAIN, SPECIAL_SOUND_DRAIN);
01186         cpl.warn_drain = 0;
01187     }
01188 
01189     if (cpl.warn_hp)
01190     {
01191         if (cpl.warn_hp == 2)
01192         {
01193             sound_play_effect(SOUND_WARN_HP2, 0, 100);
01194         }
01195         else
01196         {
01197             sound_play_effect(SOUND_WARN_HP, 0, 100);
01198         }
01199 
01200         cpl.warn_hp = 0;
01201     }
01202 }
01203 
01206 void list_vid_modes()
01207 {
01208     const SDL_VideoInfo* vinfo = NULL;
01209     SDL_Rect **modes;
01210     int i;
01211 
01212     LOG(llevMsg, "List Video Modes\n");
01213 
01214     /* Get available fullscreen/hardware modes */
01215     modes = SDL_ListModes(NULL, SDL_HWACCEL);
01216 
01217     /* Check if there are any modes available */
01218     if (modes == (SDL_Rect **) 0)
01219     {
01220         LOG(llevMsg, "No modes available!\n");
01221         exit(-1);
01222     }
01223 
01224     /* Check if resolution is restricted */
01225     if (modes == (SDL_Rect **) -1)
01226     {
01227         LOG(llevMsg, "All resolutions available.\n");
01228     }
01229     else
01230     {
01231         /* Print valid modes */
01232         LOG(llevMsg, "Available Modes\n");
01233 
01234         for (i = 0; modes[i]; ++i)
01235         {
01236             LOG(llevMsg, "  %d x %d\n", modes[i]->w, modes[i]->h);
01237         }
01238     }
01239 
01240     vinfo = SDL_GetVideoInfo();
01241     LOG(llevMsg, "VideoInfo: hardware surfaces? %s\n", vinfo->hw_available ? "yes" : "no");
01242     LOG(llevMsg, "VideoInfo: windows manager? %s\n", vinfo->wm_available ? "yes" : "no");
01243     LOG(llevMsg, "VideoInfo: hw to hw blit? %s\n", vinfo->blit_hw ? "yes" : "no");
01244     LOG(llevMsg, "VideoInfo: hw to hw ckey blit? %s\n", vinfo->blit_hw_CC ? "yes" : "no");
01245     LOG(llevMsg, "VideoInfo: hw to hw alpha blit? %s\n", vinfo->blit_hw_A ? "yes" : "no");
01246     LOG(llevMsg, "VideoInfo: sw to hw blit? %s\n", vinfo->blit_sw ? "yes" : "no");
01247     LOG(llevMsg, "VideoInfo: sw to hw ckey blit? %s\n", vinfo->blit_sw_CC ? "yes" : "no");
01248     LOG(llevMsg, "VideoInfo: sw to hw alpha blit? %s\n", vinfo->blit_sw_A ? "yes":  "no");
01249     LOG(llevMsg, "VideoInfo: color fill? %s\n", vinfo->blit_fill ? "yes" : "no");
01250     LOG(llevMsg, "VideoInfo: video memory: %dKB\n", vinfo->video_mem);
01251 }
01252 
01257 static void show_option(int x, int y)
01258 {
01259     int index = 0, x1, y1 = 0, x2, y2 = 0;
01260     _BLTFX bltfx;
01261 
01262     bltfx.dark_level = 0;
01263     bltfx.surface = NULL;
01264     bltfx.alpha = 118;
01265     bltfx.flags = BLTFX_FLAG_SRCALPHA;
01266 
01267     sprite_blt(Bitmaps[BITMAP_OPTIONS_ALPHA], x - Bitmaps[BITMAP_OPTIONS_ALPHA]->bitmap->w / 2, y, NULL, &bltfx);
01268     sprite_blt(Bitmaps[BITMAP_OPTIONS_HEAD], x - Bitmaps[BITMAP_OPTIONS_HEAD]->bitmap->w / 2, y, NULL, NULL);
01269     sprite_blt(Bitmaps[BITMAP_OPTIONS_KEYS], x - Bitmaps[BITMAP_OPTIONS_KEYS]->bitmap->w / 2, y + 100, NULL, NULL);
01270     sprite_blt(Bitmaps[BITMAP_OPTIONS_SETTINGS], x - Bitmaps[BITMAP_OPTIONS_SETTINGS]->bitmap->w / 2, y + 165, NULL, NULL);
01271     sprite_blt(Bitmaps[BITMAP_OPTIONS_LOGOUT], x - Bitmaps[BITMAP_OPTIONS_LOGOUT]->bitmap->w / 2, y + 235, NULL, NULL);
01272     sprite_blt(Bitmaps[BITMAP_OPTIONS_BACK], x - Bitmaps[BITMAP_OPTIONS_BACK]->bitmap->w / 2, y + 305, NULL, NULL);
01273 
01274     if (esc_menu_index == ESC_MENU_KEYS)
01275     {
01276         index = BITMAP_OPTIONS_KEYS;
01277         y1 = y2 = y + 105;
01278     }
01279     else if (esc_menu_index == ESC_MENU_SETTINGS)
01280     {
01281         index = BITMAP_OPTIONS_SETTINGS;
01282         y1 = y2 = y + 170;
01283     }
01284     else if (esc_menu_index == ESC_MENU_LOGOUT)
01285     {
01286         index = BITMAP_OPTIONS_LOGOUT;
01287         y1 = y2 = y + 244;
01288     }
01289     else if (esc_menu_index == ESC_MENU_BACK)
01290     {
01291         index = BITMAP_OPTIONS_BACK;
01292         y1 = y2 = y + 310;
01293     }
01294 
01295     x1 = x - Bitmaps[index]->bitmap->w / 2 - 6;
01296     x2 = x + Bitmaps[index]->bitmap->w / 2 + 6;
01297 
01298     sprite_blt(Bitmaps[BITMAP_OPTIONS_MARK_LEFT], x1 - Bitmaps[BITMAP_OPTIONS_MARK_LEFT]->bitmap->w, y1, NULL, NULL);
01299     sprite_blt(Bitmaps[BITMAP_OPTIONS_MARK_RIGHT], x2, y2, NULL, NULL);
01300 }
01301 
01304 static void display_layer1()
01305 {
01306     static int gfx_toggle = 0;
01307     SDL_Rect rect;
01308 
01309     SDL_FillRect(ScreenSurface, NULL, 0);
01310 
01311     /* We recreate the map only when there is a change */
01312     if (map_redraw_flag)
01313     {
01314         SDL_FillRect(ScreenSurfaceMap, NULL, 0);
01315         map_draw_map();
01316         map_redraw_flag = 0;
01317 
01318         if (options.zoom != 100)
01319         {
01320             SDL_FreeSurface(zoomed);
01321             zoomed = zoomSurface(ScreenSurfaceMap, options.zoom / 100.0, options.zoom / 100.0, options.zoom_smooth);
01322         }
01323     }
01324 
01325     rect.x = options.mapstart_x;
01326     rect.y = options.mapstart_y;
01327 
01328     if (options.zoom == 100)
01329     {
01330         SDL_BlitSurface(ScreenSurfaceMap, NULL, ScreenSurface, &rect);
01331     }
01332     else
01333     {
01334         SDL_BlitSurface(zoomed, NULL, ScreenSurface, &rect);
01335     }
01336 
01337     /* The damage numbers */
01338     play_anims();
01339 
01340     /* Draw warning icons above player */
01341     if ((gfx_toggle++ & 63) < 25)
01342     {
01343         if (options.warning_hp && ((float) cpl.stats.hp / (float) cpl.stats.maxhp) * 100 <= options.warning_hp)
01344         {
01345             sprite_blt(Bitmaps[BITMAP_WARN_HP], options.mapstart_x + 393, options.mapstart_y + 298, NULL, NULL);
01346         }
01347     }
01348     else
01349     {
01350         /* Low food */
01351         if (options.warning_food && ((float) cpl.stats.food / 1000.0f) * 100 <= options.warning_food)
01352         {
01353             sprite_blt(Bitmaps[BITMAP_WARN_FOOD], options.mapstart_x + 390, options.mapstart_y + 294, NULL, NULL);
01354         }
01355     }
01356 }
01357 
01360 static void display_layer2()
01361 {
01362     cpl.container = NULL;
01363 
01364     if (GameStatus == GAME_STATUS_PLAY)
01365     {
01366         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);
01367 
01368         cpl.real_weight = cpl.window_weight;
01369 
01370         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);
01371     }
01372 }
01373 
01376 static void display_layer3()
01377 {
01378     /* Process the widgets */
01379     if (GameStatus == GAME_STATUS_PLAY)
01380     {
01381         process_widgets();
01382     }
01383 }
01384 
01385 /* dialogs, highest-priority layer */
01388 static void display_layer4()
01389 {
01390     if (GameStatus == GAME_STATUS_PLAY)
01391     {
01392         /* We have to make sure that these two get hidden right */
01393         cur_widget[IN_CONSOLE_ID].show = 0;
01394         cur_widget[IN_NUMBER_ID].show = 0;
01395 
01396         if (cpl.input_mode == INPUT_MODE_CONSOLE)
01397         {
01398             do_console();
01399         }
01400         else if (cpl.input_mode == INPUT_MODE_NUMBER)
01401         {
01402             do_number();
01403         }
01404         else if (cpl.input_mode == INPUT_MODE_GETKEY)
01405         {
01406             do_keybind_input();
01407         }
01408     }
01409 
01410     if (esc_menu_flag)
01411     {
01412         show_option(Screensize->x / 2, (Screensize->y / 2) - (Bitmaps[BITMAP_OPTIONS_ALPHA]->bitmap->h / 2));
01413     }
01414 }
01415 
01418 static void DisplayCustomCursor()
01419 {
01420     if (f_custom_cursor == MSCURSOR_MOVE)
01421     {
01422         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);
01423     }
01424 }
01425 
01431 int main(int argc, char *argv[])
01432 {
01433     int x, y, drag;
01434     uint32 anim_tick;
01435     Uint32 videoflags;
01436     int i, done = 0;
01437 
01438     init_signals();
01439     init_game_data();
01440     curl_global_init(CURL_GLOBAL_ALL);
01441 
01442     while (argc > 1)
01443     {
01444         argc--;
01445 
01446         if (strcmp(argv[argc - 1], "-port") == 0)
01447         {
01448             argServerPort = atoi(argv[argc]);
01449             argc--;
01450         }
01451         else if (strcmp(argv[argc - 1], "-server") == 0)
01452         {
01453             strcpy(argServerName, argv[argc]);
01454 
01455             if (strchr(argv[argc], ':') != '\0')
01456             {
01457                 argServerPort = atoi(strrchr(argv[argc], ':') + 1);
01458                 *strchr(argServerName, ':') = '\0';
01459             }
01460 
01461             argc--;
01462         }
01463         else if (strcmp(argv[argc], "-nometa") == 0)
01464         {
01465             options.no_meta = 1;
01466         }
01467         else if (strcmp(argv[argc], "-key") == 0)
01468         {
01469             KeyScanFlag = 1;
01470         }
01471         else
01472         {
01473             char tmp[1024];
01474 
01475             snprintf(tmp, sizeof(tmp), "Usage: %s [-server <name>] [-port <num>]\n", argv[0]);
01476             LOG(llevMsg, tmp);
01477             fprintf(stderr, "%s", tmp);
01478             exit(1);
01479         }
01480     }
01481 
01482     if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO) < 0)
01483     {
01484         LOG(llevError, "Couldn't initialize SDL: %s\n", SDL_GetError());
01485         exit(1);
01486     }
01487 
01488     /* Start the system after starting SDL */
01489     SYSTEM_Start();
01490     list_vid_modes();
01491 
01492     videoflags = get_video_flags();
01493     options.used_video_bpp = 16;
01494 
01495     if (!options.fullscreen_flag)
01496     {
01497         if (options.auto_bpp_flag)
01498         {
01499             const SDL_VideoInfo* info = NULL;
01500             info = SDL_GetVideoInfo();
01501             options.used_video_bpp = info->vfmt->BitsPerPixel;
01502         }
01503     }
01504 
01505     if ((ScreenSurface = SDL_SetVideoMode(Screensize->x, Screensize->y, options.used_video_bpp, videoflags)) == NULL)
01506     {
01507         /* We have a problem, not supportet screensize */
01508         /* If we have higher resolution we try the default 800x600 */
01509         if (Screensize->x > 800 && Screensize->y > 600)
01510         {
01511             LOG(llevError, "Try to set to default 800x600...\n");
01512 
01513             if ((ScreenSurface = SDL_SetVideoMode(Screensize->x, Screensize->y, options.used_video_bpp, videoflags)) == NULL)
01514             {
01515                 /* Now we have a really really big problem */
01516                 LOG(llevError, "Couldn't set %dx%dx%d video mode: %s\n", Screensize->x, Screensize->y, options.used_video_bpp, SDL_GetError());
01517                 exit(2);
01518             }
01519             else
01520             {
01521                 const SDL_VideoInfo *info = SDL_GetVideoInfo();
01522 
01523                 options.real_video_bpp = info->vfmt->BitsPerPixel;
01524             }
01525         }
01526         else
01527         {
01528             exit(2);
01529         }
01530     }
01531     else
01532     {
01533         const SDL_VideoInfo *info = SDL_GetVideoInfo();
01534 
01535         options.used_video_bpp = info->vfmt->BitsPerPixel;
01536     }
01537 
01538     sprite_init_system();
01539     ScreenSurfaceMap = SDL_CreateRGBSurface(videoflags, 850, 600, options.used_video_bpp, 0,0,0,0);
01540 
01541     /* 60, 70*/
01542     sdl_dgreen = SDL_MapRGB(ScreenSurface->format, 0x00, 0x80, 0x00);
01543     sdl_gray1 = SDL_MapRGB(ScreenSurface->format, 0x45, 0x45, 0x45);
01544     sdl_gray2 = SDL_MapRGB(ScreenSurface->format, 0x55, 0x55, 0x55);
01545 
01546     sdl_gray3 = SDL_MapRGB(ScreenSurface->format, 0x55, 0x55, 0x55);
01547     sdl_gray4 = SDL_MapRGB(ScreenSurface->format, 0x60, 0x60, 0x60);
01548 
01549     sdl_blue1 = SDL_MapRGB(ScreenSurface->format, 0x00, 0x00, 0xef);
01550 
01551     SDL_EnableUNICODE(1);
01552 
01553     load_bitmaps();
01554     show_intro("Load bitmaps");
01555 
01556     /* TODO: add later better error handling here */
01557     for (i = BITMAP_DOLL; i < (int) BITMAP_MAX; i++)
01558         load_bitmap(i);
01559 
01560     sound_init();
01561     show_intro("Start sound system");
01562 
01563     sound_loadall();
01564     show_intro("Load sounds");
01565 
01566     read_keybind_file(KEYBIND_FILE);
01567     show_intro("Load keys");
01568 
01569     load_mapdef_dat();
01570     show_intro("Load mapdefs");
01571 
01572     read_bmaps_p0();
01573     show_intro("Load picture data");
01574 
01575     read_settings();
01576     show_intro("Load settings");
01577 
01578     read_spells();
01579     show_intro("Load spells");
01580 
01581     read_skills();
01582     show_intro("Load skills");
01583 
01584     read_anims();
01585     show_intro("Load anims");
01586 
01587     read_bmaps();
01588     show_intro("Load bmaps");
01589 
01590     read_help_files();
01591     show_intro("Load help files");
01592 
01593     sound_play_music("orchestral.ogg", options.music_volume, 0, -1, MUSIC_MODE_DIRECT);
01594     show_intro(NULL);
01595 
01596     while (1)
01597     {
01598         SDL_Event event;
01599 
01600         SDL_PollEvent(&event);
01601 
01602         if (event.type == SDL_QUIT)
01603         {
01604             sound_freeall();
01605             sound_deinit();
01606             free_bitmaps();
01607             SYSTEM_End();
01608             return 0;
01609         }
01610 
01611         if (event.type == SDL_KEYUP || event.type == SDL_KEYDOWN || event.type == SDL_MOUSEBUTTONDOWN)
01612         {
01613             reset_keys();
01614             break;
01615         }
01616 
01617         /* force the thread to sleep */
01618         SDL_Delay(15);
01619 
01620         /* wait for keypress */
01621     }
01622 
01623     script_autoload();
01624 
01625     draw_info_format(COLOR_HGOLD, "Welcome to Atrinik version %s.", PACKAGE_VERSION);
01626     draw_info("Init network...", COLOR_GREEN);
01627 
01628     if (!socket_initialize())
01629     {
01630         exit(1);
01631     }
01632 
01633     LastTick = tmpGameTick = anim_tick = SDL_GetTicks();
01634     GameTicksSec = 0;
01635 
01636     while (!done)
01637     {
01638         done = Event_PollInputDevice();
01639 
01640         /* Have we been shutdown? */
01641         if (handle_socket_shutdown())
01642         {
01643             GameStatus = GAME_STATUS_INIT;
01644             continue;
01645         }
01646 
01647 #ifdef INSTALL_SOUND
01648         if (music_global_fade)
01649         {
01650             sound_fadeout_music(music_new.flag);
01651         }
01652 #endif
01653 
01654         GameTicksSec = LastTick - tmpGameTick;
01655 
01656         if (GameStatus > GAME_STATUS_CONNECT)
01657         {
01658             DoClient();
01659             /* Flush face request buffer. */
01660             request_face(0, 1);
01661         }
01662 
01663         if (GameStatus == GAME_STATUS_PLAY)
01664         {
01665             if (LastTick - anim_tick > 110)
01666             {
01667                 anim_tick = LastTick;
01668                 animate_objects();
01669                 map_udate_flag = 2;
01670             }
01671 
01672             play_action_sounds();
01673         }
01674 
01675         map_udate_flag = 2;
01676 
01677         if (map_udate_flag > 0)
01678         {
01679             display_layer1();
01680             display_layer2();
01681             display_layer3();
01682             display_layer4();
01683 
01684             if (GameStatus != GAME_STATUS_PLAY)
01685             {
01686                 SDL_FillRect(ScreenSurface, NULL, 0);
01687             }
01688 
01689             if (esc_menu_flag)
01690             {
01691                 map_udate_flag = 1;
01692             }
01693             else if (!options.force_redraw)
01694             {
01695                 if (options.doublebuf_flag)
01696                 {
01697                     map_udate_flag--;
01698                 }
01699                 else
01700                 {
01701                     map_udate_flag = 0;
01702                 }
01703             }
01704         }
01705 
01706         /* Get our ticks */
01707         if ((LastTick - tmpGameTick) > 1000)
01708         {
01709             tmpGameTick = LastTick;
01710             FrameCount = 0;
01711             GameTicksSec = 0;
01712         }
01713 
01714         if (GameStatus != GAME_STATUS_PLAY)
01715         {
01716             textwin_show(539, 485);
01717         }
01718 
01719         if (GameStatus == GAME_STATUS_PLAY)
01720         {
01721             SDL_Rect tmp_rect;
01722             tmp_rect.w = 275;
01723 
01724             if (cpl.input_mode == INPUT_MODE_CONSOLE)
01725                 do_console();
01726             else if (cpl.input_mode == INPUT_MODE_NUMBER)
01727                 do_number();
01728             else if (cpl.input_mode == INPUT_MODE_GETKEY)
01729                 do_keybind_input();
01730         }
01731         else if (GameStatus == GAME_STATUS_WAITFORPLAY)
01732         {
01733             StringBlt(ScreenSurface, &SystemFont, "Transfer Character to Map...", 300, 300, COLOR_DEFAULT, NULL, NULL);
01734         }
01735 
01736         /* If not connected, walk through connection chain and/or wait for action */
01737         if (GameStatus != GAME_STATUS_PLAY)
01738         {
01739             if (!game_status_chain())
01740             {
01741                 LOG(llevError, "Error connecting: GStatus: %d  SocketError: %d\n", GameStatus, socket_get_error());
01742                 exit(1);
01743             }
01744         }
01745 
01746         /* Show main option menu */
01747         if (esc_menu_flag)
01748         {
01749             show_option(Screensize->x / 2, (Screensize->y / 2) - (Bitmaps[BITMAP_OPTIONS_ALPHA]->bitmap->h / 2));
01750         }
01751 
01752         if (map_transfer_flag)
01753         {
01754             StringBlt(ScreenSurface, &SystemFont, "Transfer Character to Map...", 300, 300, COLOR_DEFAULT, NULL, NULL);
01755         }
01756 
01757         /* Show the current dragged item */
01758         if ((drag = draggingInvItem(DRAG_GET_STATUS)))
01759         {
01760             item *Item = NULL;
01761 
01762             if (drag == DRAG_IWIN_INV)
01763             {
01764                 Item = locate_item(cpl.win_inv_tag);
01765             }
01766             else if (drag == DRAG_IWIN_BELOW)
01767             {
01768                 Item = locate_item(cpl.win_below_tag);
01769             }
01770             else if (drag == DRAG_QUICKSLOT)
01771             {
01772                 Item = locate_item(cpl.win_quick_tag);
01773             }
01774             else if (drag == DRAG_PDOLL)
01775             {
01776                 Item = locate_item(cpl.win_pdoll_tag);
01777             }
01778 
01779             SDL_GetMouseState(&x, &y);
01780 
01781             if (drag == DRAG_QUICKSLOT_SPELL)
01782             {
01783                 sprite_blt(spell_list[quick_slots[cpl.win_quick_tag].groupNr].entry[quick_slots[cpl.win_quick_tag].classNr][quick_slots[cpl.win_quick_tag].spellNr].icon, x,y, NULL, NULL);
01784             }
01785             else
01786             {
01787                 blt_inv_item_centered(Item, x, y);
01788             }
01789         }
01790 
01791         if (GameStatus < GAME_STATUS_REQUEST_FILES)
01792         {
01793             show_meta_server(start_server, metaserver_sel);
01794         }
01795         else if (GameStatus >= GAME_STATUS_REQUEST_FILES && GameStatus < GAME_STATUS_NEW_CHAR)
01796         {
01797             show_login_server();
01798         }
01799         else if (GameStatus == GAME_STATUS_NEW_CHAR)
01800         {
01801             cpl.menustatus = MENU_CREATE;
01802         }
01803 
01804         /* Show all kind of the big dialog windows */
01805         show_menu();
01806 
01807         /* We have a non-standard mouse-pointer (win-size changer, etc.) */
01808         if (cursor_type)
01809         {
01810             SDL_Rect rec;
01811 
01812             SDL_GetMouseState(&x, &y);
01813             rec.w = 14;
01814             rec.h = 1;
01815             rec.x = x - 7;
01816             rec.y = y - 2;
01817             SDL_FillRect(ScreenSurface, &rec, -1);
01818             rec.y = y - 5;
01819             SDL_FillRect(ScreenSurface, &rec, -1);
01820         }
01821 
01822         if (f_custom_cursor)
01823         {
01824             DisplayCustomCursor();
01825         }
01826 
01827         FrameCount++;
01828         LastTick = SDL_GetTicks();
01829 
01830         script_process();
01831 
01832         /* Process message animations */
01833         if ((GameStatus == GAME_STATUS_PLAY) && msg_anim.message[0] != '\0')
01834         {
01835             map_udate_flag = 2;
01836 
01837             if ((LastTick - msg_anim.tick) < 3000)
01838             {
01839                 _BLTFX bmbltfx;
01840                 int bmoff = (int) ((50.0f / 3.0f) * ((float) (LastTick - msg_anim.tick) / 1000.0f) * ((float) (LastTick - msg_anim.tick) / 1000.0f) + ((int) (150.0f * ((float) (LastTick - msg_anim.tick) / 3000.0f))));
01841 
01842                 bmbltfx.alpha = 255;
01843                 bmbltfx.flags = BLTFX_FLAG_SRCALPHA;
01844 
01845                 if (LastTick - msg_anim.tick > 2000)
01846                 {
01847                     bmbltfx.alpha -= (int) (255.0f * ((float) (LastTick - msg_anim.tick - 2000) / 1000.0f));
01848                 }
01849 
01850                 StringBlt(ScreenSurface, &BigFont, msg_anim.message, Screensize->x / 2 - (StringWidth(&BigFont, msg_anim.message) / 2), 300 - bmoff, COLOR_BLACK, NULL, &bmbltfx);
01851                 StringBlt(ScreenSurface, &BigFont, msg_anim.message, Screensize->x / 2 - (StringWidth(&BigFont, msg_anim.message) / 2) - 2 , 300 - 2 - bmoff, msg_anim.flags & 0xff, NULL, &bmbltfx);
01852             }
01853             else
01854             {
01855                 msg_anim.message[0] = '\0';
01856             }
01857         }
01858 
01859         flip_screen();
01860 
01861         /* Force the thread to sleep */
01862         if (options.max_speed)
01863         {
01864             SDL_Delay(options.sleep);
01865         }
01866     }
01867 
01868     script_killall();
01869     save_interface_file();
01870     kill_widgets();
01871     save_options_dat();
01872     curl_global_cleanup();
01873     socket_deinitialize();
01874     sound_freeall();
01875     sound_deinit();
01876     free_bitmaps();
01877     SYSTEM_End();
01878 
01879     return 0;
01880 }
01881 
01885 static void show_intro(char *text)
01886 {
01887     char buf[256];
01888     int x, y, progress, progress_x, progress_y;
01889     SDL_Rect box;
01890 
01891     current_intro++;
01892 
01893     x = Screensize->x / 2 - Bitmaps[BITMAP_INTRO]->bitmap->w / 2;
01894     y = Screensize->y / 2 - Bitmaps[BITMAP_INTRO]->bitmap->h / 2;
01895 
01896     progress_x = Screensize->x / 2 - Bitmaps[BITMAP_PROGRESS]->bitmap->w / 2;
01897     progress_y = Bitmaps[BITMAP_INTRO]->bitmap->h + y - Bitmaps[BITMAP_PROGRESS]->bitmap->h;
01898 
01899     sprite_blt(Bitmaps[BITMAP_INTRO], x, y, NULL, NULL);
01900 
01901     /* Update progress bar */
01902     sprite_blt(Bitmaps[BITMAP_PROGRESS_BACK], progress_x, progress_y, NULL, NULL);
01903 
01904     progress = MIN(100, current_intro * 8);
01905     box.x = 0;
01906     box.y = 0;
01907     box.h = Bitmaps[BITMAP_PROGRESS]->bitmap->h;
01908     box.w = (int) ((float) Bitmaps[BITMAP_PROGRESS]->bitmap->w / 100 * progress);
01909     sprite_blt(Bitmaps[BITMAP_PROGRESS], progress_x, progress_y, &box, NULL);
01910 
01911     if (text)
01912     {
01913         StringBlt(ScreenSurface, &SystemFont, text, progress_x + Bitmaps[BITMAP_PROGRESS]->bitmap->w / 3, progress_y + 5, COLOR_DEFAULT, NULL, NULL);
01914     }
01915     else
01916     {
01917         StringBlt(ScreenSurface, &SystemFont, "** Press Key **", progress_x + Bitmaps[BITMAP_PROGRESS]->bitmap->w / 3, progress_y + 5, COLOR_DEFAULT, NULL, NULL);
01918     }
01919 
01920     snprintf(buf, sizeof(buf), "v. %s", PACKAGE_VERSION);
01921     StringBlt(ScreenSurface, &SystemFont, buf, x + 10, progress_y + 5, COLOR_DEFAULT, NULL, NULL);
01922     flip_screen();
01923 }
01924 
01927 static void flip_screen()
01928 {
01929     if (options.use_rect)
01930     {
01931         SDL_UpdateRect(ScreenSurface, 0, 0, Screensize->x, Screensize->y);
01932     }
01933     else
01934     {
01935         SDL_Flip(ScreenSurface);
01936     }
01937 }

Generated on Mon Nov 29 2010 00:00:05 for Atrinik Client by  doxygen 1.7.1