r1ch.net forums
* Home Help Search Login Register
r1ch.net  |  General  |  General Discussion  |  Topic: Need help
Pages: [1]
Print
Author Topic: Need help  (Read 4593 times)
Weasel
Member

Posts: 85



« on: December 24, 2004, 01:57:38 am »

This should be the source for a mod menu I am working on that is giving me WARNING: datagram overflowed for xxx errors when the menu is being displayed.  Any ideas how to fix it?

Code:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "g_local.h"

#ifndef FALSE
#define FALSE 0
#endif

#ifndef TRUE
#define TRUE 1
#endif


//
// ----------------------------------------------------------------------------------------
//
// Local Global Variables
//
// ----------------------------------------------------------------------------------------
//
static Menu *menuList = NULL;
//
// ----------------------------------------------------------------------------------------
//
// Prototypes
//
// ----------------------------------------------------------------------------------------
//
static Menu *MenuFind (int menuId);
static MenuItem *MenuItemFindFirstOption (Menu *menu);


//
// ----------------------------------------------------------------------------------------
//
static MenuItem *MenuItemFindFirstOption(Menu *menu)
{
MenuItem *first = NULL;
if (menu)
{
first = menu->menuItem;
while (first && first->itemType == OPT_FILLER)
first = first->nextItem;
}

return (first);
}

//
// ----------------------------------------------------------------------------------------
//
int Chicken_MenuSelect(void *data, int menuId)
{
edict_t *ent = (edict_t *)data;

if ((ent->client->currentMenu = MenuFind(menuId)) != NULL)
ent->client->currentItem = MenuItemFindFirstOption(ent->client->currentMenu);

return (ent->client->currentMenu?1:0);
}

//
// ----------------------------------------------------------------------------------------
//
int Chicken_MenuInsert(int menuId)
{
Menu *newMenu = NULL;
int retSta = 0;

if ((newMenu = (Menu *)gi.TagMalloc(sizeof(*newMenu), TAG_GAME)) == NULL)
exit(-1);
else
{
memset(newMenu, 0, sizeof(*newMenu));
newMenu->menuId = menuId;

if (menuList == NULL)
menuList = newMenu;
else
{
Menu *ptr = menuList;
Menu    *prev   = NULL;

while (ptr->menuId < newMenu->menuId && ptr->nextMenu)
{
prev = ptr;
ptr = ptr->nextMenu;
}

if (ptr->menuId < newMenu->menuId)
{
newMenu->nextMenu = ptr->nextMenu;
ptr->nextMenu  = newMenu;
}
else
{
if (prev)
{
newMenu->nextMenu = menuList;
menuList = newMenu;
}
else
{
newMenu->nextMenu = prev->nextMenu;
prev->nextMenu = newMenu;
}
}
}
}

return (retSta);
}

//
// ----------------------------------------------------------------------------------------
//
static Menu *MenuFind(int menuId)
{
Menu *menu = menuList;

while (menu && menu->menuId != menuId)
menu = menu->nextMenu;

return (menu);
}

