/* Copyright (C) 2011 azazello and ezQuake team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ // // HUD commands // #include "ezquakeisms.h" //#include "common_draw.h" //#include "keys.h" #include "hud.h" #include "hud_common.h" #include "hud_editor.h" //#include "utils.h" //#include "sbar.h" #define sbar_last_width 320 // yeah yeah I know, *garbage* -> leave it be :> char *align_strings_x[] = { "left", "center", "right", "before", "after" }; #define num_align_strings_x (sizeof(align_strings_x) / sizeof(align_strings_x[0])) char *align_strings_y[] = { "top", "center", "bottom", "before", "after", "console" }; #define num_align_strings_y (sizeof(align_strings_y) / sizeof(align_strings_y[0])) char *snap_strings[] = { "screen", "top", "view", "sbar", "ibar", "hbar", "sfree", "ifree", "hfree", }; #define num_snap_strings (sizeof(snap_strings) / sizeof(snap_strings[0])) // Hud elements list. hud_t *hud_huds = NULL; qbool doreorder; // // Hud plus func - show element. // void HUD_Plus_f(void) { char *t; hud_t *hud; if (Cmd_Argc() < 1) return; t = Cmd_Argv(0); if (strncmp(t, "+hud_", 5)) return; hud = HUD_Find(t + 5); if (!hud) { // This should never happen... return; } if (!hud->show) { // This should never happen... return; } Cvar_Set(hud->show, "1"); } // // Hud minus func - hide element. // void HUD_Minus_f(void) { char *t; hud_t *hud; if (Cmd_Argc() < 1) return; t = Cmd_Argv(0); if (strncmp(t, "-hud_", 5)) return; hud = HUD_Find(t + 5); if (!hud) { // this should never happen... return; } if (!hud->show) { // this should never happen... return; } Cvar_Set(hud->show, "0"); } // // Hud element func - describe it // this also solves the TAB completion problem // void HUD_Func_f(void) { int i; hud_t *hud; hud = HUD_Find(Cmd_Argv(0)); if (!hud) { // This should never happen... Com_Printf("Hud element not found\n"); return; } if (Cmd_Argc() > 1) { char buf[512]; snprintf(buf, sizeof(buf), "hud_%s_%s", hud->name, Cmd_Argv(1)); if (Cvar_Find(buf) != NULL) { Cbuf_AddText(buf); if (Cmd_Argc() > 2) { Cbuf_AddText(" "); Cbuf_AddText(Cmd_Argv(2)); } Cbuf_AddText("\n"); } else { Com_Printf("Trying \"%s\" - no such variable\n", buf); } return; } // Description. Com_Printf("%s\n\n", hud->description); // Status. if (hud->show != NULL) { Com_Printf("Current status: %s\n", hud->show->value ? "shown" : "hidden"); } if (hud->frame != NULL) { Com_Printf("Frame: %s\n\n", hud->frame->string); } if (hud->frame_color != NULL) { Com_Printf("Frame color: %s\n\n", hud->frame_color->string); } // Placement. Com_Printf("Placement: %s\n", hud->place->string); // Alignment. Com_Printf("Alignment (x y): %s %s\n", hud->align_x->string, hud->align_y->string); // Position. Com_Printf("Offset (x y): %d %d\n", (int)(hud->pos_x->value), (int)(hud->pos_y->value)); // Ordering. Com_Printf("Draw Order (z): %d\n", (int)hud->order->value); // Additional parameters. if (hud->num_params > 0) { int prefix_l = strlen(va("hud_%s_", hud->name)); Com_Printf("\nParameters:\n"); for (i=0; i < hud->num_params; i++) { if (strlen(hud->params[i]->name) > prefix_l) Com_Printf(" %-15s %s\n", hud->params[i]->name + prefix_l, hud->params[i]->string); } } } // // Find the elements with the max and min z-order. // void HUD_FindMaxMinOrder(int *max, int *min) { hud_t *hud = hud_huds; while(hud) { (*min) = ((int)hud->order->value < (*min)) ? (int)hud->order->value : (*min); (*max) = ((int)hud->order->value > (*max)) ? (int)hud->order->value : (*max); hud = hud->next; } } // // Find hud placement by string // return 0 if error // int HUD_FindPlace(hud_t *hud) { int i; hud_t *par; qbool out; char *t; // First try standard strings. for (i=0; i < num_snap_strings; i++) { if (!strcasecmp(hud->place->string, snap_strings[i])) { break; } } if (i < num_snap_strings) { // Found. hud->place_num = i+1; hud->place_hud = NULL; return 1; } // then try another HUD element out = true; t = hud->place->string; if (hud->place->string[0] == '@') { // place inside out = false; t++; } par = hud_huds; while (par) { if (par != hud && !strcmp(t, par->name)) { hud->place_outside = out; hud->place_hud = par; hud->place_num = HUD_PLACE_SCREEN; return 1; } par = par->next; } // No way. hud->place_num = HUD_PLACE_SCREEN; hud->place_hud = NULL; return 0; } // // Find hud alignment by strings // return 0 if error // int HUD_FindAlignX(hud_t *hud) { int i; // First try standard strings. for (i=0; i < num_align_strings_x; i++) { if (!strcasecmp(hud->align_x->string, align_strings_x[i])) { break; } } if (i < num_align_strings_x) { // Found. hud->align_x_num = i+1; return 1; } else { // Error. hud->align_x_num = HUD_ALIGN_LEFT; // left return 0; } } // // Find the alignment for a hud element. // int HUD_FindAlignY(hud_t *hud) { int i; // First try standard strings. for (i=0; i < num_align_strings_y; i++) { if (!strcasecmp(hud->align_y->string, align_strings_y[i])) { break; } } if (i < num_align_strings_y) { // Found. hud->align_y_num = i + 1; return 1; } else { // Error. hud->align_y_num = HUD_ALIGN_TOP; // Left. return 0; } } int Hud_HudCompare (const void *p1, const void *p2) { return strcmp((*((hud_t **) p1))->name, (*((hud_t **) p2))->name); } // // List hud elements // void HUD_List (void) { static hud_t *sorted_huds[256]; int i, count; hud_t *hud; #define MAX_SORTED_HUDS (sizeof (sorted_huds) / sizeof (sorted_huds[0])) for (hud = hud_huds, count = 0; hud && count < MAX_SORTED_HUDS; hud = hud->next, count++) sorted_huds[count] = hud; qsort (sorted_huds, count, sizeof (hud_t *), Hud_HudCompare); if (count == MAX_SORTED_HUDS) assert(!"count == MAX_SORTED_HUDS"); Com_Printf("name status\n"); Com_Printf("--------------- ------\n"); for (i = 0; i < count; i++) { hud = sorted_huds[i]; Com_Printf("%-15s %s\n", hud->name, hud->show->value ? "shown" : "hidden"); } } // // Show the specified hud element. // void HUD_Show_f (void) { hud_t *hud; if (Cmd_Argc() != 2) { Com_Printf("Usage: show [ | all]\n"); Com_Printf("Show given HUD element.\n"); Com_Printf("use \"show all\" to show all elements.\n"); Com_Printf("Current elements status:\n\n"); HUD_List(); return; } if (!strcasecmp(Cmd_Argv(1), "all")) { hud = hud_huds; while (hud) { Cvar_SetValue(hud->show, 1); hud = hud->next; } } else { hud = HUD_Find(Cmd_Argv(1)); if (!hud) { Com_Printf("No such element: %s\n", Cmd_Argv(1)); return; } Cvar_SetValue(hud->show, 1); } } // // Hide the specified hud element. // void HUD_Hide_f (void) { hud_t *hud; if (Cmd_Argc() != 2) { Com_Printf("Usage: hide [ | all]\n"); Com_Printf("Hide given HUD element\n"); Com_Printf("use \"hide all\" to hide all elements.\n"); Com_Printf("Current elements status:\n\n"); HUD_List(); return; } if (!strcasecmp(Cmd_Argv(1), "all")) { hud = hud_huds; while (hud) { Cvar_SetValue(hud->show, 0); hud = hud->next; } } else { hud = HUD_Find(Cmd_Argv(1)); if (!hud) { Com_Printf("No such element: %s\n", Cmd_Argv(1)); return; } Cvar_SetValue(hud->show, 0); } } // // Toggles specified hud element. // void HUD_Toggle_f (void) { hud_t *hud; if (Cmd_Argc() != 2) { Com_Printf("Usage: togglehud | \n"); Com_Printf("Show/hide given HUD element, or toggles variable value.\n"); return; } hud = HUD_Find(Cmd_Argv(1)); if (!hud) { // look for cvar cvar_t *var = Cvar_Find(Cmd_Argv(1)); if (!var) { Com_Printf("No such element or variable: %s\n", Cmd_Argv(1)); return; } Cvar_Set (var, var->value ? "0" : "1"); return; } Cvar_Set (hud->show, hud->show->value ? "0" : "1"); } // // Move the specified hud element relative to placement/alignment. // void HUD_Move_f (void) { hud_t *hud; if (Cmd_Argc() != 4 && Cmd_Argc() != 2) { Com_Printf("Usage: move [ ]\n"); Com_Printf("Set offset for given HUD element\n"); return; } hud = HUD_Find(Cmd_Argv(1)); if (!hud) { Com_Printf("No such element: %s\n", Cmd_Argv(1)); return; } if (Cmd_Argc() == 2) { Com_Printf("Current %s offset is:\n", Cmd_Argv(1)); Com_Printf(" x: %s\n", hud->pos_x->string); Com_Printf(" y: %s\n", hud->pos_y->string); return; } Cvar_SetValue(hud->pos_x, atof(Cmd_Argv(2))); Cvar_SetValue(hud->pos_y, atof(Cmd_Argv(3))); } // // Resets a hud item to the center of the screen. // void HUD_Reset_f (void) { hud_t *hud = NULL; char *hudname = NULL; if (Cmd_Argc() != 2) { Com_Printf("Usage: reset \n"); Com_Printf("Resets the position of the given HUD element to the center of the screen.\n"); return; } hudname = Cmd_Argv(1); hud = HUD_Find(hudname); if (!hud) { Com_Printf("No such HUD element %s.\n", hudname); return; } Cbuf_AddText(va("place %s screen\n", hudname)); Cbuf_AddText(va("move %s 0 0\n", hudname)); Cbuf_AddText(va("align %s center center\n", hudname)); } // // Reorders children so that they are place infront of their parent. // void HUD_ReorderChildren(void) { hud_t *hud = hud_huds; // Give all children a higher Z-order. while(hud) { if(hud->place_hud && hud->order->value <= hud->place_hud->order->value) { Cvar_SetValue(hud->order, hud->place_hud->order->value + 1); } hud = hud->next; } } // // Place the specified hud element. // void HUD_Place_f (void) { hud_t *hud; char temp[512]; if (Cmd_Argc() < 2 || Cmd_Argc() > 3) { Com_Printf("Usage: move []\n"); Com_Printf("Place HUD element at given area.\n"); Com_Printf("\nPossible areas are:\n"); Com_Printf(" screen - screen area\n"); Com_Printf(" top - screen minus status bar\n"); Com_Printf(" view - view\n"); Com_Printf(" sbar - status bar\n"); Com_Printf(" ibar - inventory bar\n"); Com_Printf(" hbar - health bar\n"); Com_Printf(" sfree - status bar free area\n"); Com_Printf(" ifree - inventory bar free area\n"); Com_Printf(" hfree - health bar free area\n"); Com_Printf("You can also use any other HUD element as a base alignment. In such case you should specify area as:\n"); Com_Printf(" @elem - if you want to place\n"); Com_Printf(" it inside elem\n"); Com_Printf(" elem - if you want to place\n"); Com_Printf(" it outside elem\n"); Com_Printf("Examples:\n"); Com_Printf(" place fps view\n"); Com_Printf(" place fps @ping\n"); return; } hud = HUD_Find(Cmd_Argv(1)); if (!hud) { Com_Printf("No such element: %s\n", Cmd_Argv(1)); return; } if (Cmd_Argc() == 2) { Com_Printf("Current %s placement: %s\n", hud->name, hud->place->string); return; } // Place with helper. strlcpy(temp, hud->place->string, sizeof(temp)); Cvar_Set(hud->place, Cmd_Argv(2)); if (!HUD_FindPlace(hud)) { Com_Printf("place: invalid area argument: %s\n", Cmd_Argv(2)); Cvar_Set(hud->place, temp); // Restore old value. } else { HUD_ReorderChildren(); } } // // Sets the z-order of a HUD element. // void HUD_Order_f (void) { int max = 0; int min = 0; char *option = NULL; hud_t *hud = NULL; if (Cmd_Argc() < 2 || Cmd_Argc() > 3) { Com_Printf("Usage: order [