All pastes #1219887 Raw Edit

geever

public diff v1 · immutable
#1219887 ·published 2008-10-05 14:49 UTC
rendered paste body
Index: src/client/menu/m_node_text.c===================================================================--- src/client/menu/m_node_text.c	(revision 19496)+++ src/client/menu/m_node_text.c	(working copy)@@ -139,6 +139,7 @@ 	vec4_t colorSelectedHover; 	char *cur, *tab, *end; 	int x1, y1; /* variable x and y position */+	vec2_t nodepos;  	if (text) { 		Q_strncpyz(textCopy, text, sizeof(textCopy));@@ -148,6 +149,7 @@ 		Sys_Error("MN_DrawTextNode: Called without text or linkedList pointer"); 	cur = textCopy; +	MN_GetNodeAbsPos(node, nodepos); 	/* Hover darkening effect for normal text lines. */ 	VectorScale(node->color, 0.8, colorHover); 	colorHover[3] = node->color[3];@@ -165,8 +167,7 @@  	y1 = y; 	/*Com_Printf("\n\n\nnode->textLines: %i \n", node->textLines);*/-	if (node)-		node->textLines = 0; /* these are lines only in one-line texts! */+	node->textLines = 0; /* these are lines only in one-line texts! */ 	/* but it's easy to fix, just change FontDrawString 	 * so that it returns a pair, #lines and height 	 * and add that to variable line; the only other file@@ -274,18 +275,18 @@  	/* draw scrollbars */ 	if (node->scrollbar && node->height && node->textLines > node->height) {-		const int scrollbarX = node->pos[0] + (node->scrollbarLeft ? 0 : node->size[0] - MN_SCROLLBAR_WIDTH);+		const int scrollbarX = nodepos[0] + (node->scrollbarLeft ? 0 : node->size[0] - MN_SCROLLBAR_WIDTH); 		const float scrollbarY = node->size[1] * node->height / node->textLines * MN_SCROLLBAR_HEIGHT;  		R_DrawFill(scrollbarX,-			node->pos[1],+			nodepos[1], 			MN_SCROLLBAR_WIDTH, 			node->size[1], 			ALIGN_UL, 			scrollbarBackground);  		R_DrawFill(scrollbarX,-			node->pos[1] + (node->size[1] - scrollbarY) * node->textScroll / (node->textLines - node->height),+			nodepos[1] + (node->size[1] - scrollbarY) * node->textScroll / (node->textLines - node->height), 			MN_SCROLLBAR_WIDTH, 			scrollbarY, 			ALIGN_UL,Index: src/client/menu/m_node_checkbox.c===================================================================--- src/client/menu/m_node_checkbox.c	(revision 19496)+++ src/client/menu/m_node_checkbox.c	(working copy)@@ -6,7 +6,9 @@ { 	const char *image; 	const char *ref;+	vec2_t nodepos; +	MN_GetNodeAbsPos(node, nodepos); 	/* image set? */ 	if (checkBoxImage && *checkBoxImage) 		image = checkBoxImage;@@ -19,11 +21,11 @@  	switch (*ref) { 	case '0':-		R_DrawNormPic(node->pos[0], node->pos[1], node->size[0], node->size[1],+		R_DrawNormPic(nodepos[0], nodepos[1], node->size[0], node->size[1], 			node->texh[0], node->texh[1], node->texl[0], node->texl[1], node->align, node->blend, va("%s_unchecked", image)); 		break; 	case '1':-		R_DrawNormPic(node->pos[0], node->pos[1], node->size[0], node->size[1],+		R_DrawNormPic(nodepos[0], nodepos[1], node->size[0], node->size[1], 			node->texh[0], node->texh[1], node->texl[0], node->texl[1], node->align, node->blend, va("%s_checked", image)); 		break; 	default:Index: src/client/menu/m_node_selectbox.c===================================================================--- src/client/menu/m_node_selectbox.c	(revision 19496)+++ src/client/menu/m_node_selectbox.c	(working copy)@@ -73,24 +73,26 @@ 	int selBoxX, selBoxY; 	const char *ref; 	const char *font;+	vec2_t nodepos; +	MN_GetNodeAbsPos(node, nodepos); 	if (!image) 		image = "menu/selectbox";  	ref = MN_GetReferenceString(node->menu, node->data[MN_DATA_MODEL_SKIN_OR_CVAR]);  	font = MN_GetFont(node->menu, node);-	selBoxX = node->pos[0] + SELECTBOX_SIDE_WIDTH;-	selBoxY = node->pos[1] + SELECTBOX_SPACER;+	selBoxX = nodepos[0] + SELECTBOX_SIDE_WIDTH;+	selBoxY = nodepos[1] + SELECTBOX_SPACER;  	/* left border */-	R_DrawNormPic(node->pos[0], node->pos[1], SELECTBOX_SIDE_WIDTH, node->size[1],+	R_DrawNormPic(nodepos[0], nodepos[1], SELECTBOX_SIDE_WIDTH, node->size[1], 		SELECTBOX_SIDE_WIDTH, 20.0f, 0.0f, 0.0f, node->align, node->blend, image); 	/* stretched middle bar */-	R_DrawNormPic(node->pos[0] + SELECTBOX_SIDE_WIDTH, node->pos[1], node->size[0], node->size[1],+	R_DrawNormPic(nodepos[0] + SELECTBOX_SIDE_WIDTH, nodepos[1], node->size[0], node->size[1], 		12.0f, 20.0f, 7.0f, 0.0f, node->align, node->blend, image); 	/* right border (arrow) */-	R_DrawNormPic(node->pos[0] + SELECTBOX_SIDE_WIDTH + node->size[0], node->pos[1], SELECTBOX_DEFAULT_HEIGHT, node->size[1],+	R_DrawNormPic(nodepos[0] + SELECTBOX_SIDE_WIDTH + node->size[0], nodepos[1], SELECTBOX_DEFAULT_HEIGHT, node->size[1], 		32.0f, 20.0f, 12.0f, 0.0f, node->align, node->blend, image); 	/* draw the label for the current selected option */ 	for (selectBoxOption = node->options; selectBoxOption; selectBoxOption = selectBoxOption->next) {@@ -108,15 +110,15 @@  		/* drop down menu */ 		/* left side */-		R_DrawNormPic(node->pos[0], node->pos[1] + node->size[1], SELECTBOX_SIDE_WIDTH, node->size[1] * node->height,+		R_DrawNormPic(nodepos[0], nodepos[1] + node->size[1], SELECTBOX_SIDE_WIDTH, node->size[1] * node->height, 			7.0f, 28.0f, 0.0f, 21.0f, node->align, node->blend, image);  		/* stretched middle bar */-		R_DrawNormPic(node->pos[0] + SELECTBOX_SIDE_WIDTH, node->pos[1] + node->size[1], node->size[0], node->size[1] * node->height,+		R_DrawNormPic(nodepos[0] + SELECTBOX_SIDE_WIDTH, nodepos[1] + node->size[1], node->size[0], node->size[1] * node->height, 			16.0f, 28.0f, 7.0f, 21.0f, node->align, node->blend, image);  		/* right side */-		R_DrawNormPic(node->pos[0] + SELECTBOX_SIDE_WIDTH + node->size[0], node->pos[1] + node->size[1], SELECTBOX_SIDE_WIDTH, node->size[1] * node->height,+		R_DrawNormPic(nodepos[0] + SELECTBOX_SIDE_WIDTH + node->size[0], nodepos[1] + node->size[1], SELECTBOX_SIDE_WIDTH, node->size[1] * node->height, 			23.0f, 28.0f, 16.0f, 21.0f, node->align, node->blend, image);  		/* now draw all available options for this selectbox */@@ -126,7 +128,7 @@ 				R_DrawFill(selBoxX, selBoxY, node->size[0], SELECTBOX_DEFAULT_HEIGHT, ALIGN_UL, node->color); 			/* print the option label */ 			R_FontDrawString(font, node->align, selBoxX, selBoxY,-				selBoxX, node->pos[1] + node->size[1], node->size[0] - 4, 0,+				selBoxX, nodepos[1] + node->size[1], node->size[0] - 4, 0, 				node->texh[0], _(selectBoxOption->label), 0, 0, NULL, qfalse); 			/* next entries' position */ 			selBoxY += node->size[1];@@ -134,15 +136,15 @@ 			selectBoxOption->hovered = qfalse; 		} 		/* left side */-		R_DrawNormPic(node->pos[0], selBoxY - SELECTBOX_SPACER, SELECTBOX_SIDE_WIDTH, SELECTBOX_BOTTOM_HEIGHT,+		R_DrawNormPic(nodepos[0], selBoxY - SELECTBOX_SPACER, SELECTBOX_SIDE_WIDTH, SELECTBOX_BOTTOM_HEIGHT, 			7.0f, 32.0f, 0.0f, 28.0f, node->align, node->blend, image);  		/* stretched middle bar */-		R_DrawNormPic(node->pos[0] + SELECTBOX_SIDE_WIDTH, selBoxY - SELECTBOX_SPACER, node->size[0], SELECTBOX_BOTTOM_HEIGHT,+		R_DrawNormPic(nodepos[0] + SELECTBOX_SIDE_WIDTH, selBoxY - SELECTBOX_SPACER, node->size[0], SELECTBOX_BOTTOM_HEIGHT, 			16.0f, 32.0f, 7.0f, 28.0f, node->align, node->blend, image);  		/* right bottom side */-		R_DrawNormPic(node->pos[0] + SELECTBOX_SIDE_WIDTH + node->size[0], selBoxY - SELECTBOX_SPACER,+		R_DrawNormPic(nodepos[0] + SELECTBOX_SIDE_WIDTH + node->size[0], selBoxY - SELECTBOX_SPACER, 			SELECTBOX_SIDE_WIDTH, SELECTBOX_BOTTOM_HEIGHT, 			23.0f, 32.0f, 16.0f, 28.0f, node->align, node->blend, image); 	}Index: src/client/menu/m_draw.c===================================================================--- src/client/menu/m_draw.c	(revision 19496)+++ src/client/menu/m_draw.c	(working copy)@@ -36,18 +36,21 @@  static void MN_DrawBorder (const menuNode_t *node) {+	vec2_t nodepos;+	+	MN_GetNodeAbsPos(node, nodepos); 	/** @todo use GL_LINE_LOOP + array here */ 	/* left */-	R_DrawFill(node->pos[0] - node->padding - node->border, node->pos[1] - node->padding - node->border,+	R_DrawFill(nodepos[0] - node->padding - node->border, nodepos[1] - node->padding - node->border, 		node->border, node->size[1] + (node->padding*2) + (node->border*2), node->align, node->bordercolor); 	/* right */-	R_DrawFill(node->pos[0] + node->size[0] + node->padding, node->pos[1] - node->padding - node->border,+	R_DrawFill(nodepos[0] + node->size[0] + node->padding, nodepos[1] - node->padding - node->border, 		node->border, node->size[1] + (node->padding*2) + (node->border*2), node->align, node->bordercolor); 	/* top */-	R_DrawFill(node->pos[0] - node->padding, node->pos[1] - node->padding - node->border,+	R_DrawFill(nodepos[0] - node->padding, nodepos[1] - node->padding - node->border, 		node->size[0] + (node->padding*2), node->border, node->align, node->bordercolor); 	/* down */-	R_DrawFill(node->pos[0] - node->padding, node->pos[1] + node->size[1] + node->padding,+	R_DrawFill(nodepos[0] - node->padding, nodepos[1] + node->size[1] + node->padding, 		node->size[0] + (node->padding*2), node->border, node->align, node->bordercolor); } @@ -68,6 +71,7 @@ 	int i; 	message_t *message; 	const invList_t *itemHover = NULL;+	vec2_t nodepos;  	/* render every menu on top of a menu with a render node */ 	pp = 0;@@ -97,6 +101,7 @@ 			} 		} 		for (node = menu->firstNode; node; node = node->next) {+			MN_GetNodeAbsPos(node, nodepos); 			if (!node->invis && ((node->data[MN_DATA_STRING_OR_IMAGE_OR_MODEL] /* 0 are images, models and strings e.g. */ 					|| node->type == MN_CONTAINER || node->type == MN_TEXT || node->type == MN_BASELAYOUT || node->type == MN_BASEMAP || node->type == MN_MAP) 					|| node->type == MN_CHECKBOX || node->type == MN_SELECTBOX || node->type == MN_LINESTRIP@@ -138,13 +143,13 @@ 				}  				/* check node size x and y value to check whether they are zero */-				if (node->bgcolor && node->size[0] && node->size[1] && node->pos) {+				if (node->bgcolor && node->size[0] && node->size[1] && nodepos[0] && nodepos[1]) { 					if (node->type != MN_BASELAYOUT)-						R_DrawFill(node->pos[0] - node->padding, node->pos[1] - node->padding,+						R_DrawFill(nodepos[0] - node->padding, nodepos[1] - node->padding, 							node->size[0] + (node->padding * 2), node->size[1] + (node->padding * 2), 0, node->bgcolor); 				} -				if (node->border && node->bordercolor && node->size[0] && node->size[1] && node->pos)+				if (node->border && node->bordercolor && node->size[0] && node->size[1] && nodepos) 					MN_DrawBorder(node);  				/* mouse darken effect */@@ -200,18 +205,18 @@ 					ref += node->horizontalScroll; 					/* blinking */ 					if (!node->mousefx || cl.time % 1000 < 500)-						R_FontDrawString(font, node->align, node->pos[0], node->pos[1], node->pos[0], node->pos[1], node->size[0], 0, node->texh[0], ref, 0, 0, NULL, qfalse);+						R_FontDrawString(font, node->align, nodepos[0], nodepos[1], nodepos[0], nodepos[1], node->size[0], 0, node->texh[0], ref, 0, 0, NULL, qfalse); 					else-						R_FontDrawString(font, node->align, node->pos[0], node->pos[1], node->pos[0], node->pos[1], node->size[0], node->size[1], node->texh[0], va("%s*\n", ref), 0, 0, NULL, qfalse);+						R_FontDrawString(font, node->align, nodepos[0], nodepos[1], nodepos[0], nodepos[1], node->size[0], node->size[1], node->texh[0], va("%s*\n", ref), 0, 0, NULL, qfalse); 					break;  				case MN_TEXT: 					if (mn.menuText[node->num]) { 						font = MN_GetFont(menu, node);-						MN_DrawTextNode(mn.menuText[node->num], NULL, font, node, node->pos[0], node->pos[1], node->size[0], node->size[1]);+						MN_DrawTextNode(mn.menuText[node->num], NULL, font, node, nodepos[0], nodepos[1], node->size[0], node->size[1]); 					} else if (mn.menuTextLinkedList[node->num]) { 						font = MN_GetFont(menu, node);-						MN_DrawTextNode(NULL, mn.menuTextLinkedList[node->num], font, node, node->pos[0], node->pos[1], node->size[0], node->size[1]);+						MN_DrawTextNode(NULL, mn.menuTextLinkedList[node->num], font, node, nodepos[0], nodepos[1], node->size[0], node->size[1]); 					} else if (node->num == TEXT_MESSAGESYSTEM) { 						linkedList_t *messagelist = NULL; 						char text[TIMESTAMP_TEXT + MAX_MESSAGE_TEXT];@@ -233,7 +238,7 @@ 							message = message->next; 						} 						if (messagelist) {-							MN_DrawTextNode(NULL, messagelist, font, node, node->pos[0], node->pos[1], node->size[0], node->size[1]);+							MN_DrawTextNode(NULL, messagelist, font, node, nodepos[0], nodepos[1], node->size[0], node->size[1]); 							LIST_Delete(&messagelist); 						} 					}@@ -246,7 +251,7 @@ 						/* in the case of MN_BAR the first three data array values are float values - see menuDataValues_t */ 						fac = node->size[0] / (MN_GetReferenceFloat(menu, node->data[0]) - MN_GetReferenceFloat(menu, node->data[1])); 						bar_width = (MN_GetReferenceFloat(menu, node->data[2]) - MN_GetReferenceFloat(menu, node->data[1])) * fac;-						R_DrawFill(node->pos[0], node->pos[1], bar_width, node->size[1], node->align, mouseOver ? color : node->color);+						R_DrawFill(nodepos[0], nodepos[1], bar_width, node->size[1], node->align, mouseOver ? color : node->color); 					} 					break; @@ -259,7 +264,7 @@ 							shx = node->texl[0] + round(ps * node->pointWidth) + (ps > 0 ? floor((ps - 1) / 10) * node->gapWidth : 0); 						} else 							shx = node->texh[0];-						R_DrawNormPic(node->pos[0], node->pos[1], node->size[0], node->size[1],+						R_DrawNormPic(nodepos[0], nodepos[1], node->size[0], node->size[1], 							shx, node->texh[1], node->texl[0], node->texl[1], node->align, node->blend, ref); 					} 					break;@@ -308,8 +313,8 @@ 							dragInfo.toNode = node; 							dragInfo.to = node->container; -							dragInfo.toX = (mousePosX - node->pos[0] - itemX) / C_UNIT;-							dragInfo.toY = (mousePosY - node->pos[1] - itemY) / C_UNIT;+							dragInfo.toX = (mousePosX - nodepos[0] - itemX) / C_UNIT;+							dragInfo.toY = (mousePosY - nodepos[1] - itemY) / C_UNIT;  							/** Check if the items already exists in the container. i.e. there is already at least one item. 							 * @sa Com_AddToInventory */@@ -384,7 +389,7 @@ 							CIN_PlayCinematic(node->data[MN_DATA_STRING_OR_IMAGE_OR_MODEL]); 						if (cls.playingCinematic) { 							/* only set replay to true if video was found and is running */-							CIN_SetParameters(node->pos[0], node->pos[1], node->size[0], node->size[1], CIN_STATUS_MENU, qtrue);+							CIN_SetParameters(nodepos[0], nodepos[1], node->size[0], node->size[1], CIN_STATUS_MENU, qtrue); 							CIN_RunCinematic(); 						} 					}@@ -396,7 +401,7 @@ 					menu->hoverNode = node;  				if (mn_debugmenu->integer)-					MN_DrawTooltip("f_small", node->name, node->pos[0], node->pos[1], node->size[1], 0);+					MN_DrawTooltip("f_small", node->name, nodepos[0], nodepos[1], node->size[1], 0);  				R_ColorBlend(NULL); 			}	/* if */Index: src/client/menu/m_inventory.c===================================================================--- src/client/menu/m_inventory.c	(revision 19496)+++ src/client/menu/m_inventory.c	(working copy)@@ -180,7 +180,7 @@ 					qboolean newRow = qfalse; 					vec2_t posMin; 					vec2_t posMax;-					Vector2Copy(node->pos, posMin);+					MN_GetNodeAbsPos(node, posMin); 					posMin[0] += curWidth; 					posMin[1] += curHeight; 					Vector2Copy(posMin, posMax);@@ -198,7 +198,7 @@ 						curWidth = maxHeight = 0;  						/* Re-calculate the min & max values for this item in the new row. */-						Vector2Copy(node->pos, posMin);+						MN_GetNodeAbsPos(node, posMin); 						posMin[1] += curHeight; 						Vector2Copy(posMin, posMax); 						newRow = qtrue;@@ -297,16 +297,18 @@ 	if (mouseSpace == MS_MENU) { 		invList_t *ic; 		int fromX, fromY;- 		assert(node->container); 		/* Get coordinates inside a scrollable container (if it is one). */ 		if (node->container->scroll) { 			ic = MN_GetItemFromScrollableContainer(node, mouseX, mouseY, &fromX, &fromY); 			Com_DPrintf(DEBUG_CLIENT, "MN_Drag: item %i/%i selected from scrollable container.\n", fromX, fromY); 		} else {+			vec2_t nodepos;++			MN_GetNodeAbsPos(node, nodepos); 			/* Normalize screen coordinates to container coordinates. */-			fromX = (int) (mouseX - node->pos[0]) / C_UNIT;-			fromY = (int) (mouseY - node->pos[1]) / C_UNIT;+			fromX = (int) (mouseX - nodepos[0]) / C_UNIT;+			fromY = (int) (mouseY - nodepos[1]) / C_UNIT;  			ic = Com_SearchInInventory(menuInventory, node->container, fromX, fromY); 		}@@ -620,7 +622,10 @@ void MN_DrawDisabled (const menuNode_t* node) { 	const vec4_t color = { 0.3f, 0.3f, 0.3f, 0.7f };-	R_DrawFill(node->pos[0], node->pos[1], node->size[0], node->size[1], ALIGN_UL, color);+	vec2_t nodepos;+	+	MN_GetNodeAbsPos(node, nodepos);+	R_DrawFill(nodepos[0], nodepos[1], node->size[0], node->size[1], ALIGN_UL, color); }  /**@@ -630,15 +635,18 @@ { 	const vec4_t color = { 0.0f, 1.0f, 0.0f, 0.7f }; 	invDef_t* inv = &csi.ids[container];+	vec2_t nodepos; +	MN_GetNodeAbsPos(node, nodepos); 	R_DrawFill(posx, posy, sizex, sizey, ALIGN_UL, color);  	/* if showTUs is true (only the first time in none single containers) 	 * and we are connected to a game */-	if (showTUs && cls.state == ca_active)-		R_FontDrawString("f_verysmall", 0, node->pos[0] + 3, node->pos[1] + 3,-			node->pos[0] + 3, node->pos[1] + 3, node->size[0] - 6, 0, 0,+	if (showTUs && cls.state == ca_active){+		R_FontDrawString("f_verysmall", 0, nodepos[0] + 3, nodepos[1] + 3,+			nodepos[0] + 3, nodepos[1] + 3, node->size[0] - 6, 0, 0, 			va(_("In: %i Out: %i"), inv->in, inv->out), 0, 0, NULL, qfalse);+	} }  /**@@ -648,8 +656,8 @@ void MN_InvDrawFree (inventory_t *inv, const menuNode_t *node) { 	objDef_t *od = dragInfo.item.t;	/**< Get the 'type' of the dragged item. */- 	qboolean showTUs = qtrue;+	vec2_t nodepos;  	/* The shape of the free positions. */ 	uint32_t free[SHAPE_BIG_MAX_HEIGHT];@@ -660,11 +668,12 @@ 	assert(mouseSpace == MS_DRAGITEM); 	assert(inv); +	MN_GetNodeAbsPos(node, nodepos); 	/* if single container (hands, extension, headgear) */ 	if (node->container->single) { 		/* if container is free or the dragged-item is in it */ 		if (node->container == dragInfo.from || Com_CheckToInventory(inv, od, node->container, 0, 0, dragInfo.ic))-			MN_DrawFree(node->container->id, node, node->pos[0], node->pos[1], node->size[0], node->size[1], qtrue);+			MN_DrawFree(node->container->id, node, nodepos[0], nodepos[1], node->size[0], node->size[1], qtrue); 	} else { 		memset(free, 0, sizeof(free)); 		for (y = 0; y < SHAPE_BIG_MAX_HEIGHT; y++) {@@ -681,7 +690,7 @@ 				/* Only draw on existing positions. */ 				if (Com_CheckShape(node->container->shape, x, y)) { 					if (Com_CheckShape(free, x, y)) {-						MN_DrawFree(node->container->id, node, node->pos[0] + x * C_UNIT, node->pos[1] + y * C_UNIT, C_UNIT, C_UNIT, showTUs);+						MN_DrawFree(node->container->id, node, nodepos[0] + x * C_UNIT, nodepos[1] + y * C_UNIT, C_UNIT, C_UNIT, showTUs); 						showTUs = qfalse; 					} 				}@@ -751,6 +760,7 @@ 	vec4_t color = {1, 1, 1, 1}; 	vec4_t colorLoadable = {0.5, 1, 0.5, 1}; 	qboolean drawLoadable = qfalse;+	vec2_t nodepos;  	if (!node->container) 		MN_FindContainer(node);@@ -758,6 +768,7 @@ 		return NULL;  	assert(menuInventory);+	MN_GetNodeAbsPos(node, nodepos);  	/* Highlight weapons that the dragged ammo (if it is one) can be loaded into. */ 	if (mouseSpace == MS_DRAGITEM && dragInfo.item.t)@@ -766,7 +777,7 @@ 	if (node->container->single) { 		/* Single container */ 		vec2_t pos;-		Vector2Copy(node->pos, pos);+		Vector2Copy(nodepos, pos); 		pos[0] += node->size[0] / 2.0; 		pos[1] += node->size[1] / 2.0; @@ -847,7 +858,7 @@ 							item_t tempItem = {1, NULL, NULL, 0, 0}; 							qboolean newRow = qfalse; 							vec2_t pos;-							Vector2Copy(node->pos, pos);+							Vector2Copy(nodepos, pos); 							pos[0] += curWidth; 							pos[1] += curHeight; @@ -864,7 +875,7 @@ 									curRow++;  									/* Re-calculate the position of this item in the new row. */-									Vector2Copy(node->pos, pos);+									Vector2Copy(nodepos, pos); 									pos[1] += curHeight; 									newRow = qtrue; 								}@@ -927,7 +938,7 @@ 											if (icAmmo) { 												/* Calculate the center of the item model/image. */ 												pos[0] += tempItem.t->sx * C_UNIT / 2;-												pos[1] = node->pos[1] + curHeight + icAmmo->item.t->sy * C_UNIT / 2.0;+												pos[1] = nodepos[1] + curHeight + icAmmo->item.t->sy * C_UNIT / 2.0;  												curWidth += tempItem.t->sx * C_UNIT; @@ -975,9 +986,9 @@ 			for (ic = menuInventory->c[node->container->id]; ic; ic = ic->next) { 				assert(ic->item.t); 				if (drawLoadable && INVSH_LoadableInWeapon(dragInfo.item.t, ic->item.t))-					MN_DrawItem(node->pos, &ic->item, ic->x, ic->y, scale, colorLoadable);+					MN_DrawItem(nodepos, &ic->item, ic->x, ic->y, scale, colorLoadable); 				else-					MN_DrawItem(node->pos, &ic->item, ic->x, ic->y, scale, color);+					MN_DrawItem(nodepos, &ic->item, ic->x, ic->y, scale, color); 			} 		} 	}@@ -997,8 +1008,8 @@ 		} else { 			return Com_SearchInInventory(menuInventory, 				node->container,-				(mousePosX - node->pos[0]) / C_UNIT,-				(mousePosY - node->pos[1]) / C_UNIT);+				(mousePosX - nodepos[0]) / C_UNIT,+				(mousePosY - nodepos[1]) / C_UNIT); 		} 	} @@ -1022,7 +1033,7 @@  	/* We position the model of the item ourself (in the middle of the item 	 * node). See the "-1, -1" parameter of MN_DrawItem. */-	Vector2Copy(node->pos, pos);+	MN_GetNodeAbsPos(node, pos); 	pos[0] += node->size[0] / 2.0; 	pos[1] += node->size[1] / 2.0; 	MN_DrawItem(pos, &item, -1, -1, node->scale, color);Index: src/client/menu/m_input.c===================================================================--- src/client/menu/m_input.c	(revision 19496)+++ src/client/menu/m_input.c	(working copy)@@ -125,8 +125,10 @@ { 	selectBoxOptions_t* selectBoxOption; 	int clickedAtOption;+	vec2_t pos; -	clickedAtOption = (y - node->pos[1]);+	MN_GetNodeAbsPos(node, pos);+	clickedAtOption = (y - pos[1]);  	if (node->size[1]) 		clickedAtOption = (clickedAtOption - node->size[1]) / node->size[1];@@ -174,15 +176,17 @@ static void MN_BarClick (menu_t * menu, menuNode_t * node, int x) { 	char var[MAX_VAR];+	vec2_t pos;  	if (!node->mousefx) 		return; +	MN_GetNodeAbsPos(node, pos); 	Q_strncpyz(var, node->data[2], sizeof(var)); 	/* no cvar? */ 	if (!Q_strncmp(var, "*cvar", 5)) { 		/* normalize it */-		const float frac = (float) (x - node->pos[0]) / node->size[0];+		const float frac = (float) (x - pos[0]) / node->size[0]; 		const float min = MN_GetReferenceFloat(menu, node->data[1]); 		const float value = min + frac * (MN_GetReferenceFloat(menu, node->data[0]) - min); 		/* in the case of MN_BAR the first three data array values are float values - see menuDataValues_t */@@ -250,6 +254,8 @@ 	int row, col;  	assert(base);+	assert(node);+	assert(node->menu);  	if (gd.baseAction == BA_NEWBUILDING) { 		assert(base->buildingCurrent);@@ -302,12 +308,14 @@ 	int row, col;  	assert(base);+	assert(node);+	assert(node->menu);  	for (row = 0; row < BASE_SIZE; row++) 		for (col = 0; col < BASE_SIZE; col++)-			if (base->map[row][col].building && x >= base->map[row][col].posX-			 && x < base->map[row][col].posX + node->size[0] / BASE_SIZE && y >= base->map[row][col].posY-			 && y < base->map[row][col].posY + node->size[1] / BASE_SIZE) {+			if (base->map[row][col].building && x >= base->map[row][col].posX + node->menu->origin[0]+			 && x < base->map[row][col].posX + node->menu->origin[0] + node->size[0] / BASE_SIZE && y >= base->map[row][col].posY + node->menu->origin[1]+			 && y < base->map[row][col].posY + node->menu->origin[1] + node->size[1] / BASE_SIZE) { 				building_t *entry = base->map[row][col].building; 				if (!entry) 					Sys_Error("MN_BaseMapRightClick: no entry at %i:%i\n", x, y);Index: src/client/menu/m_messages.c===================================================================--- src/client/menu/m_messages.c	(revision 19496)+++ src/client/menu/m_messages.c	(working copy)@@ -43,7 +43,8 @@  #ifdef DEBUG /**- * @brief Script command to delete all messages */+ * @brief Script command to delete all messages+ */ static void CL_DeleteMessages_f (void) { 	message_t *m = mn.messageStack;Index: src/client/menu/m_nodes.c===================================================================--- src/client/menu/m_nodes.c	(revision 19496)+++ src/client/menu/m_nodes.c	(working copy)@@ -29,6 +29,33 @@  extern menuNode_t *focusNode; +/**+ * @brief Returns the absolute position of a menunode+ * @param[in] menunode+ * @param[out] pos+ */+void MN_GetNodeAbsPos (const menuNode_t* node, vec2_t pos)+{+	if (!node)+		Sys_Error("MN_GetNodeAbsPos: No node given");+	if (!node->menu)+		Sys_Error("MN_GetNodeAbsPos: Node '%s' has no menu", node->name);++	switch (node->type) {+	case MN_NULL:+	case MN_CONFUNC:+	case MN_CVARFUNC:+	case MN_FUNC:+		break;+	case MN_MODEL:+		Vector2Set(pos, node->menu->origin[0] + node->origin[0], node->menu->origin[1] + node->origin[1]);+		break;+	default:+		Vector2Set(pos, node->menu->origin[0] + node->pos[0], node->menu->origin[1] + node->pos[1]);+		break;+	}+}+ #if 0 /** @todo to be integrated into MN_CheckNodeZone */ /**@@ -44,10 +71,12 @@ 	int width, height;	/**< Width and height for the pic. */ 	int pic_x, pic_y;	/**< Position inside image */ 	byte *color = NULL;	/**< Pointer to specific pixel in image. */+	vec2_t nodepos;  	if (!node || node->type != MN_PIC || !node->data[MN_DATA_STRING_OR_IMAGE_OR_MODEL]) 		return qfalse; +	MN_GetNodeAbsPos(node, nodepos); 	R_LoadImage(va("pics/menu/%s", path), &picture, &width, &height);  	if (!picture || !width || !height) {@@ -57,8 +86,8 @@ 	}  	/** @todo Get current location _inside_ image from global position. CHECKME */-	pic_x = x - node->pos[0];-	pic_y = y - node->pos[1];+	pic_x = x - nodepos[0];+	pic_y = y - nodepos[1];  	if (pic_x < 0 || pic_y < 0) 		return qfalse;@@ -81,6 +110,7 @@ qboolean MN_CheckNodeZone (menuNode_t* const node, int x, int y) { 	int sx, sy, tx, ty, i;+	vec2_t nodepos;  	/* don't hover nodes if we are executing an action on geoscape like rotating or moving */ 	if (mouseSpace >= MS_ROTATE && mouseSpace <= MS_SHIFT3DMAP)@@ -89,6 +119,7 @@ 	if (focusNode && mouseSpace != MS_NULL) 		return qfalse; +	MN_GetNodeAbsPos(node, nodepos); 	switch (node->type) { 	case MN_CONTAINER: 		if (!node->container)@@ -97,7 +128,7 @@ 			return qfalse;  		/* check bounding box */-		if (x < node->pos[0] || x > node->pos[0] + node->size[0] || y < node->pos[1] || y > node->pos[1] + node->size[1])+		if (x < nodepos[0] || x > nodepos[0] + node->size[0] || y < nodepos[1] || y > nodepos[1] + node->size[1]) 			return qfalse;  		/* found a container */@@ -146,7 +177,7 @@ 			int hoverOptionID; 			sy += (node->size[1] * node->height); 			/* hover a given entry in the list */-			hoverOptionID = (y - node->pos[1]);+			hoverOptionID = (y - nodepos[1]);  			if (node->size[1]) 				hoverOptionID = (hoverOptionID - node->size[1]) / node->size[1];@@ -159,17 +190,17 @@ 		} 	} -	tx = x - node->pos[0];-	ty = y - node->pos[1];+	tx = x - nodepos[0];+	ty = y - nodepos[1]; 	if (node->align > 0 && node->align < ALIGN_LAST) { 		switch (node->align % 3) { 		/* center */ 		case 1:-			tx = x - node->pos[0] + sx / 2;+			tx = x - nodepos[0] + sx / 2; 			break; 		/* right */ 		case 2:-			tx = x - node->pos[0] + sx;+			tx = x - nodepos[0] + sx; 			break; 		} 	}@@ -178,8 +209,8 @@ 		return qfalse;  	for (i = 0; i < node->excludeNum; i++) {-		if (x >= node->exclude[i].pos[0] && x <= node->exclude[i].pos[0] + node->exclude[i].size[0]-		 && y >= node->exclude[i].pos[1] && y <= node->exclude[i].pos[1] + node->exclude[i].size[1])+		if (x >= node->menu->origin[0] + node->exclude[i].pos[0] && x <= node->menu->origin[0] + node->exclude[i].pos[0] + node->exclude[i].size[0]+		 && y >= node->menu->origin[1] + node->exclude[i].pos[1] && y <= node->menu->origin[1] + node->exclude[i].pos[1] + node->exclude[i].size[1]) 			return qfalse; 	} Index: src/client/menu/m_menu.h===================================================================--- src/client/menu/m_menu.h	(revision 19496)+++ src/client/menu/m_menu.h	(working copy)@@ -31,6 +31,7 @@ typedef struct menu_s { 	char name[MAX_VAR]; 	int eventTime;+	vec2_t origin;	/**< the position of the menu */ 	vec2_t noticePos; /**< the position where the cl.msgText messages are rendered */ 	struct menuNode_s *firstNode, *initNode, *closeNode, *renderNode; 	struct menuNode_s *popupNode, *hoverNode, *eventNode, *leaveNode;Index: src/client/menu/m_parse.c===================================================================--- src/client/menu/m_parse.c	(revision 19496)+++ src/client/menu/m_parse.c	(working copy)@@ -614,6 +614,7 @@ 	int i;  	lastNode = NULL;+	Vector2Set(menu->origin, 0, 0);  	/* if inheriting another menu, link in the super menu's nodes */ 	for (node = menu->firstNode; node; node = node->next) {@@ -657,6 +658,13 @@ 							return qfalse; 						Com_ParseValue(menu->noticePos, token, V_POS, 0, sizeof(vec2_t)); 						found = qtrue;+					} else if (!Q_strcmp(token, "origin")) {+						/* get new token */+						token = COM_EParse(text, errhead, menu->name);+						if (!*text)+							return qfalse;+						Com_ParseValue(menu->origin, token, V_POS, 0, sizeof(vec2_t));+						found = qtrue; 					} else 						Com_Printf("Invalid special menu value '%s'\n", token); 				} while (found);Index: src/client/menu/m_nodes.h===================================================================--- src/client/menu/m_nodes.h	(revision 19496)+++ src/client/menu/m_nodes.h	(working copy)@@ -173,6 +173,7 @@ menuNode_t* MN_GetNodeFromCurrentMenu(const char *name); void MN_SetNewNodePos(menuNode_t* node, int x, int y); menuNode_t *MN_GetNode(const menu_t* const menu, const char *name);+void MN_GetNodeAbsPos (const menuNode_t* node, vec2_t pos);  void MN_InitNodes(void); Index: src/client/menu/m_main.c===================================================================--- src/client/menu/m_main.c	(revision 19496)+++ src/client/menu/m_main.c	(working copy)@@ -294,8 +294,30 @@ 	return NULL; } +/**+ * @brief Sets new x and y coordinates for a given menu+ */+void MN_SetNewMenuPos (menu_t* menu, int x, int y)+{+        if (menu) {+		Vector2Set(menu->origin, x, y);+        }+}  /**+ * @brief Console command for moving a menu+ */+void MN_SetNewMenuPos_f (void)+{+	menu_t* menu = MN_GetActiveMenu();++	if (Cmd_Argc() < 3)+		Com_Printf("Usage: %s <x> <y>\n", Cmd_Argv(0));++	MN_SetNewMenuPos (menu, atoi(Cmd_Argv(1)), atoi(Cmd_Argv(2)));+}++/**  * @brief This will reinit the current visible menu  * @note also available as script command mn_reinit  */@@ -634,6 +656,8 @@ 	Cmd_AddCommand("scrollcont_next", MN_ScrollContainerNext_f, "Scrolls the current container (forward)."); 	Cmd_AddCommand("scrollcont_prev", MN_ScrollContainerPrev_f, "Scrolls the current container (backward)."); +	Cmd_AddCommand("mn_move", MN_SetNewMenuPos_f, "Moves the menu to a new position.");+ 	/* 256kb */ 	/** @todo Get rid of adata, curadata and adataize */ 	mn.adataize = MENU_HUNK_SIZE;Index: src/client/menu/m_node_image.c===================================================================--- src/client/menu/m_node_image.c	(revision 19496)+++ src/client/menu/m_node_image.c	(working copy)@@ -4,7 +4,9 @@ void MN_DrawImageNode (menuNode_t *node, const char *imageName, int time) { 	vec2_t size;+	vec2_t nodepos; +	MN_GetNodeAbsPos(node, nodepos); 	/* HACK for ekg pics */ 	if (!Q_strncmp(node->name, "ekg_", 4)) { 		int pt;@@ -35,6 +37,6 @@ 	} else { 		Vector2Copy(node->size, size); 	}-	R_DrawNormPic(node->pos[0], node->pos[1], size[0], size[1],+	R_DrawNormPic(nodepos[0], nodepos[1], size[0], size[1], 		node->texh[0], node->texh[1], node->texl[0], node->texl[1], node->align, node->blend, imageName); }Index: src/client/menu/m_main.h===================================================================--- src/client/menu/m_main.h	(revision 19496)+++ src/client/menu/m_main.h	(working copy)@@ -92,7 +92,9 @@ void MN_Shutdown(void); qboolean MN_CheckCondition(menuNode_t *node); int MN_GetVisibleMenuCount(void);+void MN_SetNewMenuPos (menu_t* menu, int x, int y); +void MN_SetNewMenuPos_f (void); void MN_ScrollContainerUpdate_f(void); void MN_ScrollContainerNext_f(void); void MN_ScrollContainerPrev_f(void);Index: src/client/menu/m_node_radar.c===================================================================--- src/client/menu/m_node_radar.c	(revision 19496)+++ src/client/menu/m_node_radar.c	(working copy)@@ -250,12 +250,14 @@ 	const vec3_t offset = {MAP_SIZE_OFFSET, MAP_SIZE_OFFSET, MAP_SIZE_OFFSET}; 	float distAB, distBC; 	vec2_t gridSize;		/**< Size of the whole grid (in tiles units) */+	vec2_t nodepos;  	MN_FreeRadarImages(); 	MN_BuildRadarImageList(cl.configstrings[CS_TILES], cl.configstrings[CS_POSITIONS]); -	radar.x = node->pos[0];-	radar.y = node->pos[1];+	MN_GetNodeAbsPos(node, nodepos);+	radar.x = nodepos[0];+	radar.y = nodepos[1];  	/* only check once per map whether all the needed images exist */ 	for (i = 0; i < PATHFINDING_HEIGHT; i++) {Index: src/client/menu/m_node_model.c===================================================================--- src/client/menu/m_node_model.c	(revision 19496)+++ src/client/menu/m_node_model.c	(working copy)@@ -190,10 +190,17 @@ 	animState_t *as; 	const char *anim;					/* model anim state */ 	menuModel_t *menuModel, *menuModelParent = NULL;- 	/* if true we have to reset the anim state and make sure the correct model is shown */ 	qboolean updateModel = qfalse;+	vec2_t nodepos;+	static vec3_t nodeorigin;+	static vec3_t pmiorigin; +	MN_GetNodeAbsPos(node, nodepos);+	nodeorigin[0] = nodepos[0];+	nodeorigin[1] = nodepos[1];+	nodeorigin[3] = node->origin[2];+ 	menuModel = node->menuModel = MN_GetMenuModel(source);  	/* direct model name - no menumodel definition */@@ -214,7 +221,7 @@ 		updateModel = qtrue; 	} -	mi.origin = node->origin;+	mi.origin = nodeorigin; 	mi.angles = node->angles; 	mi.scale = node->scale; 	mi.center = node->center;@@ -274,9 +281,9 @@  							/* Use menu origin if defined. */ 							if (menuModel->menuTransform[i].useOrigin) {-								VectorAdd(node->origin, menuModel->menuTransform[i].origin, mi.origin);+								VectorAdd(nodeorigin, menuModel->menuTransform[i].origin, mi.origin); 							} else {-								VectorCopy(node->origin, mi.origin);+								VectorCopy(nodeorigin, mi.origin); 							} 							break; 						}@@ -285,12 +292,12 @@ 					if (i == menuModel->menuTransformCnt) { 						VectorCopy(node->scale, mi.scale); 						VectorCopy(node->angles, mi.angles);-						VectorCopy(node->origin, mi.origin);+						VectorCopy(nodeorigin, mi.origin); 					} 				} else { 					VectorCopy(node->scale, mi.scale); 					VectorCopy(node->angles, mi.angles);-					VectorCopy(node->origin, mi.origin);+					VectorCopy(nodeorigin, mi.origin); 				} 				Vector4Copy(node->color, mi.color); 				VectorCopy(node->center, mi.center);@@ -334,7 +341,13 @@ 				}  				pmi.name = menuModelParent->model;-				pmi.origin = menuModelParent->origin;+				pmi.origin = pmiorigin;+				pmi.origin[0] = menuModelParent->origin[0] + mi.origin[0];+				pmi.origin[1] = menuModelParent->origin[1] + mi.origin[1];+				pmi.origin[2] = menuModelParent->origin[2];+				/* don't count menuoffset twice for tagged models */+				mi.origin[0] -= node->menu->origin[0];+				mi.origin[1] -= node->menu->origin[1]; 				pmi.angles = menuModelParent->angles; 				pmi.scale = menuModelParent->scale; 				pmi.center = menuModelParent->center;@@ -419,7 +432,13 @@ 							break;  						pmi.name = modelName;-						pmi.origin = search->origin;+						VectorCopy(search->origin, pmiorigin);+						pmi.origin = pmiorigin;+						pmi.origin[0] += mi.origin[0];+						pmi.origin[1] += mi.origin[1];+						/* don't count menuoffset twice for tagged models */+						mi.origin[0] -= node->menu->origin[0];+						mi.origin[1] -= node->menu->origin[1]; 						pmi.angles = search->angles; 						pmi.scale = search->scale; 						pmi.center = search->center;Index: src/client/cl_screen.c===================================================================--- src/client/cl_screen.c	(revision 19496)+++ src/client/cl_screen.c	(working copy)@@ -327,10 +327,13 @@ 				dragInfo.item.rotated = qtrue;  			if (checkedTo && Q_strncmp(dragInfo.item.t->type, "armour", MAX_VAR)) {	/* If the item fits somehow and it's not armour */+				vec2_t nodepos;++				MN_GetNodeAbsPos(dragInfo.toNode, nodepos); 				if (dragInfo.to->single) { /* Get center of single container for placement of preview item */ 					VectorSet(org,-						dragInfo.toNode->pos[0] + dragInfo.toNode->size[0] / 2.0,-						dragInfo.toNode->pos[1] + dragInfo.toNode->size[1] / 2.0,+						nodepos[0] + dragInfo.toNode->size[0] / 2.0,+						nodepos[1] + dragInfo.toNode->size[1] / 2.0, 						-40); 				} else { 					/* This is a "grid" container - we need to calculate the item-position@@ -338,13 +341,13 @@ 					 * calculated rotation info. */ 					if (dragInfo.item.rotated) 						VectorSet(org,-							dragInfo.toNode->pos[0] + (dragInfo.toX + dragInfo.item.t->sy / 2.0) * C_UNIT,-							dragInfo.toNode->pos[1] + (dragInfo.toY + dragInfo.item.t->sx / 2.0) * C_UNIT,+							nodepos[0] + (dragInfo.toX + dragInfo.item.t->sy / 2.0) * C_UNIT,+							nodepos[1] + (dragInfo.toY + dragInfo.item.t->sx / 2.0) * C_UNIT, 							-40); 					else 						VectorSet(org,-							dragInfo.toNode->pos[0] + (dragInfo.toX + dragInfo.item.t->sx / 2.0) * C_UNIT,-							dragInfo.toNode->pos[1] + (dragInfo.toY + dragInfo.item.t->sy / 2.0) * C_UNIT,+							nodepos[0] + (dragInfo.toX + dragInfo.item.t->sx / 2.0) * C_UNIT,+							nodepos[1] + (dragInfo.toY + dragInfo.item.t->sy / 2.0) * C_UNIT, 							-40); 				} 				Vector4Set(color, 0.5, 0.5, 1, 1);	/**< Make the preview item look blueish */