//
// ----------------------------------------------------------------------------------------
//
int Chicken_MenuItemInsert(int menuId, int itemId, char *text, ItemColour colour, ItemAlign align, OptionType itemType, ...)
{
Menu *menu = MenuFind(menuId);
MenuItem *newItem = NULL;
int retSta = 0;

if (menu && itemId < MAX_MENU_ITEMS)
{
if ((newItem = (MenuItem *)gi.TagMalloc(sizeof(*newItem), TAG_GAME)) == NULL)
exit(-1);
else
{
memset(newItem, 0, sizeof(*newItem));
newItem->itemId = itemId;

newItem->text = text;

newItem->colour = colour;
newItem->align = align;
newItem->itemType = itemType;

{
va_list marker;

va_start( marker, itemType );     /* Initialize variable arguments. */

switch(itemType)
{
case OPT_TOGGLE:
{
char *text;

newItem->type->toggle->toggle = va_arg( marker,int *);

text = va_arg( marker, char *);
newItem->type->toggle->selectedText = text;
}
break;

case OPT_OPTION:
{
int i;

newItem->type->option->maxOptions = 0;
newItem->type->option->option = va_arg( marker,int *);

i = va_arg( marker, int);
while( i != -1 )
{
newItem->type->option->maxOptions++;
if ((newItem->type->option->optionList = realloc( newItem->type->option->optionList,
newItem->type->option->maxOptions * sizeof( int )) ) ==  NULL )
exit(-1);

newItem->type->option->optionList[newItem->type->option->maxOptions - 1] = i;

i = va_arg( marker, int);
}
*newItem->type->option->option = newItem->type->option->optionList[newItem->type->option->curOption];

}
break;

case OPT_MENU:
newItem->type->menu->menuId = va_arg( marker, int);
break;

case OPT_SELECT:
newItem->type->select->func = (void *)(va_arg( marker, void *));
break;

case OPT_FILLER:
break;

default:
exit(-1);
}
va_end( marker );              /* Reset variable arguments.      */
}

if (menu->menuItem == NULL)
menu->menuItem = newItem;
else
{
MenuItem *ptr = menu->menuItem;

while (ptr->itemId < newItem->itemId  && ptr->nextItem)
ptr = ptr->nextItem;

if (ptr->itemId < newItem->itemId)
{
newItem->nextItem = ptr->nextItem;
newItem->prevItem = ptr;

if (ptr->nextItem)
ptr->nextItem->prevItem = newItem;

ptr->nextItem  = newItem;
}
else
{
if (ptr->prevItem)
{
newItem->nextItem = menu->menuItem;
menu->menuItem->prevItem = newItem;
menu->menuItem = newItem;
}
else
{
ptr->prevItem->nextItem = newItem;
newItem->prevItem = ptr;
newItem->nextItem = ptr->nextItem;
ptr->prevItem = newItem;
}
}
}
}
}

return (retSta);
}

//
// ----------------------------------------------------------------------------------------
//
void Chicken_MenuItemNext(void *data)
{
edict_t *ent = (edict_t *)data;
MenuItem *next = NULL;

if (ent->client->currentItem)
{
int oneLoop = FALSE;
next = ent->client->currentItem->nextItem;

if (!next)
{
oneLoop = TRUE;
next = ent->client->currentMenu->menuItem;
}

while (next && next->itemType == OPT_FILLER)
{
next = next->nextItem;
if (!next)
{
oneLoop = TRUE;
next = ent->client->currentMenu->menuItem;
}
}

ent->client->currentItem = next;
}
}

//
// ----------------------------------------------------------------------------------------
//
void Chicken_MenuItemPrev(void *data)
{
edict_t *ent = (edict_t *)data;
MenuItem *prev = NULL;

if (ent->client->currentItem)
{
int oneLoop = FALSE;
prev = ent->client->currentItem->prevItem;

if (!prev)
{
oneLoop = TRUE;
prev = ent->client->currentMenu->menuItem;
while(prev->nextItem)
prev = prev->nextItem;
}

while (prev && prev->itemType == OPT_FILLER)
{
prev = prev->prevItem;
if (!prev)
{
oneLoop = TRUE;
prev = ent->client->currentMenu->menuItem;
while(prev->nextItem)
prev = prev->nextItem;
}
}

ent->client->currentItem = prev;
}
}

