|
Atrinik Client 1.0
|
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 <include.h> 00031 00033 struct _dialog_list_set option_list_set; 00034 00036 const char *opt_tab[] = 00037 { 00038 "General", 00039 "Client", 00040 "Map", 00041 "Sound", 00042 "Fullscreen flags", 00043 "Windowed flags", 00044 "Debug", 00045 NULL 00046 }; 00047 00049 enum 00050 { 00051 SEL_BUTTON, 00052 SEL_CHECKBOX, 00053 SEL_RANGE, 00054 SEL_TEXT 00055 }; 00056 // get drop both 00058 _option opt[] = 00059 { 00060 /* General */ 00061 {"Playerdoll:", "Whether to always show the playerdoll.\nIf unchecked, the playerdoll is only shown while the inventory is open.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.playerdoll, VAL_BOOL}, 00062 {"Show yourself targeted:", "Show your name in the target area instead of blank.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.show_target_self, VAL_BOOL}, 00063 {"Show Tooltips:", "Show tooltips when hovering with the mouse over items.", "", SEL_CHECKBOX, 0, 1, 1, 1, &options.show_tooltips, VAL_BOOL}, 00064 {"Collect mode:", "If enabled, will get/drop all items in the stack instead of asking\nhow many to get/drop.", "None#Get#Drop#Both", SEL_RANGE, 0, 3, 1, 0, &options.collect_mode, VAL_INT}, 00065 {"Exp display:", "The format key is: ~4nl~ = For next level; ~tnl~ = Till next level;\n~LExp~ = Level exp; ~TExp~ = Total exp;", "Level/LExp#LExp\\%#LExp/LExp 4nl#TExp/TExp 4nl#(LExp\\%) LExp tnl", SEL_RANGE, 0, 4, 1, 4, &options.expDisplay, VAL_INT}, 00066 {"Chat Timestamps:", "Show a timestamp before each chat message.", "Disabled#HH:MM#HH:MM:SS#H:MM AM/PM#H:MM:SS AM/PM", SEL_RANGE, 0, 4, 1, 0, &options.chat_timestamp, VAL_INT}, 00067 {"Font size in chat boxes:", "Font size used in chat boxes on left and right.", "10px#11px#12px#13px#14px#15px#16px", SEL_RANGE, 0, 6, 1, 1, &options.chat_font_size, VAL_INT}, 00068 {"Maximum chat lines:", "Maximum number of lines in the chat boxes.", "", SEL_RANGE, 20, 1000, 10, 200, &options.chat_max_lines, VAL_INT}, 00069 {"#", "", "", 0, 0, 0, 0, 0, 0, 0}, 00070 00071 /* Client */ 00072 {"Fullscreen:", "Toggle fullscreen to windowed mode.\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.fullscreen, VAL_BOOL}, 00073 {"Resolution:", "The resolution of the screen/window.\nIf you change to lower resolutions your GUI-windows may be hidden.", "Custom#800x600#960x600#1024x768#1100x700#1280x720#1280x800#1280x960#1280x1024#1440x900#1400x1050#1600x1200#1680x1050#1920x1080#1920x1200#2048x1536#2560x1600", SEL_RANGE, 0, 15, 1, 0, &options.resolution, VAL_INT}, 00074 {"Automatic bpp:", "Use always the same bits per pixel like your default windows.\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 1, &options.auto_bpp_flag, VAL_BOOL}, 00075 {"Colordeep:", "Use this bpp for fullscreen mode. Overruled by automatic bpp.\nNOTE: You need to restart the client.", "8 bpp#16 bpp#32 bpp", SEL_RANGE, 0, 2, 1, 1, &options.video_bpp, VAL_INT}, 00076 {"Textwindows alpha value:", "Transparent value of text windows. Higher = darker", "", SEL_RANGE, 0, 255, 5, 255, &options.textwin_alpha, VAL_INT}, 00077 {"Use intelligent fps cap:", "Enables intelligent fps capping.", "", SEL_CHECKBOX, 0, 1, 1, 1, &options.intelligent_fps_cap, VAL_BOOL}, 00078 {"Save CPU time with sleep():", "Client eats less CPU time when set.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.max_speed, VAL_BOOL}, 00079 {"Sleep time in ms:", "Time the client will sleep. Used with Save CPU time.", "", SEL_RANGE, 0, 1000, 1, 25, &options.sleep, VAL_INT}, 00080 {"Key repeat speed:", "How fast to repeat a held down key.", "Off#Slow#Medium#Fast", SEL_RANGE, 0, 3, 1, 2, &options.key_repeat, VAL_INT}, 00081 {"Disable file updates:", "If on, will not update sound effects/background music/etc on server\nconnect. This may be useful for users with low bandwidth.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.disable_updates, VAL_BOOL}, 00082 {"Minimize latency:", "Disables Nagle's Algorithm in order to minimize latency, at the expense\nof more outgoing bandwidth.\nRequires server re-connection.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.tcp_nodelay, VAL_BOOL}, 00083 {"Allow off-screen widgets:", "Allows moving (parts of) widgets off-screen.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.allow_widgets_offscreen, VAL_BOOL}, 00084 {"#", "", "", 0, 0, 0, 0, 0, 0, 0}, 00085 00086 /* Map */ 00087 {"Player Names:", "Show names of players above their heads.", "show no names#show all names#show only other#show only your", SEL_RANGE, 0, 3,1, 2, &options.player_names, VAL_INT}, 00088 {"Playfield zoom:", "The zoom percentage of the playfield.", "", SEL_RANGE, 50, 200, 5, 100, &options.zoom, VAL_INT}, 00089 {"Smooth zoom:", "Whether to use smooth zoom on the playfield.\nWarning: Very CPU intensive.", "", SEL_CHECKBOX, 0, 1, 1, 1, &options.zoom_smooth, VAL_BOOL}, 00090 {"Low health warning:", "Shows a low health warning above your head.\nActivated if health is less than the given percent value.", "", SEL_RANGE, 0, 100, 5, 0, &options.warning_hp, VAL_INT}, 00091 {"Low food warning:", "Shows a low food warning above your head.\nActivated if food is less than the given percent value.", "", SEL_RANGE, 0, 100, 5, 5, &options.warning_food, VAL_INT}, 00092 {"Map X size:", "The X size of the map. If you have very low bandwidth, you may\nwant to consider lowering this somewhat.", "", SEL_RANGE, 9, MAP_MAX_SIZE, 1, MAP_MAX_SIZE, &options.map_size_x, VAL_INT}, 00093 {"Map Y size:", "The Y size of the map. If you have very low bandwidth, you may\nwant to consider lowering this somewhat.", "", SEL_RANGE, 9, MAP_MAX_SIZE, 1, MAP_MAX_SIZE, &options.map_size_y, VAL_INT}, 00094 {"#", "", "", 0, 0, 0, 0, 0, 0, 0}, 00095 00096 /* Sound */ 00097 {"Sound volume:", "Set sound volume for effects.", "", SEL_RANGE, 0, 100, 5, 100, &options.sound_volume, VAL_INT}, 00098 {"Music volume:", "Set music volume for background.", "", SEL_RANGE, 0, 100, 5, 80, &options.music_volume, VAL_INT}, 00099 {"#", "", "", 0, 0, 0, 0, 0, 0, 0}, 00100 00101 /* Fullscreen Flags */ 00102 {"Hardware Surface:", "Don't change unless you know what you're doing\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.Full_HWSURFACE, VAL_BOOL}, 00103 {"Software Surface:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 1, &options.Full_SWSURFACE, VAL_BOOL}, 00104 {"Hardware Accel:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "",SEL_CHECKBOX, 0, 1, 1, 1, &options.Full_HWACCEL, VAL_BOOL}, 00105 {"Doublebuffer:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "",SEL_CHECKBOX, 0, 1, 1, 0, &options.Full_DOUBLEBUF, VAL_BOOL}, 00106 {"Any format:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "",SEL_CHECKBOX, 0, 1, 1, 1, &options.Full_ANYFORMAT, VAL_BOOL}, 00107 {"Async blit:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "",SEL_CHECKBOX, 0, 1, 1, 0, &options.Full_ASYNCBLIT, VAL_BOOL}, 00108 {"Hardware Palette:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "",SEL_CHECKBOX, 0, 1, 1, 1, &options.Full_HWPALETTE, VAL_BOOL}, 00109 {"Resizeable:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "",SEL_CHECKBOX, 0, 1, 1, 0, &options.Full_RESIZABLE, VAL_BOOL}, 00110 {"No frame:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.Full_NOFRAME, VAL_BOOL}, 00111 {"RLE accel:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 1, &options.Full_RLEACCEL, VAL_BOOL}, 00112 {"#", "", "", 0, 0, 0, 0, 0, 0, 0}, 00113 00114 /* Windowed flags */ 00115 {"Window Hardware Surface:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.Win_HWSURFACE, VAL_BOOL}, 00116 {"Window Software Surface:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 1, &options.Win_SWSURFACE, VAL_BOOL}, 00117 {"Window Hardware Accel:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.Win_HWACCEL, VAL_BOOL}, 00118 {"Window Doublebuffer:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.Win_DOUBLEBUF, VAL_BOOL}, 00119 {"Window Any format:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 1, &options.Win_ANYFORMAT, VAL_BOOL}, 00120 {"Window Async blit:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.Win_ASYNCBLIT, VAL_BOOL}, 00121 {"Window Hardware Palette:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 1, &options.Win_HWPALETTE, VAL_BOOL}, 00122 {"Window Resizeable:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 1, &options.Win_RESIZABLE, VAL_BOOL}, 00123 {"Window No frame:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.Win_NOFRAME, VAL_BOOL}, 00124 {"Window RLE accel:", "Don't change unless you know what you're doing.\nNOTE: You need to restart the client.", "", SEL_CHECKBOX, 0, 1, 1, 1, &options.Win_RLEACCEL, VAL_BOOL}, 00125 {"#", "", "", 0, 0, 0, 0, 0, 0, 0}, 00126 00127 /* Debug */ 00128 {"Show Framerate:", "Show the framerate.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.show_frame, VAL_BOOL}, 00129 {"Force Redraw:", "Forces the system to redraw EVERY frame.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.force_redraw, VAL_BOOL}, 00130 {"Use Update Rect:", "", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.use_rect, VAL_BOOL}, 00131 {"Reload user's graphics", "If on, always try to reload faces from user's graphics (gfx_user)\ndirectory, even if they have been reloaded previously.\nThis is especially useful when creating new images and testing out how\nthey look in the game.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.reload_gfx_user, VAL_BOOL}, 00132 {"Disable region map cache:", "Disables the region maps cache.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.disable_rm_cache, VAL_BOOL}, 00133 {"Enable quickport:", "Enables using middle-click on the region map for instant teleportation.", "", SEL_CHECKBOX, 0, 1, 1, 0, &options.fastport, VAL_BOOL}, 00134 {"#", "", "", 0, 0, 0, 0, 0, 0, 0}, 00135 00136 {0, "", "", 0, 0, 0, 0, 0, 0, 0}, 00137 }; 00138 00144 static char *get_value(void *value, int type) 00145 { 00146 static char txt_value[20]; 00147 00148 switch (type) 00149 { 00150 case VAL_INT: 00151 snprintf(txt_value, sizeof(txt_value), "%d", *((int *) value)); 00152 return txt_value; 00153 00154 case VAL_U32: 00155 snprintf(txt_value, sizeof(txt_value), "%d", *((uint32 *) value)); 00156 return txt_value; 00157 00158 case VAL_CHAR: 00159 snprintf(txt_value, sizeof(txt_value), "%d", *((uint8 *) value)); 00160 return txt_value; 00161 00162 default: 00163 return NULL; 00164 } 00165 } 00166 00171 void optwin_draw_options(int x, int y) 00172 { 00173 #define LEN_NAME 111 00174 int i = -1, pos = 0, max = 0; 00175 /* for info text */ 00176 int y2 = y + 344; 00177 int mxy_opt = -1; 00178 int page = option_list_set.group_nr; 00179 int id = 0; 00180 int mx, my, mb, tmp; 00181 00182 mb = SDL_GetMouseState(&mx, &my) & SDL_BUTTON(SDL_BUTTON_LEFT); 00183 00184 /* Find actual page */ 00185 while (page && opt[++i].name) 00186 { 00187 if (opt[i].name[0] == '#') 00188 { 00189 page--; 00190 } 00191 } 00192 00193 /* Draw actual page */ 00194 while (opt[++i].name && opt[i].name[0] != '#') 00195 { 00196 max++; 00197 StringBlt(ScreenSurface, &SystemFont, opt[i].name, x + 1, y + 3, COLOR_BLACK, NULL, NULL); 00198 00199 switch (opt[i].sel_type) 00200 { 00201 case SEL_CHECKBOX: 00202 tmp = COLOR_WHITE; 00203 00204 if (option_list_set.entry_nr == max - 1) 00205 { 00206 tmp = COLOR_HGOLD; 00207 /* Remember this tab for later use */ 00208 if (mxy_opt == -1) 00209 { 00210 mxy_opt = i; 00211 } 00212 } 00213 00214 if (mx > x && mx < x + 280 && my > y && my < y + 20 ) 00215 { 00216 tmp = COLOR_GREEN; 00217 /* Remember this tab for later use */ 00218 mxy_opt = i; 00219 } 00220 00221 StringBlt(ScreenSurface, &SystemFont, opt[i].name, x, y + 2, tmp, NULL, NULL); 00222 00223 sprite_blt(Bitmaps[BITMAP_DIALOG_CHECKER], x + LEN_NAME, y, NULL, NULL); 00224 00225 if (*((int *) opt[i].value) == 1) 00226 { 00227 StringBlt(ScreenSurface, &SystemFont, "X", x + LEN_NAME + 8, y + 2, COLOR_BLACK, NULL, NULL); 00228 StringBlt(ScreenSurface, &SystemFont, "X", x + LEN_NAME + 7, y + 1, COLOR_WHITE, NULL, NULL); 00229 } 00230 00231 if ((pos == option_list_set.entry_nr && option_list_set.key_change) || (mb && mb_clicked && active_button < 0 && mx > x + LEN_NAME && mx < x + LEN_NAME + 20 && my > y && my < y + 18)) 00232 { 00233 mb_clicked = 0; 00234 option_list_set.key_change = 0; 00235 00236 if (*((int *) opt[i].value) == 1) 00237 { 00238 *((int *) opt[i].value) = 0; 00239 } 00240 else 00241 { 00242 *((int *) opt[i].value) = 1; 00243 } 00244 } 00245 break; 00246 00247 case SEL_RANGE: 00248 { 00249 #define LEN_VALUE 100 00250 SDL_Rect box; 00251 box.x = x + LEN_NAME, box.y = y + 1; 00252 box.h = 16, box.w = LEN_VALUE; 00253 00254 tmp = COLOR_WHITE; 00255 00256 if (option_list_set.entry_nr == max - 1) 00257 { 00258 tmp = COLOR_HGOLD; 00259 00260 /* Remember this tab for later use */ 00261 if (mxy_opt == -1) 00262 { 00263 mxy_opt = i; 00264 } 00265 } 00266 00267 if (mx > x && mx < x + 280 && my > y && my < y + 20) 00268 { 00269 tmp = COLOR_GREEN; 00270 /* Remember this tab for later use */ 00271 mxy_opt = i; 00272 } 00273 00274 StringBlt(ScreenSurface, &SystemFont, opt[i].name, x, y + 2, tmp, NULL, NULL); 00275 SDL_FillRect(ScreenSurface, &box, 0); 00276 00277 if (*opt[i].val_text == '\0') 00278 { 00279 StringBlt(ScreenSurface, &SystemFont, get_value(opt[i].value, opt[i].value_type), box.x + 2, y + 2, COLOR_WHITE, NULL, NULL); 00280 } 00281 else 00282 { 00283 #define MAX_LEN 40 00284 char text[MAX_LEN + 1]; 00285 int o= *((int *) opt[i].value); 00286 int p = 0, q = -1; 00287 00288 /* Find starting position of string */ 00289 while (o && opt[i].val_text[p]) 00290 { 00291 if (opt[i].val_text[p++] == '#') 00292 { 00293 o--; 00294 } 00295 } 00296 00297 /* Find ending position of string */ 00298 while (q++ < MAX_LEN && opt[i].val_text[p]) 00299 { 00300 if ((text[q] = opt[i].val_text[p++]) == '#') 00301 { 00302 break; 00303 } 00304 } 00305 00306 text[q] = '\0'; 00307 StringBlt(ScreenSurface, &SystemFont,text, box.x + 2, y + 2, COLOR_WHITE, NULL, NULL); 00308 #undef MAX_LEN 00309 } 00310 00311 sprite_blt(Bitmaps[BITMAP_DIALOG_RANGE_OFF], x + LEN_NAME + LEN_VALUE, y, NULL, NULL); 00312 00313 /* Keyboard event */ 00314 if (option_list_set.key_change && option_list_set.entry_nr == pos) 00315 { 00316 if (option_list_set.key_change == -1) 00317 { 00318 add_value(opt[i].value, opt[i].value_type,-opt[i].deltaRange, opt[i].minRange, opt[i].maxRange); 00319 } 00320 else if (option_list_set.key_change == 1) 00321 { 00322 add_value(opt[i].value, opt[i].value_type, opt[i].deltaRange, opt[i].minRange, opt[i].maxRange); 00323 } 00324 00325 option_list_set.key_change = 0; 00326 } 00327 00328 if (mx > x + LEN_NAME + LEN_VALUE && mx < x + LEN_NAME + LEN_VALUE + 14 && my > y && my < y + 18) 00329 { 00330 /* 2 buttons per row */ 00331 if (mb && active_button < 0) 00332 { 00333 active_button = id + 1; 00334 } 00335 00336 if (active_button == id + 1) 00337 { 00338 sprite_blt(Bitmaps[BITMAP_DIALOG_RANGE_L], x + LEN_NAME + LEN_VALUE, y, NULL, NULL); 00339 00340 if (!mb) 00341 { 00342 add_value(opt[i].value, opt[i].value_type, -opt[i].deltaRange, opt[i].minRange, opt[i].maxRange); 00343 } 00344 } 00345 } 00346 else if (mx > x + LEN_NAME + LEN_VALUE + 14 && mx < x + LEN_NAME + LEN_VALUE + 28 && my > y && my < y + 18) 00347 { 00348 if (mb && active_button < 0) 00349 { 00350 active_button = id; 00351 } 00352 00353 if (active_button == id) 00354 { 00355 sprite_blt(Bitmaps[BITMAP_DIALOG_RANGE_R], x + LEN_NAME+LEN_VALUE + 14, y, NULL, NULL); 00356 00357 if (!mb) 00358 { 00359 add_value(opt[i].value, opt[i].value_type, opt[i].deltaRange, opt[i].minRange, opt[i].maxRange); 00360 } 00361 } 00362 } 00363 #undef LEN_VALUE 00364 break; 00365 } 00366 00367 case SEL_BUTTON: 00368 sprite_blt(Bitmaps[BITMAP_DIALOG_BUTTON_UP], x, y, NULL, NULL); 00369 break; 00370 } 00371 00372 y += 20; 00373 pos++; 00374 id += 2; 00375 } 00376 00377 if (option_list_set.entry_nr > max - 1) 00378 { 00379 option_list_set.entry_nr = max - 1; 00380 } 00381 00382 /* Print the info text */ 00383 x += 20; 00384 00385 if (mxy_opt >= 0) 00386 { 00387 char *cp, buf[MAX_BUF]; 00388 int y_tmp = 0; 00389 00390 strncpy(buf, opt[mxy_opt].info, sizeof(buf) - 1); 00391 buf[sizeof(buf) - 1] = '\0'; 00392 cp = strtok(buf, "\n"); 00393 00394 while (cp) 00395 { 00396 StringBlt(ScreenSurface, &SystemFont, cp, x + 11, y2 + 1 + y_tmp, COLOR_BLACK, NULL, NULL); 00397 StringBlt(ScreenSurface, &SystemFont, cp, x + 10, y2 + y_tmp, COLOR_WHITE, NULL, NULL); 00398 y_tmp += 12; 00399 cp = strtok(NULL, "\n"); 00400 } 00401 } 00402 #undef LEN_NAME 00403 } 00404 00407 void show_optwin() 00408 { 00409 char buf[128]; 00410 int x, y; 00411 int mx, my, mb; 00412 int numButton = 0; 00413 00414 mb = SDL_GetMouseState(&mx, &my) & SDL_BUTTON(SDL_BUTTON_LEFT); 00415 x = Screensize->x / 2 - Bitmaps[BITMAP_DIALOG_BG]->bitmap->w / 2; 00416 y = Screensize->y / 2 - Bitmaps[BITMAP_DIALOG_BG]->bitmap->h / 2; 00417 sprite_blt(Bitmaps[BITMAP_DIALOG_BG], x, y, NULL, NULL); 00418 sprite_blt(Bitmaps[BITMAP_DIALOG_TITLE_OPTIONS], x + 250 - Bitmaps[BITMAP_DIALOG_TITLE_OPTIONS]->bitmap->w / 2, y + 14, NULL, NULL); 00419 add_close_button(x, y, MENU_OPTION); 00420 00421 draw_tabs(opt_tab, &option_list_set.group_nr, "Option Group", x + 8, y + 70); 00422 optwin_draw_options(x + 130, y + 90); 00423 00424 sprintf(buf, "~SHIFT~ + ~%c%c~ to select group ~%c%c~ to select option ~%c%c~ to change option", ASCII_UP, ASCII_DOWN, ASCII_UP, ASCII_DOWN, ASCII_RIGHT, ASCII_LEFT); 00425 StringBlt(ScreenSurface, &SystemFont, buf, x + 135, y + 410, COLOR_WHITE, NULL, NULL); 00426 00427 /* Mark active entry */ 00428 StringBlt(ScreenSurface, &SystemFont, ">", x + TXT_START_NAME - 15, y + 10 + TXT_Y_START + option_list_set.entry_nr * 20, COLOR_HGOLD, NULL, NULL); 00429 00430 /* save button */ 00431 if (add_button(x + 25, y + 454, numButton++, BITMAP_DIALOG_BUTTON_UP, "Done", "~D~one")) 00432 { 00433 check_menu_keys(MENU_OPTION, SDLK_d); 00434 } 00435 00436 if (!mb) 00437 { 00438 active_button = -1; 00439 } 00440 } 00441 00443 enum 00444 { 00445 BUTTON_SETTINGS, 00446 BUTTON_KEY_SETTINGS, 00447 BUTTON_LOGOUT, 00448 BUTTON_BACK, 00449 00450 BUTTON_NUM 00451 }; 00452 00454 static const char *const button_names[BUTTON_NUM] = 00455 { 00456 "Client Settings", "Key settings", "Logout", "Back to play" 00457 }; 00458 00460 static size_t button_selected; 00461 00465 static void settings_popup_draw_func(popup_struct *popup) 00466 { 00467 SDL_Rect box; 00468 size_t i; 00469 int x, y, mx, my; 00470 char buf[MAX_BUF]; 00471 uint64 flags; 00472 00473 box.x = 0; 00474 box.y = 10; 00475 box.w = popup->surface->w; 00476 box.h = 0; 00477 string_blt(popup->surface, FONT_SERIF20, "<u>Settings</u>", box.x, box.y, COLOR_SIMPLE(COLOR_HGOLD), TEXT_ALIGN_CENTER | TEXT_MARKUP, &box); 00478 box.y += 50; 00479 00480 SDL_GetMouseState(&mx, &my); 00481 00482 for (i = 0; i < BUTTON_NUM; i++) 00483 { 00484 if (GameStatus != GAME_STATUS_PLAY && (i == BUTTON_BACK || i == BUTTON_LOGOUT)) 00485 { 00486 continue; 00487 } 00488 00489 flags = TEXT_ALIGN_CENTER; 00490 x = Screensize->x / 2 - popup->surface->w / 2 + box.x; 00491 y = Screensize->y / 2 - popup->surface->h / 2 + box.y; 00492 00493 if (mx >= x && mx < x + popup->surface->w && my >= y && my < y + FONT_HEIGHT(FONT_SERIF40)) 00494 { 00495 snprintf(buf, sizeof(buf), "<u>%s</u>", button_names[i]); 00496 flags |= TEXT_MARKUP; 00497 } 00498 else 00499 { 00500 strncpy(buf, button_names[i], sizeof(buf) - 1); 00501 buf[sizeof(buf) - 1] = '\0'; 00502 } 00503 00504 if (button_selected == i) 00505 { 00506 string_blt_shadow_format(popup->surface, FONT_SERIF40, box.x, box.y, COLOR_SIMPLE(COLOR_HGOLD), COLOR_SIMPLE(COLOR_BLACK), flags | TEXT_MARKUP, &box, "<c=#9f0408>></c> %s <c=#9f0408><</c>", buf); 00507 } 00508 else 00509 { 00510 00511 string_blt_shadow(popup->surface, FONT_SERIF40, buf, box.x, box.y, COLOR_SIMPLE(COLOR_WHITE), COLOR_SIMPLE(COLOR_BLACK), flags, &box); 00512 } 00513 00514 box.y += FONT_HEIGHT(FONT_SERIF40); 00515 } 00516 } 00517 00521 static void settings_button_handle(size_t button) 00522 { 00523 if (button == BUTTON_KEY_SETTINGS) 00524 { 00525 keybind_status = KEYBIND_STATUS_NO; 00526 cpl.menustatus = MENU_KEYBIND; 00527 } 00528 else if (button == BUTTON_SETTINGS) 00529 { 00530 cpl.menustatus = MENU_OPTION; 00531 } 00532 else if (button == BUTTON_LOGOUT) 00533 { 00534 socket_close(&csocket); 00535 GameStatus = GAME_STATUS_INIT; 00536 } 00537 00538 popup_destroy_visible(); 00539 } 00540 00543 static int settings_popup_event_func(popup_struct *popup, SDL_Event *event) 00544 { 00545 if (event->type == SDL_KEYDOWN) 00546 { 00547 /* Move the selected button up and down. */ 00548 if (event->key.keysym.sym == SDLK_UP || event->key.keysym.sym == SDLK_DOWN) 00549 { 00550 int selected = button_selected, num_buttons; 00551 00552 selected += event->key.keysym.sym == SDLK_DOWN ? 1 : -1; 00553 num_buttons = (GameStatus == GAME_STATUS_PLAY ? BUTTON_NUM : BUTTON_LOGOUT) - 1; 00554 00555 if (selected < 0) 00556 { 00557 selected = num_buttons; 00558 } 00559 else if (selected > num_buttons) 00560 { 00561 selected = 0; 00562 } 00563 00564 button_selected = selected; 00565 return 1; 00566 } 00567 else if (event->key.keysym.sym == SDLK_RETURN || event->key.keysym.sym == SDLK_KP_ENTER) 00568 { 00569 settings_button_handle(button_selected); 00570 return 1; 00571 } 00572 } 00573 else if (event->type == SDL_MOUSEBUTTONDOWN) 00574 { 00575 if (event->button.button == SDL_BUTTON_LEFT) 00576 { 00577 int x, y; 00578 size_t i; 00579 00580 x = Screensize->x / 2 - popup->surface->w / 2; 00581 y = Screensize->y / 2 - popup->surface->h / 2 + 60; 00582 00583 for (i = 0; i < BUTTON_NUM; i++) 00584 { 00585 if (event->motion.x >= x && event->motion.x < x + popup->surface->w && event->motion.y >= y && event->motion.y < y + FONT_HEIGHT(FONT_SERIF40)) 00586 { 00587 settings_button_handle(i); 00588 break; 00589 } 00590 00591 y += FONT_HEIGHT(FONT_SERIF40); 00592 } 00593 } 00594 } 00595 00596 return -1; 00597 } 00598 00601 void settings_open() 00602 { 00603 popup_struct *popup; 00604 00605 popup = popup_create(BITMAP_POPUP); 00606 popup->draw_func = settings_popup_draw_func; 00607 popup->event_func = settings_popup_event_func; 00608 00609 button_selected = GameStatus == GAME_STATUS_PLAY ? BUTTON_BACK : BUTTON_SETTINGS; 00610 }
1.7.4