From 715f34e831826b6d76c9c4e381c401002b151c35 Mon Sep 17 00:00:00 2001 From: Spoike Date: Mon, 8 Jan 2007 03:13:03 +0000 Subject: [PATCH] Added 'combo' menu script commands (one var, multiple descrete values). git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2461 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/m_items.c | 123 +++++++++++++++++++++++++++++++-------- engine/client/m_script.c | 115 +++++++++++++++++++++++++++++++++++- 2 files changed, 214 insertions(+), 24 deletions(-) diff --git a/engine/client/m_items.c b/engine/client/m_items.c index f6607f0f2..8e951785e 100644 --- a/engine/client/m_items.c +++ b/engine/client/m_items.c @@ -402,9 +402,18 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu) int x = xpos+option->common.posx; int y = ypos+option->common.posy; - Draw_String(x, y, option->combo.caption); + if (!menu->cursoritem && menu->selecteditem == option) + Draw_Alt_String(x, y, option->combo.caption); + else + Draw_String(x, y, option->combo.caption); x += strlen(option->combo.caption)*8+24; - Draw_String(x, y, option->combo.options[option->combo.selectedoption]); + if (option->combo.numoptions) + { + if (!menu->cursoritem && menu->selecteditem == option) + Draw_Alt_String(x, y, option->combo.options[option->combo.selectedoption]); + else + Draw_String(x, y, option->combo.options[option->combo.selectedoption]); + } } break; case mt_custom: @@ -759,25 +768,52 @@ menuslider_t *MC_AddSlider(menu_t *menu, int x, int y, const char *text, cvar_t menucombo_t *MC_AddCombo(menu_t *menu, int x, int y, const char *caption, const char **ops, int initialvalue) { - menucombo_t *n = Z_Malloc(sizeof(menucombo_t)); + int numopts; + int optlen; + int maxoptlen; + int optbufsize; + menucombo_t *n; + char **newops; + char *optbuf; + int i; + + maxoptlen = 0; + optbufsize = sizeof(char*); + numopts = 0; + optlen = 0; + while(ops[numopts]) + { + optlen = strlen(ops[numopts]); + if (maxoptlen < optlen) + maxoptlen = optlen; + optbufsize += optlen+1+sizeof(char*); + numopts++; + } + + + n = Z_Malloc(sizeof(*n) + optbufsize); + newops = (char **)(n+1); + optbuf = (char*)(newops + numopts+1); n->common.type = mt_combo; n->common.iszone = true; n->common.posx = x; n->common.posy = y; n->common.height = 8; - n->common.width = strlen(caption)*8; + n->common.width = strlen(caption)*8 + maxoptlen*8; n->caption = caption; - n->options = ops; + n->options = newops; n->common.next = menu->options; menu->options = (menuoption_t *)n; - n->numoptions = 0; - while(ops[n->numoptions]) + n->numoptions = numopts; + for (i = 0; i < numopts; i++) { - n->common.width = strlen(caption)*8+strlen(ops[n->numoptions])*8; - n->numoptions++; + strcpy(optbuf, ops[i]); + newops[i] = optbuf; + optbuf += strlen(optbuf)+1; } + newops[i] = NULL; if (initialvalue >= n->numoptions) { @@ -790,34 +826,75 @@ menucombo_t *MC_AddCombo(menu_t *menu, int x, int y, const char *caption, const } menucombo_t *MC_AddCvarCombo(menu_t *menu, int x, int y, const char *caption, cvar_t *cvar, const char **ops, const char **values) { - menucombo_t *n = Z_Malloc(sizeof(menucombo_t)); + int numopts; + int optlen; + int maxoptlen; + int optbufsize; + menucombo_t *n; + char **newops; + char **newvalues; + char *optbuf; + int i; + + maxoptlen = 0; + optbufsize = sizeof(char*)*2 + strlen(caption)+1; + numopts = 0; + optlen = 0; + while(ops[numopts]) + { + optlen = strlen(ops[numopts]); + if (maxoptlen < optlen) + maxoptlen = optlen; + optbufsize += optlen+1+sizeof(char*); + optbufsize += strlen(values[numopts])+1+sizeof(char*); + numopts++; + } + + + + n = Z_Malloc(sizeof(*n) + optbufsize); + newops = (char **)(n+1); + newvalues = (char**)(newops + numopts+1); + optbuf = (char*)(newvalues + numopts+1); n->common.type = mt_combo; n->common.iszone = true; n->common.posx = x; n->common.posy = y; n->common.height = 8; - n->common.width = strlen(caption)*8; - n->caption = caption; - n->options = ops; - n->values = values; + n->common.width = strlen(caption)*8 + maxoptlen*8; + + strcpy(optbuf, caption); + n->caption = optbuf; + optbuf += strlen(optbuf)+1; + + n->options = newops; + n->values = newvalues; n->cvar = cvar; - if (!(cvar->flags & CVAR_ARCHIVE)) - Con_Printf("Warning: %s is not set for archiving\n", cvar->name); +// if (!(cvar->flags & CVAR_ARCHIVE)) +// Con_Printf("Warning: %s is not set for archiving\n", cvar->name); n->selectedoption = 0; n->common.next = menu->options; menu->options = (menuoption_t *)n; - n->numoptions = 0; - while(ops[n->numoptions]) + n->numoptions = numopts; + for (i = 0; i < numopts; i++) { - if (!strcmp(values[n->numoptions], cvar->string)) - n->selectedoption = n->numoptions; - n->common.width = strlen(caption)*8+strlen(ops[n->numoptions])*8; - n->numoptions++; + if (!strcmp(values[i], cvar->string)) + n->selectedoption = i; + + strcpy(optbuf, ops[i]); + newops[i] = optbuf; + optbuf += strlen(optbuf)+1; + + strcpy(optbuf, values[i]); + newvalues[i] = optbuf; + optbuf += strlen(optbuf)+1; } + newops[i] = NULL; + newvalues[i] = NULL; return n; } @@ -1029,7 +1106,7 @@ void MC_Combo_Key(menucombo_t *combo, int key) combo->selectedoption = 0; changed: - if (combo->cvar) + if (combo->cvar && combo->numoptions) Cvar_Set(combo->cvar, (char *)combo->values[combo->selectedoption]); } else if (key == K_LEFTARROW) diff --git a/engine/client/m_script.c b/engine/client/m_script.c index 88788031b..f29f69b48 100644 --- a/engine/client/m_script.c +++ b/engine/client/m_script.c @@ -239,6 +239,118 @@ void M_MenuS_Bind_f (void) MC_AddBind(menu_script, x, y, command, caption); } +void M_MenuS_Comboi_f (void) +{ + int opt; + char *opts[64]; + char *values[64]; + char valuesb[64][8]; + int x = atoi(Cmd_Argv(1)); + int y = atoi(Cmd_Argv(2)); + char *caption = Cmd_Argv(3); + char *command = Cmd_Argv(4); + char *line; + + cvar_t *var; + + if (!menu_script) + { + Con_Printf("%s with no active menu\n", Cmd_Argv(0)); + return; + } + + var = Cvar_Get(command, "0", 0, "custom cvars"); + if (!var) + return; + + if (!*caption) + caption = command; + + for (opt = 0; opt < sizeof(opts)/sizeof(opts[0])-2 && *(line=Cmd_Argv(5+opt)); opt++) + { + opts[opt] = line; + sprintf(valuesb[opt], "%i", opt); + values[opt] = valuesb[opt]; + } + opts[opt] = NULL; + + MC_AddCvarCombo(menu_script, x, y, caption, var, opts, values); +} + +char *Hunk_TempString(char *s) +{ + char *h; + h = Hunk_TempAllocMore(strlen(s)+1); + strcpy(h, s); + return h; +} + +void M_MenuS_Combos_f (void) +{ + int opt; + char *opts[64]; + char *values[64]; + int x = atoi(Cmd_Argv(1)); + int y = atoi(Cmd_Argv(2)); + char *caption = Cmd_Argv(3); + char *command = Cmd_Argv(4); + char *line; + + cvar_t *var; + + if (!menu_script) + { + Con_Printf("%s with no active menu\n", Cmd_Argv(0)); + return; + } + + var = Cvar_Get(command, "0", 0, "custom cvars"); + if (!var) + return; + + if (!*caption) + caption = command; + + line = Cmd_Argv(5); + if (!*line) + { + line = Cbuf_GetNext(Cmd_ExecLevel); + if (*line != '{') + Cbuf_InsertText(line, Cmd_ExecLevel, true); //whoops. Stick the trimmed string back in to the cbuf. + else + line = "{"; + } + if (!strcmp(line, "{")) + { + char *line; + Hunk_TempAlloc(4); + for (opt = 0; opt < sizeof(opts)/sizeof(opts[0])-2; opt++) + { + line = Cbuf_GetNext(Cmd_ExecLevel); + line = COM_Parse(line); + if (!strcmp(com_token, "}")) + break; + opts[opt] = Hunk_TempString(com_token); + line = COM_Parse(line); + values[opt] = Hunk_TempString(com_token); + } + } + else + { + for (opt = 0; opt < sizeof(opts)/sizeof(opts[0])-2; opt++) + { + line = Cmd_Argv(5+opt*2); + if (!*line) + break; + opts[opt] = line; + values[opt] = Cmd_Argv(5+opt*2 + 1); + } + } + opts[opt] = NULL; + + MC_AddCvarCombo(menu_script, x, y, caption, var, opts, values); +} + /* menuclear menualias menucallback @@ -264,7 +376,8 @@ void M_Script_Init(void) Cmd_AddCommand("menucheck", M_MenuS_CheckBox_f); Cmd_AddCommand("menuslider", M_MenuS_Slider_f); Cmd_AddCommand("menubind", M_MenuS_Bind_f); -// Cmd_AddCommand("menucombo", M_MenuS_Combo_f); + Cmd_AddCommand("menucomboi", M_MenuS_Comboi_f); + Cmd_AddCommand("menucombos", M_MenuS_Combos_f); Cvar_Register(&menualias, "Scripting"); }