//
// ----------------------------------------------------------------------------------------
//
int Chicken_MenuItemSelect(void *data, int itemId)
{
int retSta = 0;
char message[64];
edict_t *ent = (edict_t *)data;

switch(ent->client->currentItem->itemType)
{
case OPT_TOGGLE:
{
if (*ent->client->currentItem->type->toggle->toggle)
{
*ent->client->currentItem->type->toggle->toggle = FALSE;
sprintf(message, "%s turned %s off\n",
ent->client?ent->client->pers.netname:"someone", ent->client->currentItem->text);
}
else
{
*ent->client->currentItem->type->toggle->toggle = TRUE;
sprintf(message, "%s turned %s on\n",
ent->client?ent->client->pers.netname:"someone", ent->client->currentItem->text);
}

gi.bprintf(PRINT_HIGH, message);

}
break;

case OPT_OPTION:
ent->client->currentItem->type->option->curOption++;
ent->client->currentItem->type->option->curOption %= ent->client->currentItem->type->option->maxOptions;
*ent->client->currentItem->type->option->option = ent->client->currentItem->type->option->optionList[ent->client->currentItem->type->option->curOption];
sprintf(message, "%s changed %s to %d\n",
ent->client?ent->client->pers.netname:"someone", ent->client->currentItem->text, *ent->client->currentItem->type->option->option);
gi.bprintf(PRINT_HIGH, message);
break;

case OPT_MENU:
Chicken_MenuSelect(ent, ent->client->currentItem->type->menu->menuId);
break;

case OPT_SELECT:
retSta = ent->client->currentItem->type->select->func(ent, itemId);
break;

case OPT_FILLER:
break;

default:
exit(-1);
}

return (retSta);
}

