ui_main.c

Go to the documentation of this file.
00001 
00005 /*
00006 Copyright (C) 2002-2010 UFO: Alien Invasion.
00007 
00008 This program is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU General Public License
00010 as published by the Free Software Foundation; either version 2
00011 of the License, or (at your option) any later version.
00012 
00013 This program is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016 
00017 See the 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00023 */
00024 
00025 #include "ui_main.h"
00026 #include "ui_internal.h"
00027 #include "ui_draw.h"
00028 #include "ui_timer.h"
00029 #include "ui_font.h"
00030 #include "ui_sound.h"
00031 
00032 #include "../client.h"
00033 
00035 cvar_t *mn_sequence;
00036 cvar_t *mn_hud;
00037 
00038 uiGlobal_t ui_global;
00039 
00040 struct memPool_s *ui_dynStringPool;
00041 struct memPool_s *ui_dynPool;
00042 struct memPool_s *ui_sysPool;
00043 
00044 #ifdef DEBUG
00045 static cvar_t *ui_debug;
00046 #endif
00047 
00052 static void UI_CheckCvar (const cvar_t *cvar)
00053 {
00054     if (cvar->modified) {
00055         if (cvar->flags & CVAR_R_CONTEXT) {
00056             UI_DisplayNotice(_("This change requires a restart"), 2000, NULL);
00057         } else if (cvar->flags & CVAR_R_IMAGES) {
00058             UI_DisplayNotice(_("This change might require a restart"), 2000, NULL);
00059         }
00060     }
00061 }
00062 
00067 int UI_DebugMode (void)
00068 {
00069 #ifdef DEBUG
00070     return ui_debug->integer;
00071 #else
00072     return 0;
00073 #endif
00074 }
00075 
00082 void UI_SetCvar (const char *name, const char *str, float value)
00083 {
00084     const cvar_t *cvar;
00085     cvar = Cvar_FindVar(name);
00086     if (!cvar) {
00087         Com_Printf("Could not find cvar '%s'\n", name);
00088         return;
00089     }
00090     if (str)
00091         Cvar_Set(cvar->name, str);
00092     else
00093         Cvar_SetValue(cvar->name, value);
00094     UI_CheckCvar(cvar);
00095 }
00096 
00102 static void UI_Modify_f (void)
00103 {
00104     float value;
00105 
00106     if (Cmd_Argc() < 5)
00107         Com_Printf("Usage: %s <name> <amount> <min> <max>\n", Cmd_Argv(0));
00108 
00109     value = Cvar_GetValue(Cmd_Argv(1));
00110     value += atof(Cmd_Argv(2));
00111     if (value < atof(Cmd_Argv(3)))
00112         value = atof(Cmd_Argv(3));
00113     else if (value > atof(Cmd_Argv(4)))
00114         value = atof(Cmd_Argv(4));
00115 
00116     Cvar_SetValue(Cmd_Argv(1), value);
00117 }
00118 
00126 static void UI_ModifyWrap_f (void)
00127 {
00128     float value;
00129 
00130     if (Cmd_Argc() < 5) {
00131         Com_Printf("Usage: %s <name> <amount> <min> <max>\n", Cmd_Argv(0));
00132         return;
00133     }
00134 
00135     value = Cvar_GetValue(Cmd_Argv(1));
00136     value += atof(Cmd_Argv(2));
00137     if (value < atof(Cmd_Argv(3)))
00138         value = atof(Cmd_Argv(4));
00139     else if (value > atof(Cmd_Argv(4)))
00140         value = atof(Cmd_Argv(3));
00141 
00142     Cvar_SetValue(Cmd_Argv(1), value);
00143 }
00144 
00149 static void UI_Translate_f (void)
00150 {
00151     const char *current, *list;
00152     char original[MAX_VAR], translation[MAX_VAR];
00153 
00154     if (Cmd_Argc() < 4) {
00155         Com_Printf("Usage: %s <source> <dest> <list>\n", Cmd_Argv(0));
00156         return;
00157     }
00158 
00159     current = Cvar_GetString(Cmd_Argv(1));
00160     list = Cmd_Argv(3);
00161 
00162     while (list[0] != '\0') {
00163         char *trans;
00164         char *orig = original;
00165         while (list[0] != '\0' && list[0] != ':') {
00167             *orig++ = *list++;
00168         }
00169         *orig = '\0';
00170         list++;
00171 
00172         trans = translation;
00173         while (list[0] != '\0' && list[0] != ',') {
00175             *trans++ = *list++;
00176         }
00177         *trans = '\0';
00178         list++;
00179 
00180         if (!strcmp(current, original)) {
00181             Cvar_Set(Cmd_Argv(2), _(translation));
00182             return;
00183         }
00184     }
00185 
00186     if (current[0] != '\0') {
00187         /* nothing found, copy value */
00188         Cvar_Set(Cmd_Argv(2), _(current));
00189     } else {
00190         Cvar_Set(Cmd_Argv(2), "");
00191     }
00192 }
00193 
00194 #ifdef DEBUG
00195 
00199 static void UI_Memory_f (void)
00200 {
00201     int i;
00202     const size_t nodeSize = sizeof(uiNode_t);
00203     size_t size;
00204     Com_Printf("Allocation:\n");
00205     Com_Printf("\t-Window allocation: %i/%i\n", ui_global.numWindows, UI_MAX_WINDOWS);
00206     Com_Printf("\t-Rendering window stack slot: %i\n", UI_MAX_WINDOWSTACK);
00207     Com_Printf("\t-Action allocation: %i/%i\n", ui_global.numActions, UI_MAX_ACTIONS);
00208     Com_Printf("\t-Model allocation: %i/%i\n", ui_global.numModels, UI_MAX_MODELS);
00209     Com_Printf("\t-Exclude rect allocation: %i/%i\n", ui_global.numExcludeRect, UI_MAX_EXLUDERECTS);
00210     Com_Printf("\t -Node allocation: %i\n", ui_global.numNodes);
00211 
00212     Com_Printf("Memory:\n");
00213     Com_Printf("\t-Action structure size: "UFO_SIZE_T" B\n", sizeof(uiAction_t));
00214     Com_Printf("\t-Model structure size: "UFO_SIZE_T" B\n", sizeof(uiModel_t));
00215     Com_Printf("\t-Node structure size: "UFO_SIZE_T" B x%d\n", sizeof(uiNode_t), ui_global.numNodes);
00216     for (i = 0; i < UI_GetNodeBehaviourCount(); i++) {
00217         uiBehaviour_t *b = UI_GetNodeBehaviourByIndex(i);
00218         Com_Printf("\t -Behaviour %20s structure size: "UFO_SIZE_T" (+"UFO_SIZE_T" B) x%4u\n", b->name, sizeof(uiNode_t) + b->extraDataSize, b->extraDataSize, b->count);
00219     }
00220 
00221     size = 0;
00222     for (i = 0; i < UI_GetNodeBehaviourCount(); i++) {
00223         uiBehaviour_t *b = UI_GetNodeBehaviourByIndex(i);
00224         size += nodeSize * b->count + b->extraDataSize * b->count;
00225     }
00226     Com_Printf("Global memory:\n");
00227     Com_Printf("\t-System pool: %ui B\n", _Mem_PoolSize(ui_sysPool));
00228     Com_Printf("\t -AData allocation: "UFO_SIZE_T"/%i B\n", (ptrdiff_t)(ui_global.curadata - ui_global.adata), ui_global.adataize);
00229     Com_Printf("\t -AData used by nodes: "UFO_SIZE_T" B\n", size);
00230     Com_Printf("\t-Dynamic node/data pool: %ui B\n", _Mem_PoolSize(ui_dynPool));
00231     Com_Printf("\t-Dynamic strings pool: %ui B\n", _Mem_PoolSize(ui_dynStringPool));
00232 
00233     size = _Mem_PoolSize(ui_sysPool) + _Mem_PoolSize(ui_dynPool) + _Mem_PoolSize(ui_dynStringPool);
00234     Com_Printf("\t-Full size: "UFO_SIZE_T" B\n", size);
00235 }
00236 #endif
00237 
00238 #define MAX_CONFUNC_SIZE 512
00239 
00244 void UI_ExecuteConfunc (const char *fmt, ...)
00245 {
00246     va_list ap;
00247     char confunc[MAX_CONFUNC_SIZE];
00248 
00249     va_start(ap, fmt);
00250     Q_vsnprintf(confunc, sizeof(confunc), fmt, ap);
00251     Cmd_ExecuteString(confunc);
00252     va_end(ap);
00253 }
00254 
00258 void UI_Reinit (void)
00259 {
00260     UI_InitFonts();
00261     UI_ReleaseInput();
00262     UI_InvalidateMouse();
00263 }
00264 
00272 void UI_Shutdown (void)
00273 {
00274     int i;
00275     const uiBehaviour_t *confunc;
00276 
00277     /* MN is not yet initialized */
00278     if (ui_global.adata == NULL)
00279         return;
00280 
00281     confunc = UI_GetNodeBehaviour("confunc");
00282 
00283     /* remove all confunc commands */
00284     for (i = 0; i < ui_global.numWindows; i++) {
00285         uiNode_t *node = ui_global.windows[i];
00286         while (node) {
00287 
00288             /* remove the command */
00289             if (node->behaviour == confunc) {
00290                 /* many nodes to one command is allowed */
00291                 if (Cmd_Exists(node->name))
00292                     Cmd_RemoveCommand(node->name);
00293             }
00294 
00295             /* recursive next */
00296             if (node->firstChild != NULL)
00297                 node = node->firstChild;
00298             else {
00299                 while (node) {
00300                     if (node->next != NULL) {
00301                         node = node->next;
00302                         break;
00303                     }
00304                     node = node->parent;
00305                 }
00306             }
00307         }
00308     }
00309 
00310     if (ui_global.adataize)
00311         Mem_Free(ui_global.adata);
00312     ui_global.adata = NULL;
00313     ui_global.adataize = 0;
00314 
00315     /* release pools */
00316     Mem_FreePool(ui_sysPool);
00317     Mem_FreePool(ui_dynStringPool);
00318     Mem_FreePool(ui_dynPool);
00319     ui_sysPool = NULL;
00320     ui_dynStringPool = NULL;
00321     ui_dynPool = NULL;
00322 }
00323 
00324 #define UI_HUNK_SIZE 2*1024*1024
00325 
00326 void UI_Init (void)
00327 {
00328 #ifdef DEBUG
00329     ui_debug = Cvar_Get("debug_ui", "0", CVAR_DEVELOPER, "Prints node names for debugging purposes - valid values are 1 and 2");
00330 #endif
00331 
00332     /* reset global UI structures */
00333     memset(&ui_global, 0, sizeof(ui_global));
00334 
00335     /* add cvars */
00337     mn_sequence = Cvar_Get("mn_sequence", "sequence", 0, "This is the sequence window to render the sequence in");
00339     mn_hud = Cvar_Get("mn_hud", "hud", CVAR_ARCHIVE | CVAR_LATCH, "This is the current selected HUD");
00340 
00341     ui_sounds = Cvar_Get("ui_sounds", "1", CVAR_ARCHIVE, "Activates UI sounds");
00342 
00343     /* add global UI commands */
00344     Cmd_AddCommand("mn_modify", UI_Modify_f, NULL);
00345     Cmd_AddCommand("mn_modifywrap", UI_ModifyWrap_f, NULL);
00346     Cmd_AddCommand("mn_translate", UI_Translate_f, NULL);
00347 #ifdef DEBUG
00348     Cmd_AddCommand("debug_mnmemory", UI_Memory_f, "Display info about UI memory allocation");
00349 #endif
00350 
00351     ui_sysPool = Mem_CreatePool("Client: UI");
00352     ui_dynStringPool = Mem_CreatePool("Client: Dynamic string for UI");
00353     ui_dynPool = Mem_CreatePool("Client: Dynamic memory for UI");
00354 
00355     /* 256kb */
00356     ui_global.adataize = UI_HUNK_SIZE;
00357     ui_global.adata = (byte*)Mem_PoolAlloc(ui_global.adataize, ui_sysPool, 0);
00358     ui_global.curadata = ui_global.adata;
00359 
00360     UI_InitData();
00361     UI_InitNodes();
00362     UI_InitWindows();
00363     UI_InitDraw();
00364     UI_InitActions();
00365 }

Generated by  doxygen 1.6.2