//
// ----------------------------------------------------------------------------------------
//
void Chicken_MenuDisplay(void *data)
{
edict_t *ent = (edict_t *)data;

if (ent->client->currentMenu)
{
char string[1400];
int itemCount = 0;
MenuItem *curItem = ent->client->currentMenu->menuItem;

sprintf(string, "xv 32 yv 12 picn chicken_options ");

while(curItem)
{
int len = (curItem->text?strlen(curItem->text):0);

sprintf(string + strlen(string), "yv %d xv %d ", 32 + curItem->itemId * 8, 50);

switch(curItem->itemType)
{
case OPT_FILLER:
switch (curItem->align)
{
case CENTER:
sprintf(string + strlen(string), "%s \"%-*.*s%-*.*s\" ",
curItem->colour == WHITE ? "string "   : "string2",
(MENU_ITEM_LINE_LEN-len)/2, (MENU_ITEM_LINE_LEN-len)/2, " ",
len, len,
curItem->text ? curItem->text: " ");
break;
case LEFT:
sprintf(string + strlen(string), "%s \"%-*.*s\" ",
curItem->colour == WHITE ? "string "   : "string2",
MENU_ITEM_LINE_LEN, MENU_ITEM_LINE_LEN,
curItem->text ? curItem->text: " ");
break;
case RIGHT:
sprintf(string + strlen(string), "%s \"%*.*s\" ",
curItem->colour == WHITE ? "string "   : "string2",
MENU_ITEM_LINE_LEN, MENU_ITEM_LINE_LEN,
curItem->text ? curItem->text: " ");
break;
}
break;

case OPT_TOGGLE:
case OPT_SELECT:
case OPT_MENU:
switch(curItem->align)
{
case CENTER:
sprintf(string + strlen(string), "%s \"%-1s%-*.*s%-*.*s%-*.*s %3s\" ",

curItem->colour == WHITE ? "string "   : "string2",

curItem == ent->client->currentItem ? "\x0d"   : " ",

(MENU_ITEM_LINE_LEN-5-len)/2, (MENU_ITEM_LINE_LEN-5-len)/2, " ",
len, len,
(curItem->itemType == OPT_TOGGLE ?
(*curItem->type->toggle->toggle ?
(curItem->type->toggle->selectedText ? curItem->type->toggle->selectedText:
(curItem->text ? curItem->text: " ")):
(curItem->text ? curItem->text: " ")):
(curItem->text ? curItem->text: " ")),

(MENU_ITEM_LINE_LEN-5-len)/2, (MENU_ITEM_LINE_LEN-5-len)/2, " ",
(curItem->itemType == OPT_TOGGLE ?
(*curItem->type->toggle->toggle ? "on" : "off"):
" "));
break;
case LEFT:
sprintf(string + strlen(string), "%s \"%-1s%-*.*s %3s\" ",

curItem->colour == WHITE ? "string "   : "string2",

curItem == ent->client->currentItem ? "\x0d"   : " ",

MENU_ITEM_LINE_LEN-5, MENU_ITEM_LINE_LEN-5,

(curItem->itemType == OPT_TOGGLE ?
(*curItem->type->toggle->toggle ?
(curItem->type->toggle->selectedText ? curItem->type->toggle->selectedText:
(curItem->text ? curItem->text: " ")):
(curItem->text ? curItem->text: " ")):
(curItem->text ? curItem->text: " ")),

(curItem->itemType == OPT_TOGGLE ?
(*curItem->type->toggle->toggle ? "on" : "off"):
" "));
break;
case RIGHT:
sprintf(string + strlen(string), "%s \"%-1s%*.*s %3s\" ",

curItem->colour == WHITE ? "string "   : "string2",

curItem == ent->client->currentItem ? "\x0d"   : " ",

MENU_ITEM_LINE_LEN-5, MENU_ITEM_LINE_LEN-5,

(curItem->itemType == OPT_TOGGLE ?
(*curItem->type->toggle->toggle ?
(curItem->type->toggle->selectedText ? curItem->type->toggle->selectedText:
(curItem->text ? curItem->text: " ")):
(curItem->text ? curItem->text: " ")):
(curItem->text ? curItem->text: " ")),

(curItem->itemType == OPT_TOGGLE ?
(*curItem->type->toggle->toggle ? "on" : "off"):
" "));
break;
}
break;

case OPT_OPTION:
switch(curItem->align)
{
case CENTER:
sprintf(string + strlen(string), "%s \"%-1s%-*.*s%-*.*s%-*.*s %3d\" ",

curItem->colour == WHITE ? "string "   : "string2",

curItem == ent->client->currentItem ? "\x0d"   : " ",

(MENU_ITEM_LINE_LEN-5-len)/2, (MENU_ITEM_LINE_LEN-5-len)/2, " ",
len, len, curItem->text,
(MENU_ITEM_LINE_LEN-5-len)/2, (MENU_ITEM_LINE_LEN-5-len)/2, " ",
*curItem->type->option->option);
break;
case LEFT:
sprintf(string + strlen(string), "%s \"%-1s%-*.*s %3d\" ",
curItem->colour == WHITE ? "string "   : "string2",

curItem == ent->client->currentItem ? "\x0d"   : " ",

MENU_ITEM_LINE_LEN-5, MENU_ITEM_LINE_LEN-5,
curItem->text,
*curItem->type->option->option);
break;
case RIGHT:
sprintf(string + strlen(string), "%s \"%-1s%*.*s %3d\" ",
curItem->colour == WHITE ? "string "   : "string2",

curItem == ent->client->currentItem ? "\x0d"   : " ",

MENU_ITEM_LINE_LEN-5, MENU_ITEM_LINE_LEN-5,
curItem->text,
*curItem->type->option->option);
break;
}
break;

}

itemCount++;
curItem = curItem->nextItem;

}


gi.WriteByte (svc_layout);
gi.WriteString (string);
gi.unicast (ent, false);
}
}
Logged
QwazyWabbit
Member

Posts: 402


« Reply #1 on: January 21, 2005, 08:31:10 am »

You probably already have found your answer by now but the maximum frame size allowed by the Quake2 protocol is 1400 bytes. Your menu is probably sending too many characters.
Logged
Pages: [1]
Print
r1ch.net  |  General  |  General Discussion  |  Topic: Need help
Jump to:  

Powered by SMF 1.1.19 | SMF © 2013, Simple